diff options
author | chrisdurrer <christian.durrer@sensemail.ch> | 2019-02-20 21:57:08 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2019-02-26 06:51:27 +0000 |
commit | a4068a9057d8d0a77f4d259b78e15831ac6e2fe1 (patch) | |
tree | 2d4df420184d13b79a6997ee827e5be58097a7ee /epan/dissectors/packet-sbus.c | |
parent | 6e1d30ce878d1ce706ad10dfe9699ec5dd3ef6a4 (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.c | 544 |
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, |