diff options
author | Dan Williams <dcbw@redhat.com> | 2011-11-11 23:39:20 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2011-11-11 23:39:20 -0600 |
commit | 1aa6d01d53f2034e85156c3d3fece4d198ba6035 (patch) | |
tree | d5c64de0083150beb12cbb4447e77962ddc5ebfa /libwmc | |
parent | ae3f1cd578e59245a6bff5cfd19f64f0c47f5de9 (diff) | |
download | ModemManager-1aa6d01d53f2034e85156c3d3fece4d198ba6035.tar.gz |
wmc: protocol and testcase update
Diffstat (limited to 'libwmc')
-rw-r--r-- | libwmc/src/commands.c | 98 | ||||
-rw-r--r-- | libwmc/src/commands.h | 15 | ||||
-rw-r--r-- | libwmc/src/protocol.h | 85 | ||||
-rw-r--r-- | libwmc/tests/test-wmc-com.c | 65 | ||||
-rw-r--r-- | libwmc/tests/test-wmc-com.h | 2 | ||||
-rw-r--r-- | libwmc/tests/test-wmc.c | 1 |
6 files changed, 262 insertions, 4 deletions
diff --git a/libwmc/src/commands.c b/libwmc/src/commands.c index cda4a5bee..0128a8a9f 100644 --- a/libwmc/src/commands.c +++ b/libwmc/src/commands.c @@ -131,12 +131,16 @@ wmc_cmd_device_info_result (const char *buf, gsize buflen) { WmcResult *r = NULL; WmcCmdDeviceInfoRsp *rsp = (WmcCmdDeviceInfoRsp *) buf; + WmcCmdDeviceInfo2Rsp *rsp2 = (WmcCmdDeviceInfo2Rsp *) buf; char tmp[65]; g_return_val_if_fail (buf != NULL, NULL); - if (check_command (buf, buflen, WMC_CMD_DEVICE_INFO, sizeof (WmcCmdDeviceInfoRsp)) < 0) - return NULL; + if (check_command (buf, buflen, WMC_CMD_DEVICE_INFO, sizeof (WmcCmdDeviceInfo2Rsp)) < 0) { + rsp2 = NULL; + if (check_command (buf, buflen, WMC_CMD_DEVICE_INFO, sizeof (WmcCmdDeviceInfoRsp)) < 0) + return NULL; + } r = wmc_result_new (); @@ -164,6 +168,96 @@ wmc_cmd_device_info_result (const char *buf, gsize buflen) memcpy (tmp, rsp->hwrev, sizeof (rsp->hwrev)); wmc_result_add_string (r, WMC_CMD_DEVICE_INFO_ITEM_HW_REVISION, tmp); + if (rsp2) { + /* IMEI */ + memset (tmp, 0, sizeof (tmp)); + g_assert (sizeof (rsp2->imei) <= sizeof (tmp)); + memcpy (tmp, rsp2->imei, sizeof (rsp2->imei)); + wmc_result_add_string (r, WMC_CMD_DEVICE_INFO_ITEM_IMEI, tmp); + + /* IMSI */ + memset (tmp, 0, sizeof (tmp)); + g_assert (sizeof (rsp2->imsi) <= sizeof (tmp)); + memcpy (tmp, rsp2->imsi, sizeof (rsp2->imsi)); + wmc_result_add_string (r, WMC_CMD_DEVICE_INFO_ITEM_IMSI, tmp); + + /* MCC */ + memset (tmp, 0, sizeof (tmp)); + g_assert (sizeof (rsp2->mcc) <= sizeof (tmp)); + memcpy (tmp, rsp2->mcc, sizeof (rsp2->mcc)); + wmc_result_add_string (r, WMC_CMD_DEVICE_INFO_ITEM_MCC, tmp); + + /* MNC */ + memset (tmp, 0, sizeof (tmp)); + g_assert (sizeof (rsp2->mnc) <= sizeof (tmp)); + memcpy (tmp, rsp2->mnc, sizeof (rsp2->mnc)); + wmc_result_add_string (r, WMC_CMD_DEVICE_INFO_ITEM_MNC, tmp); + } + + return r; +} + +/**********************************************************************/ + +size_t +wmc_cmd_status_new (char *buf, size_t buflen) +{ + WmcCmdHeader *cmd = (WmcCmdHeader *) buf; + + wmc_return_val_if_fail (buf != NULL, 0); + wmc_return_val_if_fail (buflen >= sizeof (*cmd), 0); + + memset (cmd, 0, sizeof (*cmd)); + cmd->marker = WMC_CMD_MARKER; + cmd->cmd = WMC_CMD_STATUS; + return sizeof (*cmd); +} + +static u_int8_t +sanitize_dbm (u_int8_t in_dbm) +{ + /* 0x7D (-125 dBm) really means no signal */ + return in_dbm >= 0x7D ? 0 : in_dbm; +} + +WmcResult * +wmc_cmd_status_result (const char *buf, gsize buflen) +{ + WmcResult *r = NULL; + WmcCmdStatusRsp *rsp = (WmcCmdStatusRsp *) buf; + WmcCmdStatus2Rsp *rsp2 = (WmcCmdStatus2Rsp *) buf; + char tmp[65]; + + g_return_val_if_fail (buf != NULL, NULL); + + if (check_command (buf, buflen, WMC_CMD_STATUS, sizeof (WmcCmdStatus2Rsp)) < 0) { + rsp2 = NULL; + if (check_command (buf, buflen, WMC_CMD_STATUS, sizeof (WmcCmdStatusRsp)) < 0) + return NULL; + } + + r = wmc_result_new (); + + wmc_result_add_u8 (r, WMC_CMD_STATUS_ITEM_CDMA_DBM, sanitize_dbm (rsp->cdma1x_dbm)); + + if (rsp2) { + wmc_result_add_u8 (r, WMC_CMD_STATUS_ITEM_HDR_DBM, sanitize_dbm (rsp2->hdr_dbm)); + wmc_result_add_u8 (r, WMC_CMD_STATUS_ITEM_LTE_DBM, sanitize_dbm (rsp2->lte_dbm)); + + memset (tmp, 0, sizeof (tmp)); + if (sanitize_dbm (rsp2->lte_dbm)) { + /* LTE operator name */ + g_assert (sizeof (rsp2->lte_opname) <= sizeof (tmp)); + memcpy (tmp, rsp2->lte_opname, sizeof (rsp2->lte_opname)); + wmc_result_add_string (r, WMC_CMD_STATUS_ITEM_OPNAME, tmp); + } else if (sanitize_dbm (rsp2->hdr_dbm) || sanitize_dbm (rsp2->cdma1x_dbm)) { + /* CDMA2000 operator name */ + g_assert (sizeof (rsp2->cdma_opname) <= sizeof (tmp)); + memcpy (tmp, rsp2->cdma_opname, sizeof (rsp2->cdma_opname)); + wmc_result_add_string (r, WMC_CMD_STATUS_ITEM_OPNAME, tmp); + } + } + return r; } diff --git a/libwmc/src/commands.h b/libwmc/src/commands.h index 60ecdac08..a6c5abf41 100644 --- a/libwmc/src/commands.h +++ b/libwmc/src/commands.h @@ -36,6 +36,10 @@ WmcResult * wmc_cmd_init_result (const char *buf, size_t len, int wmc2); #define WMC_CMD_DEVICE_INFO_ITEM_MODEL "model" #define WMC_CMD_DEVICE_INFO_ITEM_FW_REVISION "firmware-revision" #define WMC_CMD_DEVICE_INFO_ITEM_HW_REVISION "hardware-revision" +#define WMC_CMD_DEVICE_INFO_ITEM_IMEI "imei" +#define WMC_CMD_DEVICE_INFO_ITEM_IMSI "imsi" +#define WMC_CMD_DEVICE_INFO_ITEM_MCC "mcc" +#define WMC_CMD_DEVICE_INFO_ITEM_MNC "mnc" size_t wmc_cmd_device_info_new (char *buf, size_t buflen); @@ -43,4 +47,15 @@ WmcResult * wmc_cmd_device_info_result (const char *buf, size_t len); /**********************************************************************/ +#define WMC_CMD_STATUS_ITEM_CDMA_DBM "cdma-dbm" +#define WMC_CMD_STATUS_ITEM_HDR_DBM "hdr-dbm" +#define WMC_CMD_STATUS_ITEM_LTE_DBM "lte-dbm" +#define WMC_CMD_STATUS_ITEM_OPNAME "opname" + +size_t wmc_cmd_status_new (char *buf, size_t buflen); + +WmcResult * wmc_cmd_status_result (const char *buf, size_t len); + +/**********************************************************************/ + #endif /* LIBWMC_COMMANDS_H */ diff --git a/libwmc/src/protocol.h b/libwmc/src/protocol.h index b09322dd8..3f0ef4a95 100644 --- a/libwmc/src/protocol.h +++ b/libwmc/src/protocol.h @@ -49,7 +49,6 @@ struct WmcCmdInit2Rsp { } __attribute__ ((packed)); typedef struct WmcCmdInit2Rsp WmcCmdInit2Rsp; - struct WmcCmdDeviceInfoRsp { WmcCmdHeader hdr; u_int8_t _unknown1[27]; @@ -65,5 +64,89 @@ struct WmcCmdDeviceInfoRsp { } __attribute__ ((packed)); typedef struct WmcCmdDeviceInfoRsp WmcCmdDeviceInfoRsp; +struct WmcCmdDeviceInfo2Rsp { + WmcCmdHeader hdr; + u_int8_t _unknown1[27]; + char manf[64]; + char model[64]; + char fwrev[64]; + char hwrev[64]; + u_int8_t _unknown2[64]; + u_int8_t _unknown3[64]; + u_int8_t _unknown4[22]; + u_int8_t _unknown5[8]; + u_int8_t _unknown6[6]; + u_int8_t _unknown7[64]; + u_int8_t _unknown8[20]; + u_int8_t imei[22]; + u_int8_t _unknown9[16]; + u_int8_t imsi[22]; + u_int8_t _unknown10[4]; + u_int8_t mcc[16]; + u_int8_t mnc[16]; + u_int8_t _unknown11[4]; + u_int8_t _unknown12[4]; + u_int8_t _unknown13[4]; +} __attribute__ ((packed)); +typedef struct WmcCmdDeviceInfo2Rsp WmcCmdDeviceInfo2Rsp; + +/* Shorter response used by earlier devices like PC5740 */ +struct WmcCmdStatusRsp { + WmcCmdHeader hdr; + u_int8_t _unknown1; + u_int8_t _unknown2[3]; /* Always zero */ + u_int8_t _unknown3; /* Always 0x06 */ + u_int8_t _unknown4; /* Either 0x00 or 0x01 */ + u_int8_t magic[10]; + u_int16_t counter1; /* A timestamp/counter? */ + u_int8_t _unknown5; + u_int8_t _unknown6; + u_int8_t _unknown7[3]; /* Always 0xFE 0xFF 0xFF */ + u_int8_t cdma1x_dbm; + u_int8_t _unknown8[37]; /* Always zero */ +} __attribute__ ((packed)); +typedef struct WmcCmdStatusRsp WmcCmdStatusRsp; + +/* Long-format response used on newer devices like the UML290 */ +struct WmcCmdStatus2Rsp { + WmcCmdHeader hdr; + u_int8_t _unknown1; /* 0x00 on LTE, 0x07 or 0x1F on CDMA */ + u_int8_t _unknown2[3]; /* Always zero */ + u_int8_t _unknown3; /* 0x0E on LTE, 0x0F on CDMA */ + u_int8_t _unknown4; + u_int8_t magic[10]; /* Whatever was passed in WMC_CMD_INIT with some changes */ + u_int16_t counter1; /* A timestamp/counter? */ + u_int16_t counter2; /* Time since firmware start? */ + u_int8_t _unknown5; /* 0x00 on LTE, various values (0xD4, 0x5C) on CDMA */ + u_int8_t _unknown6[3]; /* always zero on LTE, 0xFE 0xFF 0xFF on CDMA */ + u_int8_t cdma1x_dbm; /* 0x7D = no signal */ + u_int8_t _unknown7[3]; /* Always zero */ + u_int8_t cdma_opname[16]; /* Zero terminated? */ + u_int8_t _unknown8[18]; /* Always zero */ + u_int8_t hdr_dbm; /* 0x7D = no signal */ + u_int8_t _unknown9[3]; /* Always zero */ + u_int8_t _unknown10; /* 0x01 on LTE, 0x40 on CDMA */ + u_int8_t _unknown11[3]; /* Always zero */ + u_int8_t _unknown12; /* Always 0x01 */ + u_int8_t lte_opname[8]; /* Zero terminated? Sometimes "MCC MNC" too */ + u_int8_t _unknown13[60]; /* Always zero */ + u_int8_t lte_dbm; /* 0x00 if not in LTE mode */ + u_int8_t _unknown14[3]; /* Always zero */ + u_int8_t _unknown15[4]; +} __attribute__ ((packed)); +typedef struct WmcCmdStatus2Rsp WmcCmdStatus2Rsp; + +struct WmcCmdIpInfoRsp { + WmcCmdHeader hdr; + u_int32_t xfer_bytes; + u_int32_t xfer_bytes2; /* Same value as xfer_bytes */ + u_int8_t _unknown3[8]; + u_int8_t _unknown4; /* Either 0x01, 0x02, 0x03, or 0x04 */ + u_int8_t _unknown5[7]; /* Always 0xc0 0x0b 0x00 0x01 0x00 0x00 0x00 */ + u_int8_t ip4_address[16]; /* String format, ie "10.156.45.3" */ + u_int8_t _unknown6[8]; /* Netmask? */ + u_int8_t ip6_address[40]; /* String format */ +} __attribute__ ((packed)); +typedef struct WmcCmdIpInfoRsp WmcCmdIpInfoRsp; #endif /* LIBWMC_PROTOCOL_H */ diff --git a/libwmc/tests/test-wmc-com.c b/libwmc/tests/test-wmc-com.c index bf906ed60..203aeefe0 100644 --- a/libwmc/tests/test-wmc-com.c +++ b/libwmc/tests/test-wmc-com.c @@ -258,7 +258,7 @@ test_com_device_info (void *f, void *data) TestComData *d = data; gboolean success; char buf[1024]; - const char *str; + const char *str, *str2; gint len; WmcResult *result; gsize reply_len; @@ -295,6 +295,69 @@ test_com_device_info (void *f, void *data) wmc_result_get_string (result, WMC_CMD_DEVICE_INFO_ITEM_HW_REVISION, &str); g_message ("%s: HW Revision: %s", __func__, str); + str = NULL; + wmc_result_get_string (result, WMC_CMD_DEVICE_INFO_ITEM_IMEI, &str); + g_message ("%s: IMEI: %s", __func__, str ? str : "(none)"); + + str = NULL; + wmc_result_get_string (result, WMC_CMD_DEVICE_INFO_ITEM_IMSI, &str); + g_message ("%s: IMSI: %s", __func__, str ? str : "(none)"); + + str = NULL; + wmc_result_get_string (result, WMC_CMD_DEVICE_INFO_ITEM_MCC, &str); + str2 = NULL; + wmc_result_get_string (result, WMC_CMD_DEVICE_INFO_ITEM_MNC, &str2); + g_message ("%s: MCC/MNC: %s %s", __func__, + str ? str : "(none)", + str2 ? str2 : "(none)"); + + wmc_result_unref (result); +} + +void +test_com_status (void *f, void *data) +{ + TestComData *d = data; + gboolean success; + char buf[1024]; + const char *str; + u_int8_t dbm; + gint len; + WmcResult *result; + gsize reply_len; + + len = wmc_cmd_status_new (buf, sizeof (buf)); + g_assert (len == 2); + + /* Send the command */ + success = send_command (d, buf, sizeof (buf), len); + g_assert (success); + + /* Get a response */ + reply_len = wait_reply (d, buf, sizeof (buf)); + + /* Parse the response into a result structure */ + result = wmc_cmd_status_result (buf, reply_len); + g_assert (result); + + g_print ("\n"); + + dbm = 0; + wmc_result_get_u8 (result, WMC_CMD_STATUS_ITEM_CDMA_DBM, &dbm); + g_message ("%s: CDMA 1x dBm: %d", __func__, dbm); + + dbm = 0; + wmc_result_get_u8 (result, WMC_CMD_STATUS_ITEM_HDR_DBM, &dbm); + g_message ("%s: HDR dBm: %d", __func__, dbm); + + dbm = 0; + wmc_result_get_u8 (result, WMC_CMD_STATUS_ITEM_LTE_DBM, &dbm); + g_message ("%s: LTE dBm: %d", __func__, dbm); + + str = NULL; + wmc_result_get_string (result, WMC_CMD_STATUS_ITEM_OPNAME, &str); + g_message ("%s: Operator Name: %s", __func__, str ? str : "(none)"); + wmc_result_unref (result); } diff --git a/libwmc/tests/test-wmc-com.h b/libwmc/tests/test-wmc-com.h index a26d364f4..6c3d2a07a 100644 --- a/libwmc/tests/test-wmc-com.h +++ b/libwmc/tests/test-wmc-com.h @@ -27,5 +27,7 @@ void test_com_init (void *f, void *data); void test_com_device_info (void *f, void *data); +void test_com_status (void *f, void *data); + #endif /* TEST_WMC_COM_H */ diff --git a/libwmc/tests/test-wmc.c b/libwmc/tests/test-wmc.c index 91a2c271c..6479312a8 100644 --- a/libwmc/tests/test-wmc.c +++ b/libwmc/tests/test-wmc.c @@ -102,6 +102,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_com_port_init, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_init, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_device_info, data->com_data)); + g_test_suite_add (suite, TESTCASE (test_com_status, data->com_data)); } result = g_test_run (); |