diff options
Diffstat (limited to 'libqcdm/src')
-rw-r--r-- | libqcdm/src/commands.c | 127 | ||||
-rw-r--r-- | libqcdm/src/commands.h | 43 | ||||
-rw-r--r-- | libqcdm/src/error.c | 1 | ||||
-rw-r--r-- | libqcdm/src/error.h | 3 | ||||
-rw-r--r-- | libqcdm/src/nv-items.h | 30 |
5 files changed, 201 insertions, 3 deletions
diff --git a/libqcdm/src/commands.c b/libqcdm/src/commands.c index 5dcbeaee..766a131e 100644 --- a/libqcdm/src/commands.c +++ b/libqcdm/src/commands.c @@ -107,6 +107,19 @@ check_command (const char *buf, gsize len, guint8 cmd, gsize min_len, GError **e return FALSE; } + /* NV read/write have a status byte at the end too */ + if (cmd == DIAG_CMD_NV_READ || cmd == DIAG_CMD_NV_WRITE) { + DMCmdNVReadWrite *nvcmd = (DMCmdNVReadWrite *) buf; + + g_warn_if_fail (len >= sizeof (DMCmdNVReadWrite)); + if (nvcmd->status != 0) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_NVCMD_FAILED, + "The NV operation failed (status 0x%X).", + GUINT16_FROM_LE (nvcmd->status)); + return FALSE; + } + } + return TRUE; } @@ -384,6 +397,108 @@ qcdm_cmd_nv_get_mdn_result (const char *buf, gsize len, GError **error) /**********************************************************************/ +static gboolean +roam_pref_validate (guint8 dm) +{ + if ( dm == DIAG_NV_ROAM_PREF_HOME_ONLY + || dm == DIAG_NV_ROAM_PREF_ROAM_ONLY + || dm == DIAG_NV_ROAM_PREF_AUTO) + return TRUE; + return FALSE; +} + +gsize +qcdm_cmd_nv_get_roam_pref_new (char *buf, gsize len, guint8 profile, GError **error) +{ + char cmdbuf[sizeof (DMCmdNVReadWrite) + 2]; + DMCmdNVReadWrite *cmd = (DMCmdNVReadWrite *) &cmdbuf[0]; + DMNVItemRoamPref *req; + + 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_ROAM_PREF); + + req = (DMNVItemRoamPref *) &cmd->data[0]; + req->profile = profile; + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +QCDMResult * +qcdm_cmd_nv_get_roam_pref_result (const char *buf, gsize len, GError **error) +{ + QCDMResult *result = NULL; + DMCmdNVReadWrite *rsp = (DMCmdNVReadWrite *) buf; + DMNVItemRoamPref *roam; + + g_return_val_if_fail (buf != NULL, NULL); + + if (!check_command (buf, len, DIAG_CMD_NV_READ, sizeof (DMCmdNVReadWrite), error)) + return NULL; + + roam = (DMNVItemRoamPref *) &rsp->data[0]; + + if (!roam_pref_validate (roam->roam_pref)) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_PARAMETER, + "Unknown roam preference 0x%X", + roam->roam_pref); + return NULL; + } + + result = qcdm_result_new (); + qcdm_result_add_uint8 (result, QCDM_CMD_NV_GET_ROAM_PREF_ITEM_PROFILE, roam->profile); + qcdm_result_add_uint8 (result, QCDM_CMD_NV_GET_ROAM_PREF_ITEM_ROAM_PREF, roam->roam_pref); + + return result; +} + +gsize +qcdm_cmd_nv_set_roam_pref_new (char *buf, + gsize len, + guint8 profile, + guint8 roam_pref, + GError **error) +{ + char cmdbuf[sizeof (DMCmdNVReadWrite) + 2]; + DMCmdNVReadWrite *cmd = (DMCmdNVReadWrite *) &cmdbuf[0]; + DMNVItemRoamPref *req; + + g_return_val_if_fail (buf != NULL, 0); + g_return_val_if_fail (len >= sizeof (*cmd) + DIAG_TRAILER_LEN, 0); + + if (!roam_pref_validate (roam_pref)) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_PARAMETER, + "Invalid roam preference %d", roam_pref); + return 0; + } + + memset (cmd, 0, sizeof (*cmd)); + cmd->code = DIAG_CMD_NV_WRITE; + cmd->nv_item = GUINT16_TO_LE (DIAG_NV_ROAM_PREF); + + req = (DMNVItemRoamPref *) &cmd->data[0]; + req->profile = profile; + req->roam_pref = roam_pref; + + return dm_encapsulate_buffer (cmdbuf, sizeof (*cmd), sizeof (cmdbuf), buf, len); +} + +QCDMResult * +qcdm_cmd_nv_set_roam_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; + + return qcdm_result_new (); +} + +/**********************************************************************/ + gsize qcdm_cmd_cm_subsys_state_info_new (char *buf, gsize len, GError **error) { @@ -407,12 +522,21 @@ qcdm_cmd_cm_subsys_state_info_result (const char *buf, gsize len, GError **error QCDMResult *result = NULL; DMCmdSubsysCMStateInfoRsp *rsp = (DMCmdSubsysCMStateInfoRsp *) buf; guint32 tmp_num; + guint32 roam_pref; g_return_val_if_fail (buf != NULL, NULL); if (!check_command (buf, len, DIAG_CMD_SUBSYS, sizeof (DMCmdSubsysCMStateInfoRsp), error)) return NULL; + roam_pref = (guint32) GUINT32_FROM_LE (rsp->roam_pref); + if (!roam_pref_validate (roam_pref)) { + g_set_error (error, QCDM_COMMAND_ERROR, QCDM_COMMAND_BAD_PARAMETER, + "Unknown roam preference 0x%X", + roam_pref); + return NULL; + } + result = qcdm_result_new (); tmp_num = (guint32) GUINT32_FROM_LE (rsp->call_state); @@ -430,8 +554,7 @@ qcdm_cmd_cm_subsys_state_info_result (const char *buf, gsize len, GError **error tmp_num = (guint32) GUINT32_FROM_LE (rsp->band_pref); qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_BAND_PREF, tmp_num); - tmp_num = (guint32) GUINT32_FROM_LE (rsp->roam_pref); - qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF, tmp_num); + qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF, roam_pref); tmp_num = (guint32) GUINT32_FROM_LE (rsp->srv_domain_pref); qcdm_result_add_uint32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SERVICE_DOMAIN_PREF, tmp_num); diff --git a/libqcdm/src/commands.h b/libqcdm/src/commands.h index f1b6f77e..a7d86748 100644 --- a/libqcdm/src/commands.h +++ b/libqcdm/src/commands.h @@ -112,6 +112,37 @@ QCDMResult *qcdm_cmd_nv_get_mdn_result (const char *buf, /**********************************************************************/ +/* Values for QCDM_CMD_NV_GET_ROAM_PREF_ITEM_ROAM_PREF */ +enum { + QCDM_CMD_NV_ROAM_PREF_ITEM_ROAM_PREF_HOME_ONLY = 0x01, + QCDM_CMD_NV_ROAM_PREF_ITEM_ROAM_PREF_ROAM_ONLY = 0x06, + QCDM_CMD_NV_ROAM_PREF_ITEM_ROAM_PREF_AUTO = 0xFF, +}; + +#define QCDM_CMD_NV_GET_ROAM_PREF_ITEM_PROFILE "profile" +#define QCDM_CMD_NV_GET_ROAM_PREF_ITEM_ROAM_PREF "roam-pref" + +gsize qcdm_cmd_nv_get_roam_pref_new (char *buf, + gsize len, + guint8 profile, + GError **error); + +QCDMResult *qcdm_cmd_nv_get_roam_pref_result (const char *buf, + gsize len, + GError **error); + +gsize qcdm_cmd_nv_set_roam_pref_new (char *buf, + gsize len, + guint8 profile, + guint8 roam_pref, + GError **error); + +QCDMResult *qcdm_cmd_nv_set_roam_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 @@ -126,6 +157,18 @@ enum { QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WCDMA = 5 }; +/* Values for QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_ROAM_PREF */ +enum { + QCDM_CMD_CM_SUBSYS_STATE_INFO_ROAM_PREF_HOME_ONLY = 0x01, + QCDM_CMD_CM_SUBSYS_STATE_INFO_ROAM_PREF_ROAM_ONLY = 0x06, + QCDM_CMD_CM_SUBSYS_STATE_INFO_ROAM_PREF_AUTO = 0xFF, +}; + +/* Values for QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_MODE_PREF */ +enum { + QCDM_CMD_CM_SUBSYS_STATE_INFO_MODE_PREF_AUTO = 0x02, +}; + #define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_CALL_STATE "call-state" #define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE "operating-mode" #define QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE "system-mode" diff --git a/libqcdm/src/error.c b/libqcdm/src/error.c index bf16b56a..e3b97a04 100644 --- a/libqcdm/src/error.c +++ b/libqcdm/src/error.c @@ -74,6 +74,7 @@ qcdm_command_error_get_type (void) ENUM_ENTRY (QCDM_COMMAND_BAD_PARAMETER, "QcdmCommandBadParameter"), ENUM_ENTRY (QCDM_COMMAND_NOT_ACCEPTED, "QcdmCommandNotAccepted"), ENUM_ENTRY (QCDM_COMMAND_BAD_MODE, "QcdmCommandBadMode"), + ENUM_ENTRY (QCDM_COMMAND_NVCMD_FAILED, "QcdmCommandNvCmdFailed"), { 0, 0, 0 } }; diff --git a/libqcdm/src/error.h b/libqcdm/src/error.h index 7098fcbe..7a02ae2c 100644 --- a/libqcdm/src/error.h +++ b/libqcdm/src/error.h @@ -39,7 +39,8 @@ enum { QCDM_COMMAND_BAD_COMMAND = 3, QCDM_COMMAND_BAD_PARAMETER = 4, QCDM_COMMAND_NOT_ACCEPTED = 5, - QCDM_COMMAND_BAD_MODE = 6 + QCDM_COMMAND_BAD_MODE = 6, + QCDM_COMMAND_NVCMD_FAILED = 7, }; #define QCDM_COMMAND_ERROR (qcdm_command_error_quark ()) diff --git a/libqcdm/src/nv-items.h b/libqcdm/src/nv-items.h index 6f058121..b82e3a4f 100644 --- a/libqcdm/src/nv-items.h +++ b/libqcdm/src/nv-items.h @@ -19,10 +19,27 @@ #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 */ }; +/* 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 */ +struct DMNVItemModePref { + guint8 profile; + guint8 _unknown1; + guint8 mode_pref; +} __attribute__ ((packed)); +typedef struct DMNVItemModePref DMNVItemModePref; + /* DIAG_NV_DIR_NUMBER */ struct DMNVItemMdn { guint8 profile; @@ -30,6 +47,19 @@ struct DMNVItemMdn { } __attribute__ ((packed)); typedef struct DMNVItemMdn DMNVItemMdn; +/* Roam preference values */ +enum { + DIAG_NV_ROAM_PREF_HOME_ONLY = 0x01, + DIAG_NV_ROAM_PREF_ROAM_ONLY = 0x06, + DIAG_NV_ROAM_PREF_AUTO = 0xFF, +}; + +/* DIAG_NV_ROAM_PREF */ +struct DMNVItemRoamPref { + guint8 profile; + guint8 roam_pref; +} __attribute__ ((packed)); +typedef struct DMNVItemRoamPref DMNVItemRoamPref; #endif /* LIBQCDM_NV_ITEMS_H */ |