aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-dvbci.c
diff options
context:
space:
mode:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>2011-10-07 16:46:37 +0000
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>2011-10-07 16:46:37 +0000
commit0b44f0b088a2601da42acf7ada02534d31a8b5d5 (patch)
treedae849f0fbd1a21e938f84bb1a46cf17cacf560b /epan/dissectors/packet-dvbci.c
parentada3d80239a550cab7f0264060c186724d02b9b9 (diff)
From Martin Kaiser:
DVB-CI / CI+ CC resource version 2 https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6436 git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@39306 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-dvbci.c')
-rw-r--r--epan/dissectors/packet-dvbci.c289
1 files changed, 256 insertions, 33 deletions
diff --git a/epan/dissectors/packet-dvbci.c b/epan/dissectors/packet-dvbci.c
index 5d277806cc..44c70e5750 100644
--- a/epan/dissectors/packet-dvbci.c
+++ b/epan/dissectors/packet-dvbci.c
@@ -24,7 +24,7 @@
*/
/* This dissector supports DVB-CI as defined in EN50221 and
- * CI+ version 1.2 (www.ci-plus.com).
+ * CI+ (www.ci-plus.com).
* For more details, see http://wiki.wireshark.org/DVB-CI.
*
* The pcap input format for this dissector is documented at
@@ -275,6 +275,22 @@
#define CC_SAC_AUTH_AES128_XCBC_MAC 0x0
#define CC_SAC_ENC_AES128_CBC 0x0
+#define CC_CAP_NONE 0x0
+#define CC_CAP_CAS_PIN 0x1
+#define CC_CAP_CAS_FTA_PIN 0x2
+#define CC_CAP_CAS_PIN_CACHED 0x3
+#define CC_CAP_CAS_FTA_PIN_CACHED 0x4
+
+/* length of DVB-SI utc time field in bytes */
+#define UTC_TIME_LEN 5
+
+#define CC_PIN_BAD 0x0
+#define CC_PIN_CAM_BUSY 0x1
+#define CC_PIN_OK 0x2
+#define CC_PIN_UNCONFIRMED 0x3
+#define CC_PIN_VB_NOT_REQ 0x4
+#define CC_PIN_CSA 0x5
+
/* application mmi resource */
#define ACK_CODE_OK 0x1
#define ACK_CODE_WRONG_API 0x2
@@ -445,6 +461,13 @@ dissect_dvbci_payload_sas(guint32 tag, gint len_field _U_,
#define T_CC_SAC_DATA_CNF 0x9F9008
#define T_CC_SAC_SYNC_REQ 0x9F9009
#define T_CC_SAC_SYNC_CNF 0x9F9010
+#define T_CC_PIN_CAPABILITIES_REQ 0x9F9011
+#define T_CC_PIN_CAPABILITIES_REPLY 0x9F9012
+#define T_CC_PIN_CMD 0x9F9013
+#define T_CC_PIN_REPLY 0x9F9014
+#define T_CC_PIN_EVENT 0x9F9015
+#define T_CC_PIN_PLAYBACK 0x9F9016
+#define T_CC_PIN_MMI_REQ 0x9F9017
#define T_REQUEST_START 0x9F8000
#define T_REQUEST_START_ACK 0x9F8001
#define T_FILE_REQUEST 0x9F8002
@@ -519,16 +542,23 @@ static const apdu_info_t apdu_info[] = {
{T_CAM_FIRMWARE_UPGRADE_PROGRESS, 0, 1, DATA_CAM_TO_HOST, dissect_dvbci_payload_cup},
{T_CAM_FIRMWARE_UPGRADE_COMPLETE, 0, 1, DATA_CAM_TO_HOST, dissect_dvbci_payload_cup},
- {T_CC_OPEN_REQ, 0, 0, DATA_CAM_TO_HOST, NULL},
- {T_CC_OPEN_CNF, 0, 1, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
- {T_CC_DATA_REQ, 3, LEN_FIELD_ANY, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
- {T_CC_DATA_CNF, 2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
- {T_CC_SYNC_REQ, 0, 0, DATA_CAM_TO_HOST, NULL},
- {T_CC_SYNC_CNF, 0, 1, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
- {T_CC_SAC_DATA_REQ, 8, LEN_FIELD_ANY, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
- {T_CC_SAC_DATA_CNF, 8, LEN_FIELD_ANY, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
- {T_CC_SAC_SYNC_REQ, 8, LEN_FIELD_ANY, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
- {T_CC_SAC_SYNC_CNF, 8, LEN_FIELD_ANY, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
+ {T_CC_OPEN_REQ, 0, 0, DATA_CAM_TO_HOST, NULL},
+ {T_CC_OPEN_CNF, 0, 1, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
+ {T_CC_DATA_REQ, 3, LEN_FIELD_ANY, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
+ {T_CC_DATA_CNF, 2, LEN_FIELD_ANY, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
+ {T_CC_SYNC_REQ, 0, 0, DATA_CAM_TO_HOST, NULL},
+ {T_CC_SYNC_CNF, 0, 1, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
+ {T_CC_SAC_DATA_REQ, 8, LEN_FIELD_ANY, DIRECTION_ANY, dissect_dvbci_payload_cc},
+ {T_CC_SAC_DATA_CNF, 8, LEN_FIELD_ANY, DIRECTION_ANY, dissect_dvbci_payload_cc},
+ {T_CC_SAC_SYNC_REQ, 8, LEN_FIELD_ANY, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
+ {T_CC_SAC_SYNC_CNF, 8, LEN_FIELD_ANY, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
+ {T_CC_PIN_CAPABILITIES_REQ, 0, 0, DATA_HOST_TO_CAM, NULL},
+ {T_CC_PIN_CAPABILITIES_REPLY, 7, 7, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
+ {T_CC_PIN_CMD, 1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
+ {T_CC_PIN_REPLY, 1, 1, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
+ {T_CC_PIN_EVENT, 25, 25, DATA_CAM_TO_HOST, dissect_dvbci_payload_cc},
+ {T_CC_PIN_PLAYBACK, 16, 16, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
+ {T_CC_PIN_MMI_REQ, 1, LEN_FIELD_ANY, DATA_HOST_TO_CAM, dissect_dvbci_payload_cc},
{T_REQUEST_START, 2, LEN_FIELD_ANY, DATA_CAM_TO_HOST, dissect_dvbci_payload_ami},
{T_REQUEST_START_ACK, 0, 1, DATA_HOST_TO_CAM, dissect_dvbci_payload_ami},
@@ -601,6 +631,13 @@ static const value_string dvbci_apdu_tag[] = {
{ T_CC_SAC_DATA_CNF, "CC SAC data confirm" },
{ T_CC_SAC_SYNC_REQ, "CC SAC sync request" },
{ T_CC_SAC_SYNC_CNF, "CC SAC sync confirm" },
+ { T_CC_PIN_CAPABILITIES_REQ, "CC PIN capabilities request" },
+ { T_CC_PIN_CAPABILITIES_REPLY, "CC PIN capabilities reply" },
+ { T_CC_PIN_CMD, "CC PIN command" },
+ { T_CC_PIN_REPLY, "CC PIN reply" },
+ { T_CC_PIN_EVENT, "CC PIN event" },
+ { T_CC_PIN_PLAYBACK, "CC PIN playback" },
+ { T_CC_PIN_MMI_REQ, "CC PIN MMI request" },
{ T_REQUEST_START, "Request start" },
{ T_REQUEST_START_ACK, "Request start ack" },
{ T_FILE_REQUEST, "File request" },
@@ -745,6 +782,15 @@ static int hf_dvbci_sac_payload_enc = -1;
static int hf_dvbci_sac_enc_cip = -1;
static int hf_dvbci_sac_payload_len = -1;
static int hf_dvbci_sac_body = -1;
+static int hf_dvbci_rating = -1;
+static int hf_dvbci_capability_field = -1;
+static int hf_dvbci_pin_chg_time = -1;
+static int hf_dvbci_pincode_status = -1;
+static int hf_dvbci_cc_prog_num = -1;
+static int hf_dvbci_pin_evt_time = -1;
+static int hf_dvbci_pin_evt_cent = -1;
+static int hf_dvbci_cc_priv_data = -1;
+static int hf_dvbci_pincode = -1;
static int hf_dvbci_app_dom_id = -1;
static int hf_dvbci_init_obj = -1;
static int hf_dvbci_ack_code = -1;
@@ -1098,6 +1144,28 @@ static const value_string dvbci_cc_sac_enc[] = {
{ CC_SAC_ENC_AES128_CBC, "AES 128 CBC" },
{ 0, NULL }
};
+static const value_string dvbci_cc_cap[] = {
+ { CC_CAP_NONE,
+ "No PIN handling capability" },
+ { CC_CAP_CAS_PIN,
+ "CAM can do PIN handling on CAS services" },
+ { CC_CAP_CAS_FTA_PIN,
+ "CAM can do PIN handling on CAS and free services" },
+ { CC_CAP_CAS_PIN_CACHED,
+ "CAM can do PIN handling on CAS services and supports PIN caching" },
+ { CC_CAP_CAS_FTA_PIN_CACHED,
+ "CAM can do PIN handling on CAS and free services, supports PIN caching" },
+ { 0, NULL }
+};
+static const value_string dvbci_pincode_status[] = {
+ { CC_PIN_BAD, "Bad pin code" },
+ { CC_PIN_CAM_BUSY, "CAM busy" },
+ { CC_PIN_OK, "Pin code correct" },
+ { CC_PIN_UNCONFIRMED, "Pin code unconfirmed" },
+ { CC_PIN_VB_NOT_REQ, "Video blanking not required" },
+ { CC_PIN_CSA, "Content still CSA scrambled" },
+ { 0, NULL }
+};
static const value_string dvbci_ack_code[] = {
{ ACK_CODE_OK, "Ok" },
{ ACK_CODE_WRONG_API, "Application Domain unsupported" },
@@ -1197,6 +1265,55 @@ dvbci_init(void)
reassembled_table_init(&spdu_reassembled_table);
}
+/* read a utc_time field in an apdu and write it to utc_time
+ the encoding of the field is according to DVB-SI specification, section 5.2.5
+ 16bit modified julian day (MJD), 24bit 6*4bit BCD digits hhmmss
+ return the length in bytes or -1 for error */
+static gint
+read_utc_time(tvbuff_t *tvb, gint offset, nstime_t *utc_time)
+{
+ gint bcd_time_offset; /* start offset of the bcd time in the tvbuff */
+ guint8 hour, min, sec;
+
+ if (!utc_time)
+ return -1;
+
+ nstime_set_zero(utc_time);
+ utc_time->secs = (tvb_get_ntohs(tvb, offset) - 40587) * 86400;
+ bcd_time_offset = offset+2;
+ hour = BCD44_TO_DEC(tvb_get_guint8(tvb, bcd_time_offset));
+ min = BCD44_TO_DEC(tvb_get_guint8(tvb, bcd_time_offset+1));
+ sec = BCD44_TO_DEC(tvb_get_guint8(tvb, bcd_time_offset+2));
+ if (hour>23 || min>59 || sec>59)
+ return -1;
+
+ utc_time->secs += hour*3600 + min*60 + sec;
+ return 5;
+}
+
+
+/* dissect age rating byte encoded as defined in
+ DVB-SI parental rating descriptor
+ returns rating's length in bytes or -1 for error */
+static gint
+dissect_rating(tvbuff_t *tvb, gint offset,
+ packet_info *pinfo _U_, proto_tree *tree)
+{
+ guint8 rating;
+
+ rating = tvb_get_guint8(tvb, offset);
+ if (1<=rating && rating<=0x0F) {
+ proto_tree_add_uint_format(tree, hf_dvbci_rating,
+ tvb, offset, 1, rating,
+ "Rating is %d years (%d+3)", rating+3, rating);
+ } else {
+ proto_tree_add_uint_format(tree, hf_dvbci_rating,
+ tvb, offset, 1, rating,
+ "Rating is unknown/undefined (%d)", rating);
+ }
+
+ return 1;
+}
/* dissect a connection_descriptor for the lsc resource
@@ -1906,10 +2023,9 @@ dissect_dvbci_payload_dt(guint32 tag, gint len_field,
nstime_t resp_intv;
proto_item *pi = NULL;
const gchar *tag_str;
+ gint time_field_len;
nstime_t utc_time;
gint16 local_offset; /* field in the apdu */
- gint bcd_time_offset; /* start offset of the bcd time in the tvbuff */
- guint8 hour, min, sec;
if (tag==T_DATE_TIME_ENQ) {
@@ -1937,30 +2053,21 @@ dissect_dvbci_payload_dt(guint32 tag, gint len_field,
"Length field for %s must be 5 or 7 bytes", tag_str);
return;
}
- /* the 40bit utc_time field is encoded according to DVB-SI spec,
- * section 5.2.5:
- * 16bit modified julian day (MJD), 24bit 6*4bit BCD digits hhmmss */
- nstime_set_zero(&utc_time);
- utc_time.secs = (tvb_get_ntohs(tvb, offset) - 40587) * 86400;
- bcd_time_offset = offset+2;
- hour = BCD44_TO_DEC(tvb_get_guint8(tvb, bcd_time_offset));
- min = BCD44_TO_DEC(tvb_get_guint8(tvb, bcd_time_offset+1));
- sec = BCD44_TO_DEC(tvb_get_guint8(tvb, bcd_time_offset+2));
- if (hour>23 || min>59 || sec>59) {
+
+ time_field_len = read_utc_time(tvb, offset, &utc_time);
+ if (time_field_len<0) {
pi = proto_tree_add_text(
- tree, tvb, bcd_time_offset, 3, "Invalid BCD time");
+ tree, tvb, offset, 5, "Invalid UTC time field");
expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR,
- "BCD time must be hhmmss");
+ "2 bytes MJD, 3 bytes BCD time hhmmss");
return;
}
- utc_time.secs += hour*3600 + min*60 + sec;
-
- proto_tree_add_time_format(tree, hf_dvbci_utc_time, tvb, offset, 5,
- &utc_time, "%s UTC",
- abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE));
- col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ",
- "%s UTC", abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE));
- offset += 5;
+ proto_tree_add_time_format(tree, hf_dvbci_utc_time,
+ tvb, offset, time_field_len, &utc_time,
+ "%s UTC", abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE));
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s UTC",
+ abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE));
+ offset += time_field_len;
if (len_field==7) {
local_offset = two_comp_to_int16(tvb_get_ntohs(tvb, offset));
@@ -2244,6 +2351,10 @@ dissect_dvbci_payload_cc(guint32 tag, gint len_field _U_,
guint8 status;
guint32 msg_ctr;
guint8 enc_flag;
+ proto_item *pi = NULL;
+ nstime_t utc_time;
+ guint8 pin_stat;
+ guint8 evt_cent;
switch(tag) {
case T_CC_OPEN_CNF:
@@ -2321,6 +2432,91 @@ dissect_dvbci_payload_cc(guint32 tag, gint len_field _U_,
proto_tree_add_item(tree, hf_dvbci_sac_body, tvb, offset,
tvb_reported_length_remaining(tvb, offset), ENC_NA);
break;
+ case T_CC_PIN_CAPABILITIES_REPLY:
+ proto_tree_add_item(tree, hf_dvbci_capability_field,
+ tvb, offset, 1 , ENC_BIG_ENDIAN);
+ offset++;
+ /* we can't read_utc_time() and check with nstime_is_zero() */
+ if (tvb_get_ntoh40(tvb, offset) == 0) {
+ proto_tree_add_text(tree, tvb, offset, UTC_TIME_LEN,
+ "CICAM PIN has never been changed");
+ }
+ else {
+ if (read_utc_time(tvb, offset, &utc_time) < 0) {
+ pi = proto_tree_add_text(tree, tvb, offset, UTC_TIME_LEN,
+ "Invalid UTC time field");
+ expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR,
+ "2 bytes MJD, 3 bytes BCD time hhmmss");
+ break;
+ }
+ else {
+ /* abs_time_to_str() never returns NULL */
+ proto_tree_add_time_format(tree, hf_dvbci_pin_chg_time,
+ tvb, offset, UTC_TIME_LEN, &utc_time,
+ "PIN change time %s UTC",
+ abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE));
+ }
+ }
+ offset += UTC_TIME_LEN;
+ dissect_rating(tvb, offset, pinfo, tree);
+ break;
+ case T_CC_PIN_REPLY:
+ pin_stat = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_dvbci_pincode_status,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, ": ", "%s",
+ val_to_str(pin_stat, dvbci_pincode_status, "unknown"));
+ break;
+ case T_CC_PIN_EVENT:
+ proto_tree_add_item(tree, hf_dvbci_cc_prog_num,
+ tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tree, hf_dvbci_pincode_status,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ dissect_rating(tvb, offset, pinfo, tree);
+ offset++;
+ if (read_utc_time(tvb, offset, &utc_time) < 0) {
+ pi = proto_tree_add_text(tree, tvb, offset, UTC_TIME_LEN,
+ "Invalid UTC time field");
+ expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR,
+ "2 bytes MJD, 3 bytes BCD time hhmmss");
+ break;
+ }
+ else {
+ proto_tree_add_time_format(tree, hf_dvbci_pin_evt_time,
+ tvb, offset, UTC_TIME_LEN, &utc_time,
+ "PIN event time %s UTC",
+ abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE));
+ }
+ offset += UTC_TIME_LEN;
+ evt_cent = tvb_get_guint8(tvb, offset);
+ if (evt_cent > 100) {
+ pi = proto_tree_add_text(tree, tvb, offset, 1,
+ "Invalid value for event time centiseconds");
+ expert_add_info_format(pinfo, pi, PI_PROTOCOL, PI_WARN,
+ "Value must be between 0 and 100");
+ }
+ proto_tree_add_item(tree, hf_dvbci_pin_evt_cent,
+ tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ /* length field was already checked by the caller */
+ proto_tree_add_item(tree, hf_dvbci_cc_priv_data, tvb, offset,
+ tvb_reported_length_remaining(tvb, offset), ENC_NA);
+ break;
+ case T_CC_PIN_PLAYBACK:
+ dissect_rating(tvb, offset, pinfo, tree);
+ offset++;
+ /* length field was already checked by the caller */
+ proto_tree_add_item(tree, hf_dvbci_cc_priv_data, tvb, offset,
+ tvb_reported_length_remaining(tvb, offset), ENC_NA);
+ break;
+ case T_CC_PIN_CMD:
+ case T_CC_PIN_MMI_REQ:
+ proto_tree_add_item(tree, hf_dvbci_pincode, tvb, offset,
+ tvb_reported_length_remaining(tvb, offset),
+ ENC_ASCII|ENC_BIG_ENDIAN);
+ break;
default:
break;
}
@@ -3767,6 +3963,33 @@ proto_register_dvbci(void)
{ &hf_dvbci_sac_body,
{ "SAC body", "dvb-ci.cc.sac_body", FT_BYTES,
BASE_NONE, NULL, 0, NULL, HFILL } },
+ { &hf_dvbci_rating,
+ { "Rating", "dvb-ci.cc.rating", FT_UINT8, BASE_DEC,
+ NULL, 0, NULL, HFILL } },
+ { &hf_dvbci_capability_field,
+ { "Capability field", "dvb-ci.cc.capability_field", FT_UINT8,
+ BASE_HEX, VALS(dvbci_cc_cap), 0, NULL, HFILL } },
+ { &hf_dvbci_pin_chg_time,
+ { "PIN change time (UTC)", "dvb-ci.cc.pin_change_time",
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL } },
+ { &hf_dvbci_pincode_status,
+ { "Pincode status field", "dvb-ci.cc.pincode_status_field", FT_UINT8,
+ BASE_HEX, VALS(dvbci_pincode_status), 0, NULL, HFILL } },
+ { &hf_dvbci_cc_prog_num,
+ { "Program number", "dvb-ci.cc.program_number", FT_UINT16,
+ BASE_HEX, NULL, 0, NULL, HFILL } },
+ { &hf_dvbci_pin_evt_time,
+ { "PIN event time (UTC)", "dvb-ci.cc.pin_event_time",
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL } },
+ { &hf_dvbci_pin_evt_cent,
+ { "PIN event time centiseconds", "dvb-ci.cc.pin_event_time_centi",
+ FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
+ { &hf_dvbci_cc_priv_data,
+ { "Private data", "dvb-ci.cc.private_data", FT_BYTES,
+ BASE_NONE, NULL, 0, NULL, HFILL } },
+ { &hf_dvbci_pincode,
+ { "PIN code", "dvb-ci.cc.pincode", FT_STRING,
+ BASE_NONE, NULL, 0, NULL, HFILL } },
{ &hf_dvbci_app_dom_id,
{ "Application Domain Identifier", "dvb-ci.ami.app_dom_id",
FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },