diff options
Diffstat (limited to 'libqcdm/src')
-rw-r--r-- | libqcdm/src/commands.c | 149 | ||||
-rw-r--r-- | libqcdm/src/commands.h | 69 | ||||
-rw-r--r-- | libqcdm/src/dm-commands.h | 44 |
3 files changed, 262 insertions, 0 deletions
diff --git a/libqcdm/src/commands.c b/libqcdm/src/commands.c index 14d2b280..1d67603b 100644 --- a/libqcdm/src/commands.c +++ b/libqcdm/src/commands.c @@ -1616,3 +1616,152 @@ qcmd_cmd_log_config_mask_result_code_set (QcdmResult *result, /**********************************************************************/ +static char bcd_chars[] = "0123456789\0\0\0\0\0\0"; + +static qcdmbool +imxi_to_bcd_string (u_int8_t bytes[9], char *buf, size_t buflen) +{ + char *p; + u_int32_t i; + + if (bytes[0] == 0) + return TRUE; + + qcdm_return_val_if_fail (bytes[0] == 0x08, FALSE); + qcdm_return_val_if_fail (buf != NULL, FALSE); + qcdm_return_val_if_fail (buflen > bytes[0], FALSE); + + p = buf; + for (i = 0 ; i < bytes[0]; i++) { + /* IMxI are 15 chars long, so the lower 4-bits of the first + * byte of the IMxI is skipped. Not sure what it does. + */ + if (i > 0) { + *p = bcd_chars[bytes[i + 1] & 0xf]; + if (!*p) + return FALSE; + p++; + } + *p = bcd_chars[(bytes[i + 1] >> 4) & 0xf]; + if (!*p) + return FALSE; + p++; + } + *p++ = '\0'; + return TRUE; +} + +size_t +qcdm_cmd_wcdma_subsys_state_info_new (char *buf, size_t len) +{ + char cmdbuf[sizeof (DMCmdSubsysHeader) + 2]; + DMCmdSubsysHeader *cmd = (DMCmdSubsysHeader *) &cmdbuf[0]; + + qcdm_return_val_if_fail (buf != NULL, 0); + qcdm_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_SUBSYS; + cmd->subsys_id = DIAG_SUBSYS_WCDMA; + cmd->subsys_cmd = htole16 (DIAG_SUBSYS_WCDMA_STATE_INFO); + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +QcdmResult * +qcdm_cmd_wcdma_subsys_state_info_result (const char *buf, size_t len, int *out_error) +{ + QcdmResult *result = NULL; + DMCmdSubsysWcdmaStateInfoRsp *rsp = (DMCmdSubsysWcdmaStateInfoRsp *) buf; + char imxi[10]; + + qcdm_return_val_if_fail (buf != NULL, NULL); + + if (!check_command (buf, len, DIAG_CMD_SUBSYS, sizeof (DMCmdSubsysWcdmaStateInfoRsp), out_error)) + return NULL; + + result = qcdm_result_new (); + + qcdm_result_add_u8 (result, QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_L1_STATE, rsp->l1_state); + + memset (imxi, 0, sizeof (imxi)); + if (imxi_to_bcd_string (rsp->imei, imxi, sizeof (imxi))) + qcdm_result_add_string (result, QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_IMEI, imxi); + + memset (imxi, 0, sizeof (imxi)); + if (imxi_to_bcd_string (rsp->imsi, imxi, sizeof (imxi))) + qcdm_result_add_string (result, QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_IMSI, imxi); + + return result; +} + +/**********************************************************************/ + +size_t +qcdm_cmd_gsm_subsys_state_info_new (char *buf, size_t len) +{ + char cmdbuf[sizeof (DMCmdSubsysHeader) + 2]; + DMCmdSubsysHeader *cmd = (DMCmdSubsysHeader *) &cmdbuf[0]; + + qcdm_return_val_if_fail (buf != NULL, 0); + qcdm_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_SUBSYS; + cmd->subsys_id = DIAG_SUBSYS_GSM; + cmd->subsys_cmd = htole16 (DIAG_SUBSYS_GSM_STATE_INFO); + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +QcdmResult * +qcdm_cmd_gsm_subsys_state_info_result (const char *buf, size_t len, int *out_error) +{ + QcdmResult *result = NULL; + DMCmdSubsysGsmStateInfoRsp *rsp = (DMCmdSubsysGsmStateInfoRsp *) buf; + char imxi[10]; + u_int32_t mcc = 0, mnc = 0; + u_int8_t mnc3; + + qcdm_return_val_if_fail (buf != NULL, NULL); + + if (!check_command (buf, len, DIAG_CMD_SUBSYS, sizeof (DMCmdSubsysGsmStateInfoRsp), out_error)) + return NULL; + + result = qcdm_result_new (); + + memset (imxi, 0, sizeof (imxi)); + if (imxi_to_bcd_string (rsp->imei, imxi, sizeof (imxi))) + qcdm_result_add_string (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_IMEI, imxi); + + memset (imxi, 0, sizeof (imxi)); + if (imxi_to_bcd_string (rsp->imsi, imxi, sizeof (imxi))) + qcdm_result_add_string (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_IMSI, imxi); + + /* Quick convert BCD LAI into MCC/MNC/LAC */ + mcc = (rsp->lai[0] & 0xF) * 100; + mcc += ((rsp->lai[0] >> 4) & 0xF) * 10; + mcc += rsp->lai[1] & 0xF; + qcdm_result_add_u32 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_LAI_MCC, mcc); + + mnc = (rsp->lai[2] & 0XF) * 100; + mnc += ((rsp->lai[2] >> 4) & 0xF) * 10; + mnc3 = (rsp->lai[1] >> 4) & 0xF; + if (mnc3 != 0xF) + mnc += mnc3; + qcdm_result_add_u32 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_LAI_MNC, mnc); + + qcdm_result_add_u32 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_LAI_LAC, + le16toh (*(u_int16_t *)(&rsp->lai[3]))); + + qcdm_result_add_u32 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CELLID, le16toh (rsp->cellid)); + + qcdm_result_add_u8 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_CALL_STATE, rsp->cm_call_state); + qcdm_result_add_u8 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_OP_MODE, rsp->cm_opmode); + qcdm_result_add_u8 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_SYS_MODE, rsp->cm_sysmode); + + return result; +} + +/**********************************************************************/ + diff --git a/libqcdm/src/commands.h b/libqcdm/src/commands.h index 440f0755..ecf2d92e 100644 --- a/libqcdm/src/commands.h +++ b/libqcdm/src/commands.h @@ -343,6 +343,14 @@ enum { QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_LTE = 9, }; +enum { + QCDM_CMD_CM_SUBSYS_STATE_INFO_CALL_STATE_IDLE = 0, + QCDM_CMD_CM_SUBSYS_STATE_INFO_CALL_STATE_ORIGINATING = 1, + QCDM_CMD_CM_SUBSYS_STATE_INFO_CALL_STATE_ALERTING = 3, + QCDM_CMD_CM_SUBSYS_STATE_INFO_CALL_STATE_ORIGINATION_ALERTING = 4, + QCDM_CMD_CM_SUBSYS_STATE_INFO_CALL_STATE_CONVERSATION = 5, +}; + /* Values for QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF */ enum { QCDM_CMD_CM_SUBSYS_STATE_INFO_ROAM_PREF_HOME_ONLY = 0x01, @@ -567,4 +575,65 @@ QcdmResult *qcdm_cmd_nw_subsys_modem_snapshot_cdma_result (const char *buf, /**********************************************************************/ +#define QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_IMEI "imei" + +#define QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_IMSI "imsi" + +/* Values for QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_L1_STATE */ + +enum { + QCDM_WCDMA_L1_STATE_IDLE = 0, + QCDM_WCDMA_L1_STATE_FS = 1, + QCDM_WCDMA_L1_STATE_ACQ = 2, + QCDM_WCDMA_L1_STATE_BCH = 3, + QCDM_WCDMA_L1_STATE_PCH = 4, + QCDM_WCDMA_L1_STATE_FACH = 5, + QCDM_WCDMA_L1_STATE_DCH = 6, + QCDM_WCDMA_L1_STATE_DEACTIVATED = 7, + QCDM_WCDMA_L1_STATE_PCH_SLEEP = 8, + QCDM_WCDMA_L1_STATE_DEEP_SLEEP = 9, + QCDM_WCDMA_L1_STATE_STOPPED = 10, + QCDM_WCDMA_L1_STATE_SUSPENDED = 11, +}; + +/* One of QCDM_WCDMA_L1_STATE_* */ +#define QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_L1_STATE "l1-state" + +size_t qcdm_cmd_wcdma_subsys_state_info_new (char *buf, size_t len); + +QcdmResult *qcdm_cmd_wcdma_subsys_state_info_result (const char *buf, + size_t len, + int *out_error); + +/**********************************************************************/ + +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_IMEI "imei" + +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_IMSI "imsi" + +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_LAI_MCC "lai-mcc" + +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_LAI_MNC "lai-mnc" + +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_LAI_LAC "lai-lac" + +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CELLID "cellid" + +/* One of QCDM_CMD_CM_SUBSYS_STATE_INFO_CALL_STATE_* */ +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_CALL_STATE "cm-call-state" + +/* One of QCDM_CMD_CM_SUBSYS_STATE_INFO_OPERATING_MODE_* */ +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_OP_MODE "cm-op-mode" + +/* One of QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_* */ +#define QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_SYS_MODE "cm-sys-mode" + +size_t qcdm_cmd_gsm_subsys_state_info_new (char *buf, size_t len); + +QcdmResult *qcdm_cmd_gsm_subsys_state_info_result (const char *buf, + size_t len, + int *out_error); + +/**********************************************************************/ + #endif /* LIBQCDM_COMMANDS_H */ diff --git a/libqcdm/src/dm-commands.h b/libqcdm/src/dm-commands.h index 385241bc..b803411d 100644 --- a/libqcdm/src/dm-commands.h +++ b/libqcdm/src/dm-commands.h @@ -136,11 +136,24 @@ enum { DIAG_SUBSYS_NW_CONTROL_6800 = 250 /* for Novatel Wireless MSM6800-based devices */ }; +/* WCDMA subsystem command codes */ +enum { + DIAG_SUBSYS_WCDMA_CALL_START = 12, /* Starts a call */ + DIAG_SUBSYS_WCDMA_CALL_END = 13, /* Ends an ongoing call */ + DIAG_SUBSYS_WCDMA_STATE_INFO = 15, /* Gets WCDMA state */ +}; + /* HDR subsystem command codes */ enum { DIAG_SUBSYS_HDR_STATE_INFO = 8, /* Gets EVDO state */ }; +/* GSM subsystem command codes */ +enum { + DIAG_SUBSYS_GSM_STATE_INFO = 1, /* Gets GSM state */ +}; + +/* CM subsystem command codes */ enum { DIAG_SUBSYS_CM_STATE_INFO = 0, /* Gets Call Manager state */ }; @@ -505,5 +518,36 @@ struct DMCmdLogConfigRsp { } __attribute__ ((packed)); typedef struct DMCmdLogConfigRsp DMCmdLogConfigRsp; +/* DIAG_SUBSYS_WCDMA_CALL_START command */ +struct DMCmdSubsysWcdmaCallStart { + DMCmdSubsysHeader hdr; + u_int8_t number_len; + u_int8_t number_digits[32]; + u_int8_t amr_rate; /* default to 7 */ +} __attribute__ ((packed)); +typedef struct DMCmdSubsysWcdmaCallStart DMCmdSubsysWcdmaCallStart; + +/* DIAG_SUBSYS_WCDMA_STATE_INFO response */ +struct DMCmdSubsysWcdmaStateInfoRsp { + DMCmdSubsysHeader hdr; + u_int8_t imei[9]; + u_int8_t imsi[9]; + u_int8_t l1_state; +} __attribute__ ((packed)); +typedef struct DMCmdSubsysWcdmaStateInfoRsp DMCmdSubsysWcdmaStateInfoRsp; + +/* DIAG_SUBSYS_GSM_STATE_INFO response */ +struct DMCmdSubsysGsmStateInfoRsp { + DMCmdSubsysHeader hdr; + u_int8_t imei[9]; + u_int8_t imsi[9]; + u_int8_t lai[5]; + u_int16_t cellid; + u_int8_t cm_call_state; + u_int8_t cm_opmode; + u_int8_t cm_sysmode; +} __attribute__ ((packed)); +typedef struct DMCmdSubsysGsmStateInfoRsp DMCmdSubsysGsmStateInfoRsp; + #endif /* LIBQCDM_DM_COMMANDS_H */ |