AT: Implement CMGR command (binary mode)

This commit is contained in:
DarienSpencer65 2022-08-25 16:47:28 +00:00 committed by Jaap Keuter
parent 52e34b2531
commit f593c4165e
1 changed files with 174 additions and 0 deletions

View File

@ -60,6 +60,12 @@ static int hf_cmgl_msg_status = -1;
static int hf_cmgl_msg_originator_name = -1;
static int hf_cmgl_msg_length = -1;
static int hf_cmgl_msg_pdu = -1;
static int hf_cmgr_address = -1;
static int hf_cmgr_mode = -1;
static int hf_cmgr_msg_index = -1;
static int hf_cmgr_msg_length = -1;
static int hf_cmgr_msg_pdu = -1;
static int hf_cmgr_stat = -1;
static int hf_cmux_k = -1;
static int hf_cmux_n1 = -1;
static int hf_cmux_n2 = -1;
@ -409,6 +415,21 @@ static const value_string clcc_mpty_vals[] = {
{ 0, NULL }
};
static const value_string cmgr_mode_vals[] = {
{ 0, "Normal (Change unread to read)" },
{ 1, "Do not change unread to read" },
{ 0, NULL }
};
static const value_string cmgr_stat_vals[] = {
{ 0, "Received unread (i.e. new message)" },
{ 1, "Received read" },
{ 2, "Stored unsent" },
{ 3, "Stored sent" },
{ 4, "All" },
{ 0, NULL }
};
static const value_string ccwa_show_result_code_vals[] = {
{ 0, "Disabled" },
{ 1, "Enabled" },
@ -731,6 +752,13 @@ static gboolean check_cmgl(gint role, guint16 type) {
return FALSE;
}
static gboolean check_cmgr(gint role, guint16 type) {
if (role == ROLE_DTE && (type == TYPE_ACTION || type == TYPE_TEST)) return TRUE;
if (role == ROLE_DCE && type == TYPE_RESPONSE) return TRUE;
return FALSE;
}
static gboolean check_cmux(gint role, guint16 type) {
if (role == ROLE_DTE && (type == TYPE_ACTION || type == TYPE_READ || type == TYPE_TEST)) return TRUE;
if (role == ROLE_DCE && type == TYPE_RESPONSE) return TRUE;
@ -1424,6 +1452,117 @@ dissect_cmgl_parameter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
return TRUE;
}
static gboolean
dissect_cmgr_data_part(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree, gint offset, gint role, guint16 type,
guint8 *data_part_stream _U_, guint data_part_number _U_,
gint data_part_length, at_packet_info_t *at_info _U_)
{
proto_item *pitem;
gint hex_length;
gint bytes_count;
gint i;
guint8 *final_arr;
tvbuff_t *final_tvb = NULL;
if (!(role == ROLE_DCE && type == TYPE_RESPONSE)) {
return FALSE;
}
pitem = proto_tree_add_item(tree, hf_cmgr_msg_pdu, tvb, offset, data_part_length, ENC_NA | ENC_ASCII);
hex_length = data_part_length;
if (hex_length % 2 == 1) {
expert_add_info(pinfo, pitem, &ei_odd_len);
return TRUE;
}
if (hex_length < 1) {
expert_add_info(pinfo, pitem, &ei_empty_hex);
return TRUE;
}
bytes_count = hex_length / 2;
final_arr = wmem_alloc0_array(pinfo->pool, guint8, bytes_count + 1);
/* Try to parse the hex string into a byte array */
guint8 *pos = data_part_stream;
pos += 16;
for (i = 8; i < bytes_count; i++) {
if (!g_ascii_isxdigit(*pos) || !g_ascii_isxdigit(*(pos + 1))) {
/* Either current or next char isn't a hex character */
expert_add_info(pinfo, pitem, &ei_invalid_hex);
return TRUE;
}
sscanf((char *)pos, "%2hhx", &(final_arr[i-8]));
pos += 2;
}
final_tvb = tvb_new_child_real_data(tvb, final_arr, bytes_count, bytes_count);
add_new_data_source(pinfo, final_tvb, "GSM SMS payload");
/* Adjusting P2P direction as it is read by the SMS dissector */
int at_dir = pinfo->p2p_dir;
pinfo->p2p_dir = P2P_DIR_SENT;
/* Call GSM SMS dissector*/
call_dissector_only(gsm_sms_handle, final_tvb, pinfo, tree, NULL);
/* Restoring P2P direction */
pinfo->p2p_dir = at_dir;
return TRUE;
}
static gboolean
dissect_cmgr_parameter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
gint offset, gint role, guint16 type, guint8 *parameter_stream,
guint parameter_number, gint parameter_length, at_packet_info_t *at_info, void **data _U_)
{
guint32 value = 0;
if (!((role == ROLE_DTE && type == TYPE_ACTION) ||
(role == ROLE_DCE && type == TYPE_RESPONSE))) {
return FALSE;
}
if (role == ROLE_DTE && parameter_number > 1)
return FALSE;
else if (role == ROLE_DCE && parameter_number > 3)
return FALSE;
if (role == ROLE_DTE) {
switch (parameter_number) {
case 0:
value = get_uint_parameter(pinfo->pool, parameter_stream, parameter_length);
proto_tree_add_uint(tree, hf_cmgr_msg_index, tvb, offset, parameter_length, value);
break;
case 1:
value = get_uint_parameter(pinfo->pool, parameter_stream, parameter_length);
proto_tree_add_uint(tree, hf_cmgr_mode, tvb, offset, parameter_length, value);
break;
}
} else {
switch (parameter_number) {
case 0:
value = get_uint_parameter(pinfo->pool, parameter_stream, parameter_length);
proto_tree_add_uint(tree, hf_cmgr_stat, tvb, offset, parameter_length, value);
break;
case 1:
proto_tree_add_item(tree, hf_cmgr_address, tvb, offset, parameter_length, ENC_NA | ENC_ASCII);
break;
case 2:
value = get_uint_parameter(pinfo->pool, parameter_stream, parameter_length);
proto_tree_add_uint(tree, hf_cmgr_msg_length, tvb, offset, parameter_length, value);
// If we reached the length parameter we are
// expecting the next line to be our encoded data
at_processed_cmd_t * at_cmd = get_current_role_last_command(at_info, role);
if (!at_cmd)
break;
at_cmd->type = type;
at_cmd->expected_data_parts = 1;
at_cmd->consumed_data_parts = 0;
at_cmd->dissect_data = dissect_cmgr_data_part;
break;
}
}
return TRUE;
}
static gboolean
dissect_cmux_parameter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
gint offset, gint role, guint16 type, guint8 *parameter_stream,
@ -1923,6 +2062,7 @@ static const at_cmd_t at_cmds[] = {
{ "+CMEE", "Mobile Equipment Error", check_cmee, dissect_cmee_parameter },
{ "+CMER", "Event Reporting Activation/Deactivation", check_cmer, dissect_cmer_parameter },
{ "+CMGL", "List SMS messages", check_cmgl, dissect_cmgl_parameter },
{ "+CMGR", "Read SMS message", check_cmgr, dissect_cmgr_parameter },
{ "+CMUX", "Multiplexing mode", check_cmux, dissect_cmux_parameter },
{ "+CNUM", "Subscriber Number Information", check_cnum, dissect_cnum_parameter },
{ "+COPS", "Reading Network Operator", check_cops, dissect_cops_parameter },
@ -2577,6 +2717,40 @@ proto_register_at_command(void)
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL}
},
{ &hf_cmgr_address,
{ "Address", "at.cmgr.address",
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL}
},
{ &hf_cmgr_mode,
{ "Mode", "at.cmgr.mode",
FT_UINT16, BASE_DEC, VALS(cmgr_mode_vals), 0,
"Reading mode",
HFILL}
},
{ &hf_cmgr_msg_index,
{ "Index", "at.cmgr.msg_index",
FT_UINT16, BASE_DEC, NULL, 0,
"Index of the message",
HFILL}
},
{ &hf_cmgr_msg_length,
{ "Length", "at.cmgr.pdu_length",
FT_UINT16, BASE_DEC, NULL, 0,
"PDU Length",
HFILL}
},
{ &hf_cmgr_msg_pdu,
{ "SMS PDU", "at.cmgr.pdu",
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL}
},
{ &hf_cmgr_stat,
{ "Status", "at.cmgr.status",
FT_UINT32, BASE_DEC, VALS(cmgr_stat_vals), 0,
"Status of the returned message",
HFILL}
},
{ &hf_cmux_k,
{ "Window Size", "at.k",
FT_UINT8, BASE_DEC, NULL, 0,