aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-sbus.c
diff options
context:
space:
mode:
authorchrisdurrer <christian.durrer@sensemail.ch>2019-02-20 21:57:08 +0100
committerAnders Broman <a.broman58@gmail.com>2019-02-26 06:51:27 +0000
commita4068a9057d8d0a77f4d259b78e15831ac6e2fe1 (patch)
tree2d4df420184d13b79a6997ee827e5be58097a7ee /epan/dissectors/packet-sbus.c
parent6e1d30ce878d1ce706ad10dfe9699ec5dd3ef6a4 (diff)
sbus: Add multi-media telegram dissection
Added multi-media telegram dissection for multiple requests in one telegram Added read/write datablock telegram dissection Change-Id: Iaefba194bbc463340a6ed20998122c6ed14d67ca Reviewed-on: https://code.wireshark.org/review/32127 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-sbus.c')
-rw-r--r--epan/dissectors/packet-sbus.c544
1 files changed, 423 insertions, 121 deletions
diff --git a/epan/dissectors/packet-sbus.c b/epan/dissectors/packet-sbus.c
index 9e78a7d5af..04d319585c 100644
--- a/epan/dissectors/packet-sbus.c
+++ b/epan/dissectors/packet-sbus.c
@@ -195,11 +195,15 @@ static int hf_sbus_address = -1;
static int hf_sbus_command = -1;
static int hf_sbus_command_extension = -1;
static int hf_sbus_rcount = -1;
+static int hf_sbus_multimedia_length = -1;
+static int hf_sbus_sub_length = -1;
static int hf_sbus_wcount = -1;
static int hf_sbus_wcount_calculated = -1;
static int hf_sbus_fio_count = -1;
static int hf_sbus_addr_rtc = -1;
static int hf_sbus_addr_iof = -1;
+static int hf_sbus_addr_db = -1;
+static int hf_sbus_addr_base_element = -1;
static int hf_sbus_addr_eeprom = -1;
static int hf_sbus_addr_prog = -1;
static int hf_sbus_addr_68k = -1;
@@ -219,11 +223,6 @@ static int hf_sbus_sysinfo0_2 = -1;
static int hf_sbus_sysinfo0_3 = -1;
static int hf_sbus_sysinfo0_4 = -1;
static int hf_sbus_sysinfo0_5 = -1;
-/* static int hf_sbus_sysinfo_length = -1; */
-/* static int hf_sbus_f_module_type = -1; */
-/* static int hf_sbus_harware_version = -1; */
-/* static int hf_sbus_hardware_modification = -1; */
-/* static int hf_sbus_various = -1; */
static int hf_sbus_acknackcode = -1;
static int hf_sbus_cpu_status = -1;
static int hf_sbus_week_day = -1;
@@ -286,7 +285,7 @@ static const value_string sbus_att_vals[] = {
{2, "ACK/NAK"},
{0, NULL}
};
-/* Block types*/
+/* Block types (6 and 7 corrected C. Durrer, 20.02.2019)*/
static const value_string sbus_block_types[] = {
{0x00, "COB"}, /* Cyclic organization block */
{0x01, "XOB"}, /* Exception organization block */
@@ -294,10 +293,8 @@ static const value_string sbus_block_types[] = {
{0x03, "FB"}, /* Function block */
{0x04, "ST"}, /* Step of Graftec structure*/
{0x05, "TR"}, /* Transition of Graftec structure*/
-#if 0 /* XXX: Dup vals: should be 0x06 & 0x07 ?? */
- {0x04, "TEXT"}, /* Text*/
- {0x05, "DB"}, /* Data Block*/
-#endif
+ {0x06, "TEXT"}, /* Text*/
+ {0x07, "DB"}, /* Data Block*/
{0x08, "SB"}, /* Sequential Block (Graftec)*/
{0x09, "DBX"}, /* Special Data Block*/
{0x10, "BACnet"}, /* BACnet configuration block */
@@ -346,6 +343,7 @@ static const value_string sbus_command_vals[] = {
{0x0D, "Write output(s)"},
{0x0E, "Write register(s)"},
{0x0F, "Write timer(s)"},
+ {0x13, "Read write multi-medias"},
{0x14, "Read PCD status, CPU 0"},
{0x15, "Read PCD status, CPU 1"},
{0x16, "Read PCD status, CPU 2"},
@@ -395,7 +393,7 @@ static const value_string sbus_command_vals[] = {
{0x49, "Read index register*"},
{0x4A, "Read instruction pointer*"},
{0x4B, "Find history*"},
- {0x50, "Write arithmetic staus and ACCU*"},
+ {0x50, "Write arithmetic status and ACCU*"},
{0x51, "Write byte*"},
{0x52, "Write index register"},
{0x53, "Write instruction pointer*"},
@@ -535,6 +533,11 @@ typedef struct {
} sbus_request_key;
typedef struct {
+ guint8 cmd_code; /*multimedia command code*/
+ guint8 count; /*rcount of sub-request*/
+} sbus_subrequest;
+
+typedef struct {
guint8 cmd_code; /*command code from request*/
guint8 count; /*rcount value*/
guint8 sysinfo; /*system information number*/
@@ -543,6 +546,8 @@ typedef struct {
guint32 req_frame; /*frame number of last request*/
guint32 resp_frame; /*frame number of response*/
nstime_t req_time; /*time of the last request*/
+ guint8 mm_request_count; /*multi-media subrequest count*/
+ wmem_list_t *sbus_subrequests; /*list containing sub requests of multi-media request*/
} sbus_request_val;
/* The hash structure (for conversations)*/
@@ -625,6 +630,259 @@ is_sbus_pdu(tvbuff_t *tvb)
return TRUE;
}
+/*add the tree structure for one request media type to the tree*/
+static gint add_media_access_to_tree(gint sbus_cmd_code, tvbuff_t *tvb, proto_tree *tree, gint offset)
+{
+ gint i, j;
+ gint sbus_media_cnt;
+ proto_tree *sub_tree;
+ guint8 sbus_fio_cnt;
+ guint32 sbus_binaries;
+ guint32 sbus_binarymasked;
+ guint32 sbus_show_bin;
+ guint32 sbus_helper;
+
+ switch (sbus_cmd_code) {
+ /*Read Counter, Register or Timer*/
+ case SBUS_RD_COUNTER:
+ case SBUS_RD_REGISTER:
+ case SBUS_RD_TIMER:
+ sbus_media_cnt = (tvb_get_guint8(tvb,offset))+1;
+ proto_tree_add_uint(tree,
+ hf_sbus_rcount, tvb, offset, 1, sbus_media_cnt);
+ offset += 1;
+ proto_tree_add_item(tree,
+ hf_sbus_addr_rtc, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ break;
+
+ /*Read Flag, Input or Output*/
+ case SBUS_RD_FLAG:
+ case SBUS_RD_INPUT:
+ case SBUS_RD_OUTPUT:
+ sbus_media_cnt = (tvb_get_guint8(tvb,offset))+1;
+ proto_tree_add_uint(tree,
+ hf_sbus_rcount, tvb, offset, 1, sbus_media_cnt);
+ offset += 1;
+ proto_tree_add_item(tree,
+ hf_sbus_addr_iof, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ break;
+
+ /*Write Register Timer Counter*/
+ case SBUS_WR_COUNTER:
+ case SBUS_WR_REGISTER:
+ case SBUS_WR_TIMER:
+ sbus_media_cnt = (tvb_get_guint8(tvb,offset));
+ sbus_media_cnt = ((sbus_media_cnt - 1)/4);
+ proto_tree_add_uint(tree,
+ hf_sbus_wcount_calculated, tvb, offset,
+ 1, sbus_media_cnt);
+ proto_tree_add_item(tree,
+ hf_sbus_wcount, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree,
+ hf_sbus_addr_rtc, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ /*Add subtree for Data*/
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset,
+ ((sbus_media_cnt) * 4), ett_sbus_data, NULL, "Data");
+ for (i=((sbus_media_cnt)); i>0; i--) {
+ proto_tree_add_item(sub_tree,
+ hf_sbus_data_rtc, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+ break;
+
+ /* Write flags and outputs*/
+ case SBUS_WR_FLAG:
+ case SBUS_WR_OUTPUT:
+ sbus_media_cnt = (tvb_get_guint8(tvb,offset));
+ sbus_media_cnt = (sbus_media_cnt - 2);
+ proto_tree_add_uint(tree,
+ hf_sbus_wcount_calculated, tvb, offset,
+ 1, sbus_media_cnt);
+ proto_tree_add_item(tree,
+ hf_sbus_wcount, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ proto_tree_add_item(tree,
+ hf_sbus_addr_iof, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ sbus_fio_cnt = (tvb_get_guint8(tvb,offset));
+ sbus_fio_cnt = ((sbus_fio_cnt + 1));
+ proto_tree_add_uint(tree,
+ hf_sbus_fio_count, tvb, offset, 1, sbus_fio_cnt);
+ offset += 1;
+ /*Add subtree for Data*/
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset,
+ sbus_media_cnt, ett_sbus_data, NULL, "Data");
+
+ for (i=sbus_media_cnt; i>0; i--) {
+ sbus_helper = 1;
+ sbus_show_bin = 0;
+ sbus_binarymasked = 0x01;
+ sbus_binaries = tvb_get_guint8(tvb, offset);
+ for (j=0; j<8; j++) {
+ if ((sbus_binarymasked & sbus_binaries) != 0) {
+ sbus_show_bin = (sbus_show_bin + sbus_helper);
+ }
+ sbus_binarymasked = sbus_binarymasked<<1;
+ sbus_helper = 10 * sbus_helper;
+ }
+
+ proto_tree_add_uint_format(sub_tree,
+ hf_sbus_data_iof, tvb, offset, 1, sbus_show_bin,
+ "Binary data: %08u", sbus_show_bin);
+ offset += 1;
+ }
+ break;
+ case SBUS_RD_DATA_BLOCK:
+ sbus_media_cnt = (tvb_get_guint8(tvb,offset))+1;
+ proto_tree_add_uint(tree,
+ hf_sbus_rcount, tvb, offset, 1, sbus_media_cnt);
+ offset += 1;
+ proto_tree_add_item(tree,
+ hf_sbus_addr_db, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ /*add base element address*/
+ proto_tree_add_item(tree,
+ hf_sbus_addr_base_element, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ break;
+ }
+ return offset;
+
+
+}
+
+/*add the tree structure for one response media type to the tree*/
+static gint add_media_response_to_tree(gint cmd_code, gint count, tvbuff_t *tvb, proto_tree *tree, gint offset)
+{
+ gint i, j;
+ proto_tree *sub_tree;
+ guint32 sbus_binaries;
+ guint32 sbus_binarymasked;
+ guint32 sbus_show_bin;
+ guint32 sbus_helper;
+
+ switch (cmd_code) {
+
+ /*Add subtree for Data*/
+ case SBUS_RD_COUNTER:
+ case SBUS_RD_REGISTER:
+ case SBUS_RD_TIMER:
+ case SBUS_RD_USER_MEMORY:
+ case SBUS_RD_PROGRAM_LINE:
+ case SBUS_RD_USER_EEPROM_REGISTER:
+ case SBUS_RD_DATA_BLOCK:
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset,
+ (count * 4), ett_sbus_data, NULL, "Data");
+ for (i=count; i>0; i--) {
+ proto_tree_add_item(sub_tree,
+ hf_sbus_data_rtc, tvb, offset,
+ 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ }
+ break;
+
+ /* Add binary data I, O, F*/
+ case SBUS_RD_FLAG:
+ case SBUS_RD_INPUT:
+ case SBUS_RD_OUTPUT:
+ /*Add subtree for Data*/
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset,
+ (((count) + 7) / 8), ett_sbus_data, NULL, "Data");
+
+ for (i=(((count) + 7) / 8); i>0; i--) {
+ sbus_helper = 1;
+ sbus_show_bin = 0;
+ sbus_binarymasked = 0x01;
+ sbus_binaries = tvb_get_guint8(tvb, offset);
+ for (j=0; j<8; j++){
+ if ((sbus_binarymasked & sbus_binaries) != 0) {
+ sbus_show_bin = (sbus_show_bin + sbus_helper);
+ }
+ sbus_binarymasked = sbus_binarymasked<<1;
+ sbus_helper = 10 * sbus_helper;
+ }
+
+ proto_tree_add_uint_format(sub_tree,
+ hf_sbus_data_iof, tvb, offset, 1, sbus_show_bin,
+ "Binary data: %08u", sbus_show_bin);
+ offset += 1;
+ }
+ break;
+ }
+ return offset;
+}
+
+static gint get_response_length(gint cmd_code, gint count)
+{
+
+ gint length;
+ length = 0;
+
+ switch (cmd_code) {
+
+ /*Get length of 32 bit data*/
+ case SBUS_RD_COUNTER:
+ case SBUS_RD_REGISTER:
+ case SBUS_RD_TIMER:
+ case SBUS_RD_USER_MEMORY:
+ case SBUS_RD_PROGRAM_LINE:
+ case SBUS_RD_USER_EEPROM_REGISTER:
+ case SBUS_RD_DATA_BLOCK:
+ length = count * 4;
+ break;
+
+ /* Get length of binary data I, O, F*/
+ case SBUS_RD_FLAG:
+ case SBUS_RD_INPUT:
+ case SBUS_RD_OUTPUT:
+ length = ((count) + 7) / 8;
+ break;
+ }
+ return length;
+
+}
+
+
+static gint add_sbus_subrequest(tvbuff_t *tvb, wmem_list_t *request_list, gint offset)
+{
+ /*append subrequest info to requests lists and return number of sub-requests*/
+ gint subrequest_count;
+ gint internal_wcount;
+ gint internal_subwcount;
+ gint internal_offset;
+ gint internal_last_offset;
+
+ internal_offset = offset;
+ subrequest_count = 0;
+ internal_wcount = tvb_get_guint8(tvb,internal_offset);
+ internal_last_offset = internal_wcount + offset + 1; /*check for new sub requests until this end offset*/
+
+ for(gint i=0; i < 64; i +=1){ /*max sub-requests number is 64*/
+ if (internal_last_offset > internal_offset) {
+ sbus_subrequest *sub_req;
+ sub_req = wmem_new(wmem_file_scope(), sbus_subrequest);
+
+ internal_offset += 1; /*move to the next sub-request wcount*/
+ internal_subwcount = tvb_get_guint8(tvb,internal_offset);
+ internal_offset += 1;
+ sub_req->cmd_code = tvb_get_guint8(tvb,internal_offset);
+ internal_offset += 1;
+ sub_req->count = tvb_get_guint8(tvb,internal_offset) + 1;
+ internal_offset += internal_subwcount -1;
+ subrequest_count += 1;
+
+ wmem_list_append(request_list, sub_req);
+ }
+ }
+ return subrequest_count;
+
+}
+
/*Dissect the telegram*/
static int
dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
@@ -632,16 +890,22 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *ti, *hi;
- proto_tree *sbus_tree, *ethsbus_tree, *sbusdata_tree;
+ proto_tree *sbus_tree, *ethsbus_tree, *sbusdata_tree, *sbus_multimedia_tree;
gint i; /*for CRC calculation*/
- gint j; /*for CRC calculation*/
gint offset;
+ gint sbus_end_multimedia;
gint sbus_eth_len;
guint sbus_crc_calc;
guint8 sbus_attribut;
guint8 sbus_media_cnt;
- guint8 sbus_fio_cnt;
+ sbus_subrequest *mm_sub_req;
+ wmem_list_frame_t *frame;
+ guint8 sbus_multimedia_total;
+ guint8 sbus_multimedia_cnt;
+ guint8 sbus_multimedia_cmd;
+ guint8 sbus_multimedia_att;
+ guint8 sbus_multimedia_bytes;
guint8 sbus_cmd_code;
guint8 sbus_web_size;
guint8 sbus_web_aid;
@@ -652,10 +916,7 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
guint8 sbus_rdwr_block_type;
guint8 sbus_rdwr_ack_nak;
guint8 sbus_quint8_helper0;
- guint32 sbus_binarymasked;
- guint32 sbus_binaries;
guint16 sbus_ack_code;
- guint32 sbus_show_bin;
guint32 sbus_rdwr_length;
guint32 sbus_helper;
guint32 sbus_helper1;
@@ -667,6 +928,7 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
conversation_t *conversation;
sbus_request_key request_key, *new_request_key;
sbus_request_val *request_val;
+ /*sbus_multimedia_requests *multimedia_requests;*/
/* does this look like an sbus pdu? */
if(!is_sbus_pdu(tvb)){
@@ -715,10 +977,18 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
request_val->req_frame = pinfo->num; /*store actual frame nr.*/
request_val->req_time = pinfo->abs_ts;
request_val->resp_frame = 0; /*response frame is not known yet*/
+ request_val->mm_request_count = 0; /*init to 0 in case it is no multi media request*/
if (((request_val->cmd_code) == SBUS_RD_USER_EEPROM_REGISTER) ||
((request_val->cmd_code) == SBUS_WR_USER_EEPROM_REGISTER)) {
request_val->count=((tvb_get_guint8(tvb,12))+1);
+ } else if ((request_val->cmd_code) == SBUS_RDWR_MULTI_MEDIAS) {
+ request_val->count=tvb_get_guint8(tvb,11); /*length of all sub requests in bytes*/
+ /*create list for sub requests to be able to process response frame later on*/
+ request_val->sbus_subrequests = wmem_list_new(wmem_file_scope());
+ /*add the sub requests to the list*/
+ request_val->mm_request_count = add_sbus_subrequest(tvb, request_val->sbus_subrequests, 11);
+
} else {
request_val->count=((tvb_get_guint8(tvb,11))+1);
}
@@ -740,6 +1010,7 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
/* End of attaching data to hash table*/
offset = 0;
+ sbus_cmd_code = 0;
switch (sbus_attribut){
case SBUS_REQUEST:
@@ -757,6 +1028,12 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
"Unknown Request!"),
sbus_web_seq);
break;
+ case SBUS_RDWR_MULTI_MEDIAS:
+ sbus_rdwr_type = tvb_get_guint8(tvb, 12);
+ col_add_fstr( pinfo->cinfo, COL_INFO,
+ "Request: Multi media telegram (%d sub requests)",
+ request_val->mm_request_count);
+ break;
case SBUS_RD_WR_PCD_BLOCK:
sbus_rdwr_type = tvb_get_guint8(tvb, 12);
col_add_fstr( pinfo->cinfo, COL_INFO,
@@ -800,10 +1077,8 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
": (File: %s)", tmp_string);
}
}
-
break;
-
default:
/* All other requests */
col_add_fstr(pinfo->cinfo, COL_INFO,
@@ -836,6 +1111,12 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
" (Seq No: %d)",
sbus_web_seq);
}
+ } else if (request_val && ((request_val->cmd_code) == SBUS_RDWR_MULTI_MEDIAS)) {
+ /* Add some info for multi media response*/
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ "Response: Multi media (%d responses)",
+ request_val->mm_request_count);
+
} else if (request_val && ((request_val->cmd_code) == SBUS_RD_WR_PCD_BLOCK)) {
/* Treat the ACK/NAK telgrams in a special way*/
switch (request_val->block_tlg) {
@@ -936,95 +1217,27 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
case SBUS_RD_COUNTER:
case SBUS_RD_REGISTER:
case SBUS_RD_TIMER:
- sbus_media_cnt = (tvb_get_guint8(tvb,offset))+1;
- proto_tree_add_uint(sbus_tree,
- hf_sbus_rcount, tvb, offset, 1, sbus_media_cnt);
- offset += 1;
- proto_tree_add_item(sbus_tree,
- hf_sbus_addr_rtc, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
+ offset = add_media_access_to_tree(sbus_cmd_code, tvb, sbus_tree, offset);
break;
/*Read Flag, Input or Output*/
case SBUS_RD_FLAG:
case SBUS_RD_INPUT:
case SBUS_RD_OUTPUT:
- sbus_media_cnt = (tvb_get_guint8(tvb,offset))+1;
- proto_tree_add_uint(sbus_tree,
- hf_sbus_rcount, tvb, offset, 1, sbus_media_cnt);
- offset += 1;
- proto_tree_add_item(sbus_tree,
- hf_sbus_addr_iof, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
+ offset = add_media_access_to_tree(sbus_cmd_code, tvb, sbus_tree, offset);
break;
/*Write Register Timer Counter*/
case SBUS_WR_COUNTER:
case SBUS_WR_REGISTER:
case SBUS_WR_TIMER:
- sbus_media_cnt = (tvb_get_guint8(tvb,offset));
- sbus_media_cnt = ((sbus_media_cnt - 1)/4);
- proto_tree_add_uint(sbus_tree,
- hf_sbus_wcount_calculated, tvb, offset,
- 1, sbus_media_cnt);
- proto_tree_add_item(sbus_tree,
- hf_sbus_wcount, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(sbus_tree,
- hf_sbus_addr_rtc, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- /*Add subtree for Data*/
- sbusdata_tree = proto_tree_add_subtree(sbus_tree, tvb, offset,
- ((sbus_media_cnt) * 4), ett_sbus_data, NULL, "Data");
- for (i=((sbus_media_cnt)); i>0; i--) {
- proto_tree_add_item(sbusdata_tree,
- hf_sbus_data_rtc, tvb, offset,
- 4, ENC_BIG_ENDIAN);
- offset += 4;
- }
+ offset = add_media_access_to_tree(sbus_cmd_code, tvb, sbus_tree, offset);
break;
/* Write flags and outputs*/
case SBUS_WR_FLAG:
case SBUS_WR_OUTPUT:
- sbus_media_cnt = (tvb_get_guint8(tvb,offset));
- sbus_media_cnt = (sbus_media_cnt - 2);
- proto_tree_add_uint(sbus_tree,
- hf_sbus_wcount_calculated, tvb, offset,
- 1, sbus_media_cnt);
- proto_tree_add_item(sbus_tree,
- hf_sbus_wcount, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- proto_tree_add_item(sbus_tree,
- hf_sbus_addr_iof, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
- sbus_fio_cnt = (tvb_get_guint8(tvb,offset));
- sbus_fio_cnt = ((sbus_fio_cnt + 1));
- proto_tree_add_uint(sbus_tree,
- hf_sbus_fio_count, tvb, offset, 1, sbus_fio_cnt);
- offset += 1;
- /*Add subtree for Data*/
- sbusdata_tree = proto_tree_add_subtree(sbus_tree, tvb, offset,
- sbus_media_cnt, ett_sbus_data, NULL, "Data");
-
- for (i=sbus_media_cnt; i>0; i--) {
- sbus_helper = 1;
- sbus_show_bin = 0;
- sbus_binarymasked = 0x01;
- sbus_binaries = tvb_get_guint8(tvb, offset);
- for (j=0; j<8; j++) {
- if ((sbus_binarymasked & sbus_binaries) != 0) {
- sbus_show_bin = (sbus_show_bin + sbus_helper);
- }
- sbus_binarymasked = sbus_binarymasked<<1;
- sbus_helper = 10 * sbus_helper;
- }
-
- proto_tree_add_uint_format(sbusdata_tree,
- hf_sbus_data_iof, tvb, offset, 1, sbus_show_bin,
- "Binary data: %08u", sbus_show_bin);
- offset += 1;
- }
+ offset = add_media_access_to_tree(sbus_cmd_code, tvb, sbus_tree, offset);
break;
/* Request: Write Real time clock*/
@@ -1054,7 +1267,35 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
"%02x:%02x:%02x", sbus_helper, sbus_helper1, sbus_helper2);
offset += 3;
break;
+ /* Read/write multi media; multiple requests are transmitted within one single telegram*/
+ case SBUS_RDWR_MULTI_MEDIAS:
+ /*Add subtree for Sub-requests*/
+ sbus_multimedia_total = tvb_get_guint8(tvb,offset) + 1;
+ proto_tree_add_uint(sbus_tree,
+ hf_sbus_multimedia_length, tvb, offset, 1, sbus_multimedia_total);
+ offset += 1;
+ sbusdata_tree = proto_tree_add_subtree(sbus_tree, tvb, offset,
+ sbus_multimedia_total, ett_sbus_data, NULL, "Sub requests");
+ sbus_end_multimedia = offset + sbus_multimedia_total;
+ /*Add subtree for each Subrequest*/
+ for (i=0; i<64; i++) { /*max number of sub-requests is 64*/
+ if(offset >= sbus_end_multimedia){
+ break;
+ }
+ sbus_multimedia_cnt = tvb_get_guint8(tvb,offset) + 1;
+ sbus_multimedia_tree = proto_tree_add_subtree_format(sbusdata_tree, tvb, offset,
+ sbus_multimedia_cnt + 1, ett_sbus_data, NULL, "Request %d", i);
+ proto_tree_add_item(sbus_multimedia_tree,
+ hf_sbus_sub_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset +=1;
+ sbus_cmd_code = tvb_get_guint8(tvb,offset);
+ proto_tree_add_item(sbus_multimedia_tree,
+ hf_sbus_command, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+ offset = add_media_access_to_tree(sbus_cmd_code, tvb, sbus_multimedia_tree, offset);
+ }
+ break;
/* Read user memory or program line*/
case SBUS_RD_USER_MEMORY:
case SBUS_RD_PROGRAM_LINE:
@@ -1446,6 +1687,10 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
}
break;
+ case SBUS_RD_DATA_BLOCK:
+ offset = add_media_access_to_tree(sbus_cmd_code, tvb, sbus_tree, offset);
+
+ break;
/*Inform that command was not dissected and add remaining length*/
default:
@@ -1476,15 +1721,9 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
case SBUS_RD_USER_MEMORY:
case SBUS_RD_PROGRAM_LINE:
case SBUS_RD_USER_EEPROM_REGISTER:
+ case SBUS_RD_DATA_BLOCK:
/*Add subtree for Data*/
- sbusdata_tree = proto_tree_add_subtree(sbus_tree, tvb, offset,
- ((request_val->count) * 4), ett_sbus_data, NULL, "Data");
- for (i=(request_val->count); i>0; i--) {
- proto_tree_add_item(sbusdata_tree,
- hf_sbus_data_rtc, tvb, offset,
- 4, ENC_BIG_ENDIAN);
- offset += 4;
- }
+ offset = add_media_response_to_tree(request_val->cmd_code, request_val->count, tvb, sbus_tree, offset);
break;
/* Response: PCD Display register*/
@@ -1499,27 +1738,7 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
case SBUS_RD_INPUT:
case SBUS_RD_OUTPUT:
/*Add subtree for Data*/
- sbusdata_tree = proto_tree_add_subtree(sbus_tree, tvb, offset,
- (((request_val->count) + 7) / 8), ett_sbus_data, NULL, "Data");
-
- for (i=(((request_val->count) + 7) / 8); i>0; i--) {
- sbus_helper = 1;
- sbus_show_bin = 0;
- sbus_binarymasked = 0x01;
- sbus_binaries = tvb_get_guint8(tvb, offset);
- for (j=0; j<8; j++){
- if ((sbus_binarymasked & sbus_binaries) != 0) {
- sbus_show_bin = (sbus_show_bin + sbus_helper);
- }
- sbus_binarymasked = sbus_binarymasked<<1;
- sbus_helper = 10 * sbus_helper;
- }
-
- proto_tree_add_uint_format(sbusdata_tree,
- hf_sbus_data_iof, tvb, offset, 1, sbus_show_bin,
- "Binary data: %08u", sbus_show_bin);
- offset += 1;
- }
+ offset = add_media_response_to_tree(request_val->cmd_code, request_val->count, tvb, sbus_tree, offset);
break;
/* Response: Real time clock value*/
@@ -1550,6 +1769,65 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
offset += 3;
break;
+ case SBUS_RDWR_MULTI_MEDIAS:
+ /*Add subtree for Subrequests*/
+ sbus_multimedia_total = tvb_get_guint8(tvb,offset);
+ proto_tree_add_uint(sbus_tree,
+ hf_sbus_multimedia_length, tvb, offset, 1, sbus_multimedia_total);
+ offset += 1;
+ sbusdata_tree = proto_tree_add_subtree(sbus_tree, tvb, offset,
+ sbus_multimedia_total, ett_sbus_data, NULL, "Sub responses");
+ sbus_end_multimedia = offset + sbus_multimedia_total;
+ i = 0;
+ /* Start at front of list and cycle through possible sub-requests,
+ until all bytes or all requests are processed */
+ frame = wmem_list_head(request_val->sbus_subrequests);
+ while (frame && (offset < sbus_end_multimedia)) {
+ mm_sub_req = (sbus_subrequest *)wmem_list_frame_data(frame);
+ sbus_multimedia_cmd = mm_sub_req->cmd_code;
+ sbus_multimedia_cnt = mm_sub_req->count;
+
+ /*get the attribute of the sub-response (1: response, 2: ACK/NACK)*/
+ sbus_multimedia_att = tvb_get_guint8(tvb,offset + 1) ;
+
+ if (sbus_multimedia_att == SBUS_ACKNAK) {
+ sbus_multimedia_tree = proto_tree_add_subtree_format(sbusdata_tree, tvb, offset,
+ 4, ett_sbus_data, NULL, "Response %d", i);
+ proto_tree_add_item(sbus_multimedia_tree,
+ hf_sbus_sub_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset +=1;
+ proto_tree_add_item(sbus_multimedia_tree,
+ hf_sbus_attribut, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset +=1;
+ hi = proto_tree_add_item(sbus_multimedia_tree,
+ hf_sbus_acknackcode, tvb, offset, 2, ENC_BIG_ENDIAN);
+ if (tvb_get_guint8(tvb, (offset+1)) > 0) {
+ expert_add_info(pinfo, hi, &ei_sbus_telegram_not_acked);
+ }
+ offset += 2;
+
+ } else { /*response containing data*/
+ sbus_multimedia_bytes = get_response_length(sbus_multimedia_cmd, sbus_multimedia_cnt);
+ sbus_multimedia_tree = proto_tree_add_subtree_format(sbusdata_tree, tvb, offset,
+ sbus_multimedia_bytes + 2, ett_sbus_data, NULL, "Response %d", i);
+ proto_tree_add_item(sbus_multimedia_tree,
+ hf_sbus_sub_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset +=1;
+ proto_tree_add_item(sbus_multimedia_tree,
+ hf_sbus_attribut, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset +=1;
+
+ add_media_response_to_tree(sbus_multimedia_cmd, sbus_multimedia_cnt, tvb, sbus_multimedia_tree, offset);
+ offset +=sbus_multimedia_bytes ;
+ }
+
+ /* After processing this sub request, proceed to the next */
+ frame = wmem_list_frame_next(frame);
+ i++;
+ }
+
+ break;
+
/* Response: CPU status, the command codes 14..1B are concerned*/
case SBUS_RD_PCD_STATUS_CPU0:
case SBUS_RD_PCD_STATUS_CPU1:
@@ -1653,7 +1931,7 @@ dissect_sbus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
offset += 2;
break;
- /* Response: Read system infomation (without interpretation of module info)*/
+ /* Response: Read system information (without interpretation of module info)*/
case SBUS_RD_SYSTEM_INFORMATION:
if (request_val->sysinfo == 0x00){ /*sysinfo 0*/
offset += 1; /* this byte is always 0x01*/
@@ -1910,6 +2188,18 @@ proto_register_sbus(void)
"Number of elements expected in response", HFILL }
},
+ { &hf_sbus_sub_length,
+ { "Sub length", "sbus.sublength",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "Length of multi-media response or request in bytes, length and command code fields not included", HFILL }
+ },
+
+ { &hf_sbus_multimedia_length,
+ { "Multi-media length", "sbus.mmlength",
+ FT_UINT8, BASE_DEC, NULL, 0,
+ "Length of all multi-media request or responses in bytes", HFILL }
+ },
+
{ &hf_sbus_wcount,
{ "W-count (raw)", "sbus.wcount",
FT_UINT8, BASE_DEC, NULL, 0,
@@ -1940,6 +2230,18 @@ proto_register_sbus(void)
"Base address of binary elements to read", HFILL }
},
+ { &hf_sbus_addr_db,
+ { "DB address", "sbus.addr_db",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ "Datablock address to read from", HFILL }
+ },
+
+ { &hf_sbus_addr_base_element,
+ { "Base DB element address", "sbus.db_base_element",
+ FT_UINT16, BASE_DEC, NULL, 0,
+ "Base Datablock element address of 32 bit values to read", HFILL }
+ },
+
{ &hf_sbus_addr_eeprom,
{ "Base address of EEPROM register", "sbus.addr_EEPROM",
FT_UINT16, BASE_DEC, NULL, 0,