From 7fbee6ce27176bfc7ae9b34a4de9452cf5f6fa43 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Wed, 5 Feb 2014 08:38:23 +0100 Subject: Imported Upstream version 0.4+git.20110124t203624.00b6cce --- libqcdm/src/Makefile.am | 3 - libqcdm/src/commands.c | 285 ++++++++++++++++++++++++++++++++++++++++ libqcdm/src/commands.h | 111 +++++++++++++++- libqcdm/src/dm-commands.h | 68 ++++++++++ libqcdm/src/error.c | 1 + libqcdm/src/error.h | 1 + libqcdm/src/libqcdm.ver | 6 - libqcdm/src/nv-items.h | 29 +++- libqcdm/tests/test-qcdm-com.c | 281 +++++++++++++++++++++++++++++++++++++-- libqcdm/tests/test-qcdm-com.h | 8 ++ libqcdm/tests/test-qcdm-utils.c | 20 +++ libqcdm/tests/test-qcdm-utils.h | 2 + libqcdm/tests/test-qcdm.c | 9 ++ 13 files changed, 800 insertions(+), 24 deletions(-) delete mode 100644 libqcdm/src/libqcdm.ver (limited to 'libqcdm') diff --git a/libqcdm/src/Makefile.am b/libqcdm/src/Makefile.am index 5cc0568..f9451c6 100644 --- a/libqcdm/src/Makefile.am +++ b/libqcdm/src/Makefile.am @@ -22,9 +22,6 @@ libqcdm_la_SOURCES = \ libqcdm_la_LIBADD = \ $(MM_LIBS) -libqcdm_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libqcdm.ver \ - -version-info "0:0:0" - ########################################### # Test library without symbol versioning diff --git a/libqcdm/src/commands.c b/libqcdm/src/commands.c index 11a1a38..ab61ee5 100644 --- a/libqcdm/src/commands.c +++ b/libqcdm/src/commands.c @@ -119,6 +119,8 @@ bin2hexstr (const guint8 *bytes, int len) return result; } +/**********************************************************************/ + static gboolean check_command (const char *buf, gsize len, guint8 cmd, gsize min_len, GError **error) { @@ -154,6 +156,11 @@ check_command (const char *buf, gsize len, guint8 cmd, gsize min_len, GError **e "DM command %d not allowed in the current device mode", cmd); return FALSE; + case DIAG_CMD_BAD_SPC_MODE: + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_SPC_LOCKED, + "DM command %d not allowed because the Service Programming Code is locked", + cmd); + return FALSE; default: break; } @@ -430,6 +437,52 @@ qcdm_cmd_sw_version_result (const char *buf, gsize len, GError **error) /**********************************************************************/ +gsize +qcdm_cmd_status_snapshot_new (char *buf, gsize len, GError **error) +{ + char cmdbuf[3]; + DMCmdHeader *cmd = (DMCmdHeader *) &cmdbuf[0]; + + g_return_val_if_fail (buf != NULL, 0); + g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_STATUS_SNAPSHOT; + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +static guint8 +snapshot_state_to_qcdm (guint8 cdma_state) +{ + /* CDMA_STATUS_SNAPSHOT_STATE_* -> QCDM_STATUS_SNAPSHOT_STATE_* */ + return cdma_state + 1; +} + +QCDMResult * +qcdm_cmd_status_snapshot_result (const char *buf, gsize len, GError **error) +{ + QCDMResult *result = NULL; + DMCmdStatusSnapshotRsp *rsp = (DMCmdStatusSnapshotRsp *) buf; + + g_return_val_if_fail (buf != NULL, NULL); + + if (!check_command (buf, len, DIAG_CMD_STATUS_SNAPSHOT, sizeof (*rsp), error)) + return NULL; + + result = qcdm_result_new (); + + qcdm_result_add_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_BAND_CLASS, cdma_band_class_to_qcdm (rsp->band_class)); + qcdm_result_add_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_BASE_STATION_PREV, cdma_prev_to_qcdm (rsp->prev)); + qcdm_result_add_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_MOBILE_PREV, cdma_prev_to_qcdm (rsp->mob_prev)); + qcdm_result_add_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_PREV_IN_USE, cdma_prev_to_qcdm (rsp->prev_in_use)); + qcdm_result_add_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_STATE, snapshot_state_to_qcdm (rsp->state & 0xF)); + + return result; +} + +/**********************************************************************/ + gsize qcdm_cmd_pilot_sets_new (char *buf, gsize len, GError **error) { @@ -820,6 +873,107 @@ qcdm_cmd_nv_set_mode_pref_result (const char *buf, gsize len, GError **error) /**********************************************************************/ +static gboolean +hdr_rev_pref_validate (guint8 dm) +{ + if ( dm == DIAG_NV_HDR_REV_PREF_0 + || dm == DIAG_NV_HDR_REV_PREF_A + || dm == DIAG_NV_HDR_REV_PREF_EHRPD) + return TRUE; + return FALSE; +} + +gsize +qcdm_cmd_nv_get_hdr_rev_pref_new (char *buf, gsize len, GError **error) +{ + char cmdbuf[sizeof (DMCmdNVReadWrite) + 2]; + DMCmdNVReadWrite *cmd = (DMCmdNVReadWrite *) &cmdbuf[0]; + + g_return_val_if_fail (buf != NULL, 0); + g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_NV_READ; + cmd->nv_item = GUINT16_TO_LE (DIAG_NV_HDR_REV_PREF); + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +QCDMResult * +qcdm_cmd_nv_get_hdr_rev_pref_result (const char *buf, gsize len, GError **error) +{ + QCDMResult *result = NULL; + DMCmdNVReadWrite *rsp = (DMCmdNVReadWrite *) buf; + DMNVItemHdrRevPref *rev; + + g_return_val_if_fail (buf != NULL, NULL); + + if (!check_command (buf, len, DIAG_CMD_NV_READ, sizeof (DMCmdNVReadWrite), error)) + return NULL; + + if (!check_nv_cmd (rsp, DIAG_NV_HDR_REV_PREF, error)) + return NULL; + + rev = (DMNVItemHdrRevPref *) &rsp->data[0]; + + if (!hdr_rev_pref_validate (rev->rev_pref)) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_PARAMETER, + "Unknown HDR revision preference 0x%X", + rev->rev_pref); + return NULL; + } + + result = qcdm_result_new (); + qcdm_result_add_uint8 (result, QCDM_CMD_NV_GET_HDR_REV_PREF_ITEM_REV_PREF, rev->rev_pref); + + return result; +} + +gsize +qcdm_cmd_nv_set_hdr_rev_pref_new (char *buf, + gsize len, + guint8 rev_pref, + GError **error) +{ + char cmdbuf[sizeof (DMCmdNVReadWrite) + 2]; + DMCmdNVReadWrite *cmd = (DMCmdNVReadWrite *) &cmdbuf[0]; + DMNVItemHdrRevPref *req; + + g_return_val_if_fail (buf != NULL, 0); + g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + if (!hdr_rev_pref_validate (rev_pref)) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_PARAMETER, + "Invalid HDR revision preference %d", rev_pref); + return 0; + } + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_NV_WRITE; + cmd->nv_item = GUINT16_TO_LE (DIAG_NV_HDR_REV_PREF); + + req = (DMNVItemHdrRevPref *) &cmd->data[0]; + req->rev_pref = rev_pref; + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +QCDMResult * +qcdm_cmd_nv_set_hdr_rev_pref_result (const char *buf, gsize len, GError **error) +{ + g_return_val_if_fail (buf != NULL, NULL); + + if (!check_command (buf, len, DIAG_CMD_NV_WRITE, sizeof (DMCmdNVReadWrite), error)) + return NULL; + + if (!check_nv_cmd ((DMCmdNVReadWrite *) buf, DIAG_NV_HDR_REV_PREF, error)) + return NULL; + + return qcdm_result_new (); +} + +/**********************************************************************/ + gsize qcdm_cmd_cm_subsys_state_info_new (char *buf, gsize len, GError **error) { @@ -939,6 +1093,137 @@ qcdm_cmd_hdr_subsys_state_info_result (const char *buf, gsize len, GError **erro /**********************************************************************/ +gsize +qcdm_cmd_ext_logmask_new (char *buf, + gsize len, + GSList *items, + guint16 maxlog, + GError **error) +{ + char cmdbuf[sizeof (DMCmdExtLogMask) + 2]; + DMCmdExtLogMask *cmd = (DMCmdExtLogMask *) &cmdbuf[0]; + GSList *iter; + guint16 highest = 0; + gsize total = 3; + + g_return_val_if_fail (buf != NULL, 0); + g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_EXT_LOGMASK; + + for (iter = items; iter; iter = g_slist_next (iter)) { + guint32 item = GPOINTER_TO_UINT (iter->data); + + g_warn_if_fail (item > 0); + g_warn_if_fail (item < 4095); + cmd->mask[item / 8] |= 1 << item % 8; + + if (item > highest) + highest = item; + } + + g_return_val_if_fail (highest <= maxlog, 0); + cmd->len = GUINT16_TO_LE (maxlog); + total += maxlog / 8; + if (maxlog && maxlog % 8) + total++; + + return dm_encapsulate_buffer (cmdbuf, total, sizeof (cmdbuf), buf, len); +} + +QCDMResult * +qcdm_cmd_ext_logmask_result (const char *buf, + gsize len, + GError **error) +{ + QCDMResult *result = NULL; + DMCmdExtLogMask *rsp = (DMCmdExtLogMask *) buf; + guint32 masklen = 0, maxlog = 0; + gsize minlen = 0; + + g_return_val_if_fail (buf != NULL, NULL); + + /* Ensure size is at least enough for the command header */ + if (len < 1) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_LENGTH, + "DM command %d response not long enough (got %zu, expected " + "at least %d).", DIAG_CMD_EXT_LOGMASK, len, 3); + return FALSE; + } + + /* Result of a 'set' operation will be only 1 byte in size; result of + * a 'get' operation (ie setting len to 0x0000 in the request) will be + * the size of the header (3) plus the max log length. + */ + + if (len == 1) + minlen = 1; + else { + /* Ensure size is equal to max # of log items + 3 */ + maxlog = GUINT16_FROM_LE (rsp->len); + masklen = maxlog / 8; + if (maxlog % 8) + masklen++; + + if (len < (masklen + 3)) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_LENGTH, + "DM command %d response not long enough (got %zu, expected " + "at least %d).", DIAG_CMD_EXT_LOGMASK, len, masklen + 3); + return FALSE; + } + minlen = masklen + 3; + } + + if (!check_command (buf, len, DIAG_CMD_EXT_LOGMASK, minlen, error)) + return NULL; + + result = qcdm_result_new (); + + if (minlen != 4) + qcdm_result_add_uint32 (result, QCDM_CMD_EXT_LOGMASK_ITEM_MAX_ITEMS, maxlog); + + return result; +} + +gboolean +qcmd_cmd_ext_logmask_result_get_item (QCDMResult *result, + guint16 item) +{ + return FALSE; +} + +/**********************************************************************/ + +gsize +qcdm_cmd_event_report_new (char *buf, gsize len, gboolean start, GError **error) +{ + char cmdbuf[4]; + DMCmdEventReport *cmd = (DMCmdEventReport *) &cmdbuf[0]; + + g_return_val_if_fail (buf != NULL, 0); + g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_EVENT_REPORT; + cmd->on = start ? 1 : 0; + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +QCDMResult * +qcdm_cmd_event_report_result (const char *buf, gsize len, GError **error) +{ + g_return_val_if_fail (buf != NULL, NULL); + + if (!check_command (buf, len, DIAG_CMD_EVENT_REPORT, sizeof (DMCmdEventReport), error)) + return NULL; + + return qcdm_result_new (); +} + +/**********************************************************************/ + gsize qcdm_cmd_zte_subsys_status_new (char *buf, gsize len, GError **error) { diff --git a/libqcdm/src/commands.h b/libqcdm/src/commands.h index 75e83a7..fe582a6 100644 --- a/libqcdm/src/commands.h +++ b/libqcdm/src/commands.h @@ -148,6 +148,54 @@ QCDMResult *qcdm_cmd_sw_version_result (const char *buf, /**********************************************************************/ +/* One of QCDM_CDMA_BAND_CLASS_* */ +#define QCDM_CMD_STATUS_SNAPSHOT_ITEM_BAND_CLASS "band-class" + +/* The protocol revision of the base station. One of QCDM_CDMA_PREV_* */ +#define QCDM_CMD_STATUS_SNAPSHOT_ITEM_BASE_STATION_PREV "prev" + +/* The protocol revision of the mobile terminal. One of QCDM_CDMA_PREV_* */ +#define QCDM_CMD_STATUS_SNAPSHOT_ITEM_MOBILE_PREV "mob-prev" + +/* The protocol revision currently in-use. One of QCDM_CDMA_PREV_* */ +#define QCDM_CMD_STATUS_SNAPSHOT_ITEM_PREV_IN_USE "prev-in-use" + +enum { + QCDM_CMD_STATUS_SNAPSHOT_STATE_UNKNOWN = 0x00, + QCDM_CMD_STATUS_SNAPSHOT_STATE_NO_SERVICE = 0x01, + QCDM_CMD_STATUS_SNAPSHOT_STATE_INITIALIZATION = 0x02, + QCDM_CMD_STATUS_SNAPSHOT_STATE_IDLE = 0x03, + QCDM_CMD_STATUS_SNAPSHOT_STATE_VOICE_CHANNEL_INIT = 0x04, + QCDM_CMD_STATUS_SNAPSHOT_STATE_WAITING_FOR_ORDER = 0x05, + QCDM_CMD_STATUS_SNAPSHOT_STATE_WAITING_FOR_ANSWER = 0x06, + QCDM_CMD_STATUS_SNAPSHOT_STATE_CONVERSATION = 0x07, + QCDM_CMD_STATUS_SNAPSHOT_STATE_RELEASE = 0x08, + QCDM_CMD_STATUS_SNAPSHOT_STATE_SYSTEM_ACCESS = 0x09, + QCDM_CMD_STATUS_SNAPSHOT_STATE_OFFLINE_CDMA = 0x11, + QCDM_CMD_STATUS_SNAPSHOT_STATE_OFFLINE_HDR = 0x12, + QCDM_CMD_STATUS_SNAPSHOT_STATE_OFFLINE_ANALOG = 0x13, + QCDM_CMD_STATUS_SNAPSHOT_STATE_RESET = 0x14, + QCDM_CMD_STATUS_SNAPSHOT_STATE_POWER_DOWN = 0x15, + QCDM_CMD_STATUS_SNAPSHOT_STATE_POWER_SAVE = 0x16, + QCDM_CMD_STATUS_SNAPSHOT_STATE_POWER_UP = 0x17, + QCDM_CMD_STATUS_SNAPSHOT_STATE_LOW_POWER_MODE = 0x18, + QCDM_CMD_STATUS_SNAPSHOT_STATE_SEARCHER_DSMM = 0x19, /* Dedicated System Measurement Mode */ + QCDM_CMD_STATUS_SNAPSHOT_STATE_HDR = 0x41, +}; + +/* The protocol revision currently in-use. One of QCDM_STATUS_SNAPSHOT_STATE_* */ +#define QCDM_CMD_STATUS_SNAPSHOT_ITEM_STATE "state" + +gsize qcdm_cmd_status_snapshot_new (char *buf, + gsize len, + GError **error); + +QCDMResult *qcdm_cmd_status_snapshot_result (const char *buf, + gsize len, + GError **error); + +/**********************************************************************/ + enum { QCDM_CMD_PILOT_SETS_TYPE_UNKNOWN = 0, QCDM_CMD_PILOT_SETS_TYPE_ACTIVE = 1, @@ -252,6 +300,34 @@ QCDMResult *qcdm_cmd_nv_set_mode_pref_result (const char *buf, /**********************************************************************/ +/* Values for QCDM_CMD_NV_GET_HDR_REV_PREF_ITEM_REV_PREF */ +enum { + QCDM_CMD_NV_HDR_REV_PREF_ITEM_REV_PREF_0 = 0x00, + QCDM_CMD_NV_HDR_REV_PREF_ITEM_REV_PREF_A = 0x01, + QCDM_CMD_NV_HDR_REV_PREF_ITEM_REV_PREF_EHRPD = 0x04, +}; + +#define QCDM_CMD_NV_GET_HDR_REV_PREF_ITEM_REV_PREF "rev-pref" + +gsize qcdm_cmd_nv_get_hdr_rev_pref_new (char *buf, + gsize len, + GError **error); + +QCDMResult *qcdm_cmd_nv_get_hdr_rev_pref_result (const char *buf, + gsize len, + GError **error); + +gsize qcdm_cmd_nv_set_hdr_rev_pref_new (char *buf, + gsize len, + guint8 rev_pref, + GError **error); + +QCDMResult *qcdm_cmd_nv_set_hdr_rev_pref_result (const char *buf, + gsize len, + GError **error); + +/**********************************************************************/ + /* Values for QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE */ enum { QCDM_CMD_CM_SUBSYS_STATE_INFO_OPERATING_MODE_ONLINE = 5 @@ -265,7 +341,10 @@ enum { QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_GSM = 3, QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_HDR = 4, QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WCDMA = 5, - QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_GPS = 6 + QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_GPS = 6, + QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_GW = 7, /* GSM & WCDMA */ + QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WLAN = 8, + QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_LTE = 9, }; /* Values for QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF */ @@ -392,6 +471,36 @@ QCDMResult *qcdm_cmd_hdr_subsys_state_info_result (const char *buf, /**********************************************************************/ +/* Max # of log items this device supports */ +#define QCDM_CMD_EXT_LOGMASK_ITEM_MAX_ITEMS "max-items" + +gsize qcdm_cmd_ext_logmask_new (char *buf, + gsize len, + GSList *items, + guint16 maxlog, + GError **error); + +QCDMResult *qcdm_cmd_ext_logmask_result (const char *buf, + gsize len, + GError **error); + +/* Returns TRUE if 'item' is set in the log mask */ +gboolean qcmd_cmd_ext_logmask_result_get_item (QCDMResult *result, + guint16 item); + +/**********************************************************************/ + +gsize qcdm_cmd_event_report_new (char *buf, + gsize len, + gboolean start, + GError **error); + +QCDMResult *qcdm_cmd_event_report_result (const char *buf, + gsize len, + GError **error); + +/**********************************************************************/ + #define QCDM_CMD_ZTE_SUBSYS_STATUS_ITEM_SIGNAL_INDICATOR "signal-indicator" gsize qcdm_cmd_zte_subsys_status_new (char *buf, diff --git a/libqcdm/src/dm-commands.h b/libqcdm/src/dm-commands.h index cfc98f7..6ce3c5d 100644 --- a/libqcdm/src/dm-commands.h +++ b/libqcdm/src/dm-commands.h @@ -180,6 +180,28 @@ enum { CDMA_BAND_CLASS_12_PAMR_800 = 12 }; +enum { + CDMA_STATUS_SNAPSHOT_STATE_NO_SERVICE = 0x00, + CDMA_STATUS_SNAPSHOT_STATE_INITIALIZATION = 0x01, + CDMA_STATUS_SNAPSHOT_STATE_IDLE = 0x02, + CDMA_STATUS_SNAPSHOT_STATE_VOICE_CHANNEL_INIT = 0x03, + CDMA_STATUS_SNAPSHOT_STATE_WAITING_FOR_ORDER = 0x04, + CDMA_STATUS_SNAPSHOT_STATE_WAITING_FOR_ANSWER = 0x05, + CDMA_STATUS_SNAPSHOT_STATE_CONVERSATION = 0x06, + CDMA_STATUS_SNAPSHOT_STATE_RELEASE = 0x07, + CDMA_STATUS_SNAPSHOT_STATE_SYSTEM_ACCESS = 0x08, + CDMA_STATUS_SNAPSHOT_STATE_OFFLINE_CDMA = 0x10, + CDMA_STATUS_SNAPSHOT_STATE_OFFLINE_HDR = 0x11, + CDMA_STATUS_SNAPSHOT_STATE_OFFLINE_ANALOG = 0x12, + CDMA_STATUS_SNAPSHOT_STATE_RESET = 0x13, + CDMA_STATUS_SNAPSHOT_STATE_POWER_DOWN = 0x14, + CDMA_STATUS_SNAPSHOT_STATE_POWER_SAVE = 0x15, + CDMA_STATUS_SNAPSHOT_STATE_POWER_UP = 0x16, + CDMA_STATUS_SNAPSHOT_STATE_LOW_POWER_MODE = 0x17, + CDMA_STATUS_SNAPSHOT_STATE_SEARCHER_DSMM = 0x18, /* Dedicated System Measurement Mode */ + CDMA_STATUS_SNAPSHOT_STATE_HDR = 0x40, +}; + /* Generic DM command header */ struct DMCmdHeader { guint8 code; @@ -265,6 +287,29 @@ struct DMCmdSwVersionRsp { } __attribute__ ((packed)); typedef struct DMCmdSwVersionRsp DMCmdSwVersionRsp; +/* DIAG_CMD_STATUS_SNAPSHOT */ +struct DMCmdStatusSnapshotRsp { + guint8 code; + guint8 esn[4]; + guint8 imsi_s1[4]; + guint8 imsi_s2[2]; + guint8 imsi_s[8]; + guint8 imsi_11_12; + guint16 mcc; + guint8 imsi_addr_num; + guint16 sid; + guint16 nid; + guint8 prev; + guint8 prev_in_use; + guint8 mob_prev; + guint8 band_class; + guint16 frequency; + guint8 oper_mode; + guint8 state; + guint8 sub_state; +} __attribute__ ((packed)); +typedef struct DMCmdStatusSnapshotRsp DMCmdStatusSnapshotRsp; + /* DIAG_SUBSYS_CM_STATE_INFO subsys command */ struct DMCmdSubsysCMStateInfoRsp { DMCmdSubsysHeader header; @@ -323,6 +368,29 @@ struct DMCmdPilotSetsRsp { } __attribute__ ((packed)); typedef struct DMCmdPilotSetsRsp DMCmdPilotSetsRsp; +struct DMCmdExtLogMask { + guint8 code; + /* Bit number of highest '1' in 'mask'; set to 0 to get current mask. */ + guint16 len; + /* Bitfield of log messages to receive */ + guint8 mask[512]; +} __attribute__ ((packed)); +typedef struct DMCmdExtLogMask DMCmdExtLogMask; + +struct DMCmdEventReport { + guint8 code; + guint8 on; +} __attribute__ ((packed)); +typedef struct DMCmdEventReport DMCmdEventReport; + +struct DMCmdEventReportRsp { + guint8 code; + guint16 len; + guint16 event_id; + guint8 data[0]; +} __attribute__ ((packed)); +typedef struct DMCmdEventReportRsp DMCmdEventReportRsp; + /* DIAG_SUBSYS_NW_CONTROL_* subsys command */ struct DMCmdSubsysNwSnapshotReq { DMCmdSubsysHeader hdr; diff --git a/libqcdm/src/error.c b/libqcdm/src/error.c index e3b97a0..994608e 100644 --- a/libqcdm/src/error.c +++ b/libqcdm/src/error.c @@ -75,6 +75,7 @@ qcdm_command_error_get_type (void) ENUM_ENTRY (QCDM_COMMAND_NOT_ACCEPTED, "QcdmCommandNotAccepted"), ENUM_ENTRY (QCDM_COMMAND_BAD_MODE, "QcdmCommandBadMode"), ENUM_ENTRY (QCDM_COMMAND_NVCMD_FAILED, "QcdmCommandNvCmdFailed"), + ENUM_ENTRY (QCDM_COMMAND_SPC_LOCKED, "QcdmCommandSpcLocked"), { 0, 0, 0 } }; diff --git a/libqcdm/src/error.h b/libqcdm/src/error.h index 7a02ae2..f0b0534 100644 --- a/libqcdm/src/error.h +++ b/libqcdm/src/error.h @@ -41,6 +41,7 @@ enum { QCDM_COMMAND_NOT_ACCEPTED = 5, QCDM_COMMAND_BAD_MODE = 6, QCDM_COMMAND_NVCMD_FAILED = 7, + QCDM_COMMAND_SPC_LOCKED = 8, }; #define QCDM_COMMAND_ERROR (qcdm_command_error_quark ()) diff --git a/libqcdm/src/libqcdm.ver b/libqcdm/src/libqcdm.ver deleted file mode 100644 index b1567e2..0000000 --- a/libqcdm/src/libqcdm.ver +++ /dev/null @@ -1,6 +0,0 @@ -{ -global: - nm_vpn_connection_new; -local: - *; -}; diff --git a/libqcdm/src/nv-items.h b/libqcdm/src/nv-items.h index a0ca10a..8240866 100644 --- a/libqcdm/src/nv-items.h +++ b/libqcdm/src/nv-items.h @@ -19,17 +19,21 @@ #define LIBQCDM_NV_ITEMS_H enum { - DIAG_NV_MODE_PREF = 10, /* Mode preference: 1x, HDR, auto */ - DIAG_NV_DIR_NUMBER = 178, /* Mobile Directory Number (MDN) */ - DIAG_NV_ROAM_PREF = 442, /* Roaming preference */ + DIAG_NV_MODE_PREF = 10, /* Mode preference: 1x, HDR, auto */ + DIAG_NV_DIR_NUMBER = 178, /* Mobile Directory Number (MDN) */ + DIAG_NV_ROAM_PREF = 442, /* Roaming preference */ + DIAG_NV_HDR_REV_PREF = 4964, /* HDR mode preference(?): rev0, revA, eHRPD */ }; /* Mode preference values */ enum { - DIAG_NV_MODE_PREF_AUTO = 0x04, - DIAG_NV_MODE_PREF_1X_ONLY = 0x09, - DIAG_NV_MODE_PREF_HDR_ONLY = 0x0A, + DIAG_NV_MODE_PREF_AUTO = 0x04, + DIAG_NV_MODE_PREF_1X_ONLY = 0x09, + DIAG_NV_MODE_PREF_HDR_ONLY = 0x0A, + DIAG_NV_MODE_PREF_1X_HDR_ONLY = 0x0D, + DIAG_NV_MODE_PREF_LTE_ONLY = 0x1E, + DIAG_NV_MODE_PREF_1X_HDR_LTE_ONLY = 0x24, }; /* DIAG_NV_MODE_PREF */ @@ -60,5 +64,18 @@ struct DMNVItemRoamPref { } __attribute__ ((packed)); typedef struct DMNVItemRoamPref DMNVItemRoamPref; +/* HDR Revision preference values (?) */ +enum { + DIAG_NV_HDR_REV_PREF_0 = 0x00, + DIAG_NV_HDR_REV_PREF_A = 0x01, + DIAG_NV_HDR_REV_PREF_EHRPD = 0x04, +}; + +/* DIAG_NV_HDR_REV_PREF */ +struct DMNVItemHdrRevPref { + guint8 rev_pref; +} __attribute__ ((packed)); +typedef struct DMNVItemHdrRevPref DMNVItemHdrRevPref; + #endif /* LIBQCDM_NV_ITEMS_H */ diff --git a/libqcdm/tests/test-qcdm-com.c b/libqcdm/tests/test-qcdm-com.c index f41d249..b95c7d9 100644 --- a/libqcdm/tests/test-qcdm-com.c +++ b/libqcdm/tests/test-qcdm-com.c @@ -38,19 +38,19 @@ prev_to_string (guint8 prev) { switch (prev) { case QCDM_CDMA_PREV_IS_95: - return "IS-95"; + return "1 (IS-95)"; case QCDM_CDMA_PREV_IS_95A: - return "IS-95A"; + return "2 (IS-95A)"; case QCDM_CDMA_PREV_IS_95A_TSB74: - return "IS-95A TSB-74"; + return "3 (IS-95A TSB-74)"; case QCDM_CDMA_PREV_IS_95B_PHASE1: - return "IS-95B Phase I"; + return "4 (IS-95B Phase I)"; case QCDM_CDMA_PREV_IS_95B_PHASE2: - return "IS-95B Phase II"; + return "5 (IS-95B Phase II)"; case QCDM_CDMA_PREV_IS2000_REL0: - return "IS-2000 Release 0"; + return "6 (IS-2000 Release 0)"; case QCDM_CDMA_PREV_IS2000_RELA: - return "IS-2000 Release A"; + return "7 (IS-2000 Release A)"; default: break; } @@ -107,6 +107,54 @@ hdr_rev_to_string (guint8 hdr_rev) return "unknown"; } +static const char * +status_snapshot_state_to_string (guint8 state) +{ + switch (state) { + case QCDM_CMD_STATUS_SNAPSHOT_STATE_NO_SERVICE: + return "no service"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_INITIALIZATION: + return "initialization"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_IDLE: + return "idle"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_VOICE_CHANNEL_INIT: + return "voice channel init"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_WAITING_FOR_ORDER: + return "waiting for order"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_WAITING_FOR_ANSWER: + return "waiting for answer"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_CONVERSATION: + return "conversation"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_RELEASE: + return "release"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_SYSTEM_ACCESS: + return "system access"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_OFFLINE_CDMA: + return "offline CDMA"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_OFFLINE_HDR: + return "offline HDR"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_OFFLINE_ANALOG: + return "offline analog"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_RESET: + return "reset"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_POWER_DOWN: + return "power down"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_POWER_SAVE: + return "power save"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_POWER_UP: + return "power up"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_LOW_POWER_MODE: + return "low power mode"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_SEARCHER_DSMM: + return "searcher DSMM"; + case QCDM_CMD_STATUS_SNAPSHOT_STATE_HDR: + return "HDR"; + default: + break; + } + return "unknown"; +} + /************************************************************/ typedef struct { @@ -442,6 +490,9 @@ test_com_read_roam_pref (void *f, void *data) /* Parse the response into a result structure */ result = qcdm_cmd_nv_get_roam_pref_result (buf, reply_len, &error); + if (error && (error->code == QCDM_COMMAND_NVCMD_FAILED)) + return; + g_assert (result); g_print ("\n"); @@ -493,7 +544,9 @@ test_com_read_mode_pref (void *f, void *data) /* Parse the response into a result structure */ result = qcdm_cmd_nv_get_mode_pref_result (buf, reply_len, &error); if (!result) { - g_assert_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_NVCMD_FAILED); + g_assert (error); + g_assert (error->domain == QCDM_COMMAND_ERROR); + g_assert (error->code == QCDM_COMMAND_NVCMD_FAILED || error->code == QCDM_COMMAND_BAD_PARAMETER); return; } @@ -521,6 +574,62 @@ test_com_read_mode_pref (void *f, void *data) qcdm_result_unref (result); } +void +test_com_read_hdr_rev_pref (void *f, void *data) +{ + TestComData *d = data; + gboolean success; + GError *error = NULL; + char buf[512]; + guint8 pref; + const char *msg; + gint len; + QCDMResult *result; + gsize reply_len; + + len = qcdm_cmd_nv_get_hdr_rev_pref_new (buf, sizeof (buf), NULL); + g_assert (len > 0); + + /* Send the command */ + success = send_command (d, buf, len); + g_assert (success); + + /* Get a response */ + reply_len = wait_reply (d, buf, sizeof (buf)); + + /* Parse the response into a result structure */ + result = qcdm_cmd_nv_get_hdr_rev_pref_result (buf, reply_len, &error); + if (!result) { + g_assert (error); + g_assert (error->domain == QCDM_COMMAND_ERROR); + g_assert (error->code == QCDM_COMMAND_NVCMD_FAILED || error->code == QCDM_COMMAND_BAD_PARAMETER); + return; + } + + g_print ("\n"); + + success = qcdm_result_get_uint8 (result, QCDM_CMD_NV_GET_HDR_REV_PREF_ITEM_REV_PREF, &pref); + g_assert (success); + + switch (pref) { + case QCDM_CMD_NV_HDR_REV_PREF_ITEM_REV_PREF_0: + msg = "rev0"; + break; + case QCDM_CMD_NV_HDR_REV_PREF_ITEM_REV_PREF_A: + msg = "revA"; + break; + case QCDM_CMD_NV_HDR_REV_PREF_ITEM_REV_PREF_EHRPD: + msg = "eHRPD"; + break; + default: + msg = "unknown"; + break; + } + g_message ("%s: HDR rev preference: 0x%02X (%s)", __func__, pref, msg); + + qcdm_result_unref (result); +} + void test_com_status (void *f, void *data) { @@ -683,6 +792,57 @@ test_com_sw_version (void *f, void *data) */ } +void +test_com_status_snapshot (void *f, void *data) +{ + TestComData *d = data; + gboolean success; + GError *error = NULL; + char buf[100]; + gint len; + QCDMResult *result; + gsize reply_len; + guint8 n8; + + len = qcdm_cmd_status_snapshot_new (buf, sizeof (buf), NULL); + g_assert (len == 4); + + /* Send the command */ + success = send_command (d, buf, len); + g_assert (success); + + /* Get a response */ + reply_len = wait_reply (d, buf, sizeof (buf)); + + /* Parse the response into a result structure */ + result = qcdm_cmd_status_snapshot_result (buf, reply_len, &error); + g_assert (result); + + g_print ("\n"); + + n8 = 0; + qcdm_result_get_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_BAND_CLASS, &n8); + g_message ("%s: Band Class: %s", __func__, band_class_to_string (n8)); + + n8 = 0; + qcdm_result_get_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_BASE_STATION_PREV, &n8); + g_message ("%s: Base station P_REV: %s", __func__, prev_to_string (n8)); + + n8 = 0; + qcdm_result_get_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_MOBILE_PREV, &n8); + g_message ("%s: Mobile P_REV: %s", __func__, prev_to_string (n8)); + + n8 = 0; + qcdm_result_get_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_PREV_IN_USE, &n8); + g_message ("%s: P_REV in-use: %s", __func__, prev_to_string (n8)); + + n8 = 0; + qcdm_result_get_uint8 (result, QCDM_CMD_STATUS_SNAPSHOT_ITEM_STATE, &n8); + g_message ("%s: State: %d (%s)", __func__, n8, status_snapshot_state_to_string (n8)); + + qcdm_result_unref (result); +} + void test_com_pilot_sets (void *f, void *data) { @@ -802,6 +962,9 @@ test_com_cm_subsys_state_info (void *f, void *data) case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WCDMA: detail = "WCDMA"; break; + case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_LTE: + detail = "LTE"; + break; default: detail = "unknown"; break; @@ -1090,6 +1253,108 @@ test_com_hdr_subsys_state_info (void *f, void *data) qcdm_result_unref (result); } +void +test_com_ext_logmask (void *f, void *data) +{ + TestComData *d = data; + gboolean success; + GError *error = NULL; + char buf[520]; + gint len; + QCDMResult *result; + gsize reply_len; + GSList *items = NULL; + guint32 maxlog = 0; + + /* First get # of items the device supports */ + len = qcdm_cmd_ext_logmask_new (buf, sizeof (buf), NULL, 0, NULL); + + /* Send the command */ + success = send_command (d, buf, len); + g_assert (success); + + /* Get a response */ + reply_len = wait_reply (d, buf, sizeof (buf)); + + g_print ("\n"); + + /* Parse the response into a result structure */ + result = qcdm_cmd_ext_logmask_result (buf, reply_len, &error); + g_assert (result); + + qcdm_result_get_uint32 (result, QCDM_CMD_EXT_LOGMASK_ITEM_MAX_ITEMS, &maxlog); + g_message ("%s: Max # Log Items: %u (0x%X)", __func__, maxlog, maxlog); + + qcdm_result_unref (result); + + /* Now enable some log items */ + items = g_slist_append (items, GUINT_TO_POINTER (0x002C)); + items = g_slist_append (items, GUINT_TO_POINTER (0x002E)); + len = qcdm_cmd_ext_logmask_new (buf, sizeof (buf), items, (guint16) maxlog, NULL); + g_slist_free (items); + + /* Send the command */ + success = send_command (d, buf, len); + g_assert (success); + + /* Get a response */ + reply_len = wait_reply (d, buf, sizeof (buf)); + + g_print ("\n"); + + /* Parse the response into a result structure */ + result = qcdm_cmd_ext_logmask_result (buf, reply_len, &error); + g_assert (result); + + qcdm_result_unref (result); + + /* Wait for a log packet */ + reply_len = wait_reply (d, buf, sizeof (buf)); +} + +void +test_com_event_report (void *f, void *data) +{ + TestComData *d = data; + gboolean success; + GError *error = NULL; + char buf[520]; + gint len; + QCDMResult *result; + gsize reply_len; + + /* Turn event reporting on */ + len = qcdm_cmd_event_report_new (buf, sizeof (buf), TRUE, NULL); + + /* Send the command */ + success = send_command (d, buf, len); + g_assert (success); + + /* Get a response */ + reply_len = wait_reply (d, buf, sizeof (buf)); + + g_print ("\n"); + + /* Parse the response into a result structure */ + result = qcdm_cmd_event_report_result (buf, reply_len, &error); + g_assert (result); + + qcdm_result_unref (result); + + /* Wait for an event */ + reply_len = wait_reply (d, buf, sizeof (buf)); + + /* Turn event reporting off */ + len = qcdm_cmd_event_report_new (buf, sizeof (buf), FALSE, NULL); + + /* Send the command */ + success = send_command (d, buf, len); + g_assert (success); + + /* Get a response */ + reply_len = wait_reply (d, buf, sizeof (buf)); +} + void test_com_zte_subsys_status (void *f, void *data) { diff --git a/libqcdm/tests/test-qcdm-com.h b/libqcdm/tests/test-qcdm-com.h index 3cf7c4f..76075e5 100644 --- a/libqcdm/tests/test-qcdm-com.h +++ b/libqcdm/tests/test-qcdm-com.h @@ -33,16 +33,24 @@ void test_com_read_roam_pref (void *f, void *data); void test_com_read_mode_pref (void *f, void *data); +void test_com_read_hdr_rev_pref (void *f, void *data); + void test_com_status (void *f, void *data); void test_com_sw_version (void *f, void *data); +void test_com_status_snapshot (void *f, void *data); + void test_com_pilot_sets (void *f, void *data); void test_com_cm_subsys_state_info (void *f, void *data); void test_com_hdr_subsys_state_info (void *f, void *data); +void test_com_ext_logmask (void *f, void *data); + +void test_com_event_report (void *f, void *data); + void test_com_zte_subsys_status (void *f, void *data); void test_com_nw_subsys_modem_snapshot_cdma (void *f, void *data); diff --git a/libqcdm/tests/test-qcdm-utils.c b/libqcdm/tests/test-qcdm-utils.c index 27ec8d6..04807c1 100644 --- a/libqcdm/tests/test-qcdm-utils.c +++ b/libqcdm/tests/test-qcdm-utils.c @@ -84,3 +84,23 @@ test_utils_encapsulate_buffer (void *f, void *data) g_assert (memcmp (outbuf, encap_outbuf, encap_len) == 0); } +static const char cns_inbuf[] = { + 0x00, 0x0a, 0x6b, 0x74, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e +}; + +void +test_utils_decapsulate_sierra_cns (void *f, void *data) +{ + gboolean success; + char outbuf[512]; + gsize decap_len = 0; + gsize used = 0; + gboolean more = FALSE; + + success = dm_decapsulate_buffer (cns_inbuf, sizeof (cns_inbuf), + outbuf, sizeof (outbuf), + &decap_len, &used, &more); + g_assert (success == FALSE); +} + diff --git a/libqcdm/tests/test-qcdm-utils.h b/libqcdm/tests/test-qcdm-utils.h index 8038666..65a9944 100644 --- a/libqcdm/tests/test-qcdm-utils.h +++ b/libqcdm/tests/test-qcdm-utils.h @@ -22,5 +22,7 @@ void test_utils_decapsulate_buffer (void *f, void *data); void test_utils_encapsulate_buffer (void *f, void *data); +void test_utils_decapsulate_sierra_cns (void *f, void *data); + #endif /* TEST_QCDM_UTILS_H */ diff --git a/libqcdm/tests/test-qcdm.c b/libqcdm/tests/test-qcdm.c index a58780e..946fb67 100644 --- a/libqcdm/tests/test-qcdm.c +++ b/libqcdm/tests/test-qcdm.c @@ -28,7 +28,11 @@ typedef struct { gpointer com_data; } TestData; +#if GLIB_CHECK_VERSION(2,25,12) +typedef GTestFixtureFunc TCFunc; +#else typedef void (*TCFunc)(void); +#endif #define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) @@ -85,6 +89,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_escape_unescape, NULL)); g_test_suite_add (suite, TESTCASE (test_utils_decapsulate_buffer, NULL)); g_test_suite_add (suite, TESTCASE (test_utils_encapsulate_buffer, NULL)); + g_test_suite_add (suite, TESTCASE (test_utils_decapsulate_sierra_cns, NULL)); g_test_suite_add (suite, TESTCASE (test_result_string, NULL)); g_test_suite_add (suite, TESTCASE (test_result_uint32, NULL)); g_test_suite_add (suite, TESTCASE (test_result_uint8, NULL)); @@ -97,11 +102,15 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_com_mdn, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_read_roam_pref, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_read_mode_pref, data->com_data)); + g_test_suite_add (suite, TESTCASE (test_com_read_hdr_rev_pref, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_status, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_sw_version, data->com_data)); + g_test_suite_add (suite, TESTCASE (test_com_status_snapshot, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_pilot_sets, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_cm_subsys_state_info, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_hdr_subsys_state_info, data->com_data)); + g_test_suite_add (suite, TESTCASE (test_com_ext_logmask, data->com_data)); + g_test_suite_add (suite, TESTCASE (test_com_event_report, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_zte_subsys_status, data->com_data)); g_test_suite_add (suite, TESTCASE (test_com_nw_subsys_modem_snapshot_cdma, data->com_data)); } -- cgit v1.2.3