diff --git a/doc/README.dissector b/doc/README.dissector index 6a28b63e4a..ef38ad955f 100644 --- a/doc/README.dissector +++ b/doc/README.dissector @@ -1534,6 +1534,10 @@ currently supported are: ENC_KEYPAD_BC_TBCD - keypad-with-B/C "telephony packed BCD" = 0-9, B, C, *, # ENC_GB18030 - GB 18030 ENC_EUC_KR - EUC-KR + ENC_DECT_STANDARD_8BITS - DECT standard 8 bit character set as defined in + ETSI EN 300 175-5 + ENC_DECT_STANDARD_4BITS_TBCD - DECT standard 4 bit character set "telephony + packet BCD" = 0-9, 0xb = SPACE Other encodings will be added in the future. diff --git a/epan/charsets.c b/epan/charsets.c index aaeb0e4585..5e03c9625c 100644 --- a/epan/charsets.c +++ b/epan/charsets.c @@ -1880,6 +1880,46 @@ get_t61_string(wmem_allocator_t *scope, const guint8 *ptr, gint length) return (guint8 *)wmem_strbuf_finalize(strbuf); } +/* The DECT standard charset from ETSI EN 300 175-5 Annex D + */ +static const gunichar2 dect_standard_8bits_code_table[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + ' ', '!', '\"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', + 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, +}; + +guint8 * +get_dect_standard_8bits_string(wmem_allocator_t *scope, const guint8 *ptr, gint length) +{ + gint position; + const guint8 *current_byte_ptr; + wmem_strbuf_t *strbuf; + + strbuf = wmem_strbuf_sized_new(scope, length+1, 0); + + for (position = 0, current_byte_ptr = ptr; position < length; current_byte_ptr++, position++) { + if (!dect_standard_8bits_code_table[*current_byte_ptr]) { + wmem_strbuf_append_unichar(strbuf, UNREPL); + } else { + wmem_strbuf_append_unichar(strbuf, dect_standard_8bits_code_table[*current_byte_ptr]); + } + } + + return (guint8 *)wmem_strbuf_finalize(strbuf); +} /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * diff --git a/epan/charsets.h b/epan/charsets.h index 9018a3d3b5..f03bfdc876 100644 --- a/epan/charsets.h +++ b/epan/charsets.h @@ -214,6 +214,8 @@ get_euc_kr_string(wmem_allocator_t *scope, const guint8 *ptr, gint length); WS_DLL_PUBLIC guint8 * get_t61_string(wmem_allocator_t *scope, const guint8 *ptr, gint length); +WS_DLL_PUBLIC guint8 * +get_dect_standard_8bits_string(wmem_allocator_t *scope, const guint8 *ptr, gint length); #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/epan/proto.h b/epan/proto.h index 3881de3da4..e77810ad08 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -426,6 +426,8 @@ void proto_report_dissector_bug(const char *format, ...) #define ENC_GB18030 0x00000050 #define ENC_EUC_KR 0x00000052 #define ENC_APN_STR 0x00000054 /* The encoding the APN/DNN field follows 3GPP TS 23.003 [2] clause 9.1.*/ +#define ENC_DECT_STANDARD_8BITS 0x00000056 /* DECT standard character set as defined in ETSI EN 300 175-5 Annex D */ +#define ENC_DECT_STANDARD_4BITS_TBCD 0x00000058 /* DECT standard 4bits character set as defined in ETSI EN 300 175-5 Annex D (BCD with 0xb = SPACE)*/ /* * TODO: * diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 4f0bfdab82..0ddea8bd95 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -1722,6 +1722,7 @@ validate_single_byte_ascii_encoding(const guint encoding) case ENC_KEYPAD_BC_TBCD: case ENC_ETSI_TS_102_221_ANNEX_A: case ENC_APN_STR: + case ENC_DECT_STANDARD_4BITS_TBCD: REPORT_DISSECTOR_BUG("Invalid string encoding type passed to tvb_get_string_XXX"); break; default: @@ -3009,6 +3010,13 @@ static const dgt_set_t Dgt_ansi_tbcd = { } }; +static const dgt_set_t Dgt_dect_standard_4bits_tbcd = { + { + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + '0','1','2','3','4','5','6','7','8','9','?',' ','?','?','?','?' + } +}; + static guint8 * tvb_get_apn_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint length) @@ -3076,6 +3084,15 @@ end: return (guint8 *) wmem_strbuf_finalize(str); } +static guint8 * +tvb_get_dect_standard_8bits_string(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint length) +{ + const guint8 *ptr; + + ptr = ensure_contiguous(tvb, offset, length); + return get_dect_standard_8bits_string(scope, ptr, length); +} + /* * Given a tvbuff, an offset, a length, and an encoding, allocate a * buffer big enough to hold a non-null-terminated string of that length @@ -3313,6 +3330,20 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, case ENC_APN_STR: strptr = tvb_get_apn_string(scope, tvb, offset, length); break; + + case ENC_DECT_STANDARD_8BITS: + strptr = tvb_get_dect_standard_8bits_string(scope, tvb, offset, length); + break; + + case ENC_DECT_STANDARD_4BITS_TBCD: + /* + * DECT standard 4bits "telephony BCD" - packed BCD, with + * digits 0-9 and symbol SPACE for 0xb. + */ + odd = (encoding & ENC_BCD_ODD_NUM_DIG) >> 16; + skip_first = (encoding & ENC_BCD_SKIP_FIRST) >> 17; + strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_dect_standard_4bits_tbcd, skip_first, odd, FALSE); + break; } return strptr; } @@ -3545,6 +3576,20 @@ tvb_get_euc_kr_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint return get_euc_kr_string(scope, ptr, size); } +static guint8 * +tvb_get_dect_standard_8bits_stringz(wmem_allocator_t *scope, tvbuff_t *tvb, gint offset, gint *lengthp) +{ + guint size; + const guint8 *ptr; + + size = tvb_strsize(tvb, offset); + ptr = ensure_contiguous(tvb, offset, size); + /* XXX, conversion between signed/unsigned integer */ + if (lengthp) + *lengthp = size; + return get_t61_string(scope, ptr, size); +} + guint8 * tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding) { @@ -3727,6 +3772,10 @@ tvb_get_stringz_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, g case ENC_EUC_KR: strptr = tvb_get_euc_kr_stringz(scope, tvb, offset, lengthp); break; + + case ENC_DECT_STANDARD_8BITS: + strptr = tvb_get_dect_standard_8bits_stringz(scope, tvb, offset, lengthp); + break; } return strptr;