wmc: add some more commands and fix up network info
Add operator commands, and fix up the network info response handling for GSM/WCDMA capable devices like the UML190 when it's in GSM/WCDMA mode.
This commit is contained in:
@@ -213,48 +213,136 @@ wmc_cmd_network_info_new (char *buf, size_t buflen)
|
||||
return sizeof (*cmd);
|
||||
}
|
||||
|
||||
static u_int8_t
|
||||
sanitize_dbm (u_int8_t in_dbm)
|
||||
static wmcbool
|
||||
is_gsm_service (u_int8_t service)
|
||||
{
|
||||
/* 0x7D (-125 dBm) really means no signal */
|
||||
return in_dbm >= 0x7D ? 0 : in_dbm;
|
||||
return (service == WMC_SERVICE_GSM || service == WMC_SERVICE_GPRS || service == WMC_SERVICE_EDGE);
|
||||
}
|
||||
|
||||
static wmcbool
|
||||
is_umts_service (u_int8_t service)
|
||||
{
|
||||
return (service == WMC_SERVICE_UMTS || service == WMC_SERVICE_HSDPA
|
||||
|| service == WMC_SERVICE_HSUPA || service == WMC_SERVICE_HSPA);
|
||||
}
|
||||
|
||||
static wmcbool
|
||||
is_cdma_service (u_int8_t service)
|
||||
{
|
||||
return (service == WMC_SERVICE_IS95A || service == WMC_SERVICE_IS95B || service == WMC_SERVICE_1XRTT);
|
||||
}
|
||||
|
||||
static wmcbool
|
||||
is_evdo_service (u_int8_t service)
|
||||
{
|
||||
return (service == WMC_SERVICE_EVDO_0 || service == WMC_SERVICE_EVDO_A);
|
||||
}
|
||||
|
||||
static wmcbool
|
||||
is_lte_service (u_int8_t service)
|
||||
{
|
||||
return (service == WMC_SERVICE_LTE);
|
||||
}
|
||||
|
||||
static u_int8_t
|
||||
sanitize_dbm (u_int8_t in_dbm, u_int8_t service)
|
||||
{
|
||||
u_int8_t cutoff;
|
||||
|
||||
/* 0x6A (-106 dBm) = no signal for GSM/GPRS/EDGE */
|
||||
/* 0x7D (-125 dBm) = no signal for everything else */
|
||||
cutoff = is_gsm_service (service) ? 0x6A : 0x7D;
|
||||
|
||||
return in_dbm >= cutoff ? 0 : in_dbm;
|
||||
}
|
||||
|
||||
|
||||
WmcResult *
|
||||
wmc_cmd_network_info_result (const char *buf, size_t buflen)
|
||||
{
|
||||
WmcResult *r = NULL;
|
||||
WmcCmdNetworkInfoRsp *rsp = (WmcCmdNetworkInfoRsp *) buf;
|
||||
WmcCmdNetworkInfo2Rsp *rsp2 = (WmcCmdNetworkInfo2Rsp *) buf;
|
||||
WmcCmdNetworkInfo3Rsp *rsp3 = (WmcCmdNetworkInfo3Rsp *) buf;
|
||||
char tmp[65];
|
||||
int err;
|
||||
u_int32_t mccmnc = 0, mcc, mnc;
|
||||
|
||||
wmc_return_val_if_fail (buf != NULL, NULL);
|
||||
|
||||
if (check_command (buf, buflen, WMC_CMD_NET_INFO, sizeof (WmcCmdNetworkInfo2Rsp)) < 0) {
|
||||
rsp2 = NULL;
|
||||
if (check_command (buf, buflen, WMC_CMD_NET_INFO, sizeof (WmcCmdNetworkInfoRsp)) < 0)
|
||||
err = check_command (buf, buflen, WMC_CMD_NET_INFO, sizeof (WmcCmdNetworkInfo3Rsp));
|
||||
if (err != WMC_SUCCESS) {
|
||||
if (err != -WMC_ERROR_RESPONSE_BAD_LENGTH)
|
||||
return NULL;
|
||||
rsp3 = NULL;
|
||||
|
||||
err = check_command (buf, buflen, WMC_CMD_NET_INFO, sizeof (WmcCmdNetworkInfo2Rsp));
|
||||
if (err != WMC_SUCCESS) {
|
||||
if (err != -WMC_ERROR_RESPONSE_BAD_LENGTH)
|
||||
return NULL;
|
||||
rsp2 = NULL;
|
||||
|
||||
err = check_command (buf, buflen, WMC_CMD_NET_INFO, sizeof (WmcCmdNetworkInfoRsp));
|
||||
if (err != WMC_SUCCESS)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
r = wmc_result_new ();
|
||||
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_CDMA_DBM, sanitize_dbm (rsp->cdma1x_dbm));
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_SERVICE, rsp->service);
|
||||
|
||||
if (rsp2) {
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_HDR_DBM, sanitize_dbm (rsp2->hdr_dbm));
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_LTE_DBM, sanitize_dbm (rsp2->lte_dbm));
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_2G_DBM, sanitize_dbm (rsp2->two_g_dbm, rsp->service));
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_3G_DBM, sanitize_dbm (rsp2->three_g_dbm, WMC_SERVICE_NONE));
|
||||
|
||||
memset (tmp, 0, sizeof (tmp));
|
||||
if (sanitize_dbm (rsp2->lte_dbm)) {
|
||||
/* LTE operator name */
|
||||
wmc_assert (sizeof (rsp2->lte_opname) <= sizeof (tmp));
|
||||
memcpy (tmp, rsp2->lte_opname, sizeof (rsp2->lte_opname));
|
||||
wmc_result_add_string (r, WMC_CMD_NETWORK_INFO_ITEM_OPNAME, tmp);
|
||||
} else if (sanitize_dbm (rsp2->hdr_dbm) || sanitize_dbm (rsp2->cdma1x_dbm)) {
|
||||
if ( (is_cdma_service (rsp->service) && sanitize_dbm (rsp2->two_g_dbm, rsp->service))
|
||||
|| (is_evdo_service (rsp->service) && sanitize_dbm (rsp2->three_g_dbm, rsp->service))) {
|
||||
/* CDMA2000 operator name */
|
||||
wmc_assert (sizeof (rsp2->cdma_opname) <= sizeof (tmp));
|
||||
memcpy (tmp, rsp2->cdma_opname, sizeof (rsp2->cdma_opname));
|
||||
wmc_result_add_string (r, WMC_CMD_NETWORK_INFO_ITEM_OPNAME, tmp);
|
||||
} else {
|
||||
if ( (is_gsm_service (rsp->service) && sanitize_dbm (rsp2->two_g_dbm, rsp->service))
|
||||
|| (is_umts_service (rsp->service) && sanitize_dbm (rsp2->three_g_dbm, rsp->service))) {
|
||||
/* GSM/UMTS operator name */
|
||||
wmc_assert (sizeof (rsp2->tgpp_opname) <= sizeof (tmp));
|
||||
memcpy (tmp, rsp2->tgpp_opname, sizeof (rsp2->tgpp_opname));
|
||||
wmc_result_add_string (r, WMC_CMD_NETWORK_INFO_ITEM_OPNAME, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* MCC/MNC */
|
||||
mccmnc = le32toh (rsp2->mcc_mnc);
|
||||
if (mccmnc < 100000)
|
||||
mccmnc *= 10; /* account for possible 2-digit MNC */
|
||||
mcc = mccmnc / 1000;
|
||||
mnc = mccmnc - (mcc * 1000);
|
||||
|
||||
if (mcc > 100) {
|
||||
memset (tmp, 0, sizeof (tmp));
|
||||
snprintf (tmp, sizeof (tmp), "%u", mccmnc / 1000);
|
||||
wmc_result_add_string (r, WMC_CMD_NETWORK_INFO_ITEM_MCC, tmp);
|
||||
|
||||
memset (tmp, 0, sizeof (tmp));
|
||||
snprintf (tmp, sizeof (tmp), "%03u", mnc);
|
||||
wmc_result_add_string (r, WMC_CMD_NETWORK_INFO_ITEM_MNC, tmp);
|
||||
}
|
||||
} else {
|
||||
/* old format */
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_2G_DBM, sanitize_dbm (rsp->two_g_dbm, rsp->service));
|
||||
}
|
||||
|
||||
if (rsp3) {
|
||||
wmc_result_add_u8 (r, WMC_CMD_NETWORK_INFO_ITEM_LTE_DBM, sanitize_dbm (rsp3->lte_dbm, WMC_SERVICE_NONE));
|
||||
|
||||
memset (tmp, 0, sizeof (tmp));
|
||||
if (is_lte_service (rsp->service) && sanitize_dbm (rsp3->lte_dbm, rsp->service)) {
|
||||
/* LTE operator name */
|
||||
wmc_assert (sizeof (rsp2->tgpp_opname) <= sizeof (tmp));
|
||||
memcpy (tmp, rsp2->tgpp_opname, sizeof (rsp2->tgpp_opname));
|
||||
wmc_result_add_string (r, WMC_CMD_NETWORK_INFO_ITEM_OPNAME, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,3 +351,35 @@ wmc_cmd_network_info_result (const char *buf, size_t buflen)
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
size_t
|
||||
wmc_cmd_get_global_mode_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_GET_GLOBAL_MODE;
|
||||
return sizeof (*cmd);
|
||||
}
|
||||
|
||||
WmcResult *
|
||||
wmc_cmd_get_global_mode_result (const char *buf, size_t buflen)
|
||||
{
|
||||
WmcResult *r = NULL;
|
||||
WmcCmdGetGlobalModeRsp *rsp = (WmcCmdGetGlobalModeRsp *) buf;
|
||||
|
||||
wmc_return_val_if_fail (buf != NULL, NULL);
|
||||
|
||||
if (check_command (buf, buflen, WMC_CMD_GET_GLOBAL_MODE, sizeof (WmcCmdGetGlobalModeRsp)) < 0)
|
||||
return NULL;
|
||||
|
||||
r = wmc_result_new ();
|
||||
wmc_result_add_u8 (r, WMC_CMD_GET_GLOBAL_MODE_ITEM_MODE, rsp->mode);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
|
@@ -47,10 +47,33 @@ WmcResult * wmc_cmd_device_info_result (const char *buf, size_t len);
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_CDMA_DBM "cdma-dbm"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_HDR_DBM "hdr-dbm"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_LTE_DBM "lte-dbm"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_OPNAME "opname"
|
||||
enum {
|
||||
WMC_NETWORK_SERVICE_NONE = 0,
|
||||
WMC_NETWORK_SERVICE_AMPS = 1,
|
||||
WMC_NETWORK_SERVICE_IS95A = 2,
|
||||
WMC_NETWORK_SERVICE_IS95B = 3,
|
||||
WMC_NETWORK_SERVICE_GSM = 4,
|
||||
WMC_NETWORK_SERVICE_GPRS = 5,
|
||||
WMC_NETWORK_SERVICE_1XRTT = 6,
|
||||
WMC_NETWORK_SERVICE_EVDO_0 = 7,
|
||||
WMC_NETWORK_SERVICE_UMTS = 8,
|
||||
WMC_NETWORK_SERVICE_EVDO_A = 9,
|
||||
WMC_NETWORK_SERVICE_EDGE = 10,
|
||||
WMC_NETWORK_SERVICE_HSDPA = 11,
|
||||
WMC_NETWORK_SERVICE_HSUPA = 12,
|
||||
WMC_NETWORK_SERVICE_HSPA = 13,
|
||||
WMC_NETWORK_SERVICE_LTE = 14
|
||||
};
|
||||
|
||||
/* One of WMC_NETWORK_SERVICE_* */
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_SERVICE "service"
|
||||
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_2G_DBM "2g-dbm"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_3G_DBM "3g-dbm"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_LTE_DBM "lte-dbm"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_OPNAME "opname"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_MCC "mcc"
|
||||
#define WMC_CMD_NETWORK_INFO_ITEM_MNC "mnc"
|
||||
|
||||
size_t wmc_cmd_network_info_new (char *buf, size_t buflen);
|
||||
|
||||
@@ -58,4 +81,21 @@ WmcResult * wmc_cmd_network_info_result (const char *buf, size_t len);
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
enum {
|
||||
WMC_NETWORK_MODE_CDMA = 0x00,
|
||||
WMC_NETWORK_MODE_GSM_AUTO = 0x0A,
|
||||
WMC_NETWORK_MODE_GPRS_ONLY = 0x0B,
|
||||
WMC_NETWORK_MODE_UMTS_ONLY = 0x0C,
|
||||
WMC_NETWORK_MODE_AUTO = 0x14,
|
||||
};
|
||||
|
||||
/* One of WMC_NETWORK_MODE_* */
|
||||
#define WMC_CMD_GET_GLOBAL_MODE_ITEM_MODE "mode"
|
||||
|
||||
size_t wmc_cmd_get_global_mode_new (char *buf, size_t buflen);
|
||||
|
||||
WmcResult * wmc_cmd_get_global_mode_result (const char *buf, size_t len);
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
#endif /* LIBWMC_COMMANDS_H */
|
||||
|
@@ -27,9 +27,26 @@ enum {
|
||||
WMC_CMD_IP_INFO = 0x0A,
|
||||
WMC_CMD_NET_INFO = 0x0B,
|
||||
WMC_CMD_INIT = 0x0D,
|
||||
WMC_CMD_SET_OPERATOR = 0x33,
|
||||
WMC_CMD_GET_FIRST_OPERATOR = 0x34,
|
||||
WMC_CMD_GET_NEXT_OPERATOR = 0x35,
|
||||
WMC_CMD_EPS_BEARER_INFO = 0x4D,
|
||||
};
|
||||
|
||||
/* MCC/MNC representation
|
||||
*
|
||||
* Various commands accept or return an MCC/MNC. When sending, convert
|
||||
* the MCC/MNC into a number using eg. atoi() and store it as an LE 32-bit
|
||||
* value. 3-digit MNCs appear to be sent as 3-digit only if the firmware
|
||||
* reports them as 3-digit. For example:
|
||||
*
|
||||
* T-Mobile US: 310-260
|
||||
* mcc_mnc = 0x00007932 = 31026 (note the 2-digit-only MNC)
|
||||
*
|
||||
* AT&T: 310-410
|
||||
* mcc_mnc = 0x0004bc8a = 310410
|
||||
*/
|
||||
|
||||
|
||||
/* Generic WMC command header */
|
||||
struct WmcCmdHeader {
|
||||
@@ -105,9 +122,9 @@ enum {
|
||||
WMC_SERVICE_GSM = 4,
|
||||
WMC_SERVICE_GPRS = 5,
|
||||
WMC_SERVICE_1XRTT = 6,
|
||||
WMC_SERVICE_1XEVDO_0 = 7,
|
||||
WMC_SERVICE_EVDO_0 = 7,
|
||||
WMC_SERVICE_UMTS = 8,
|
||||
WMC_SERVICE_1XEVDO_A = 9,
|
||||
WMC_SERVICE_EVDO_A = 9,
|
||||
WMC_SERVICE_EDGE = 10,
|
||||
WMC_SERVICE_HSDPA = 11,
|
||||
WMC_SERVICE_HSUPA = 12,
|
||||
@@ -115,7 +132,7 @@ enum {
|
||||
WMC_SERVICE_LTE = 14
|
||||
};
|
||||
|
||||
/* Shorter response used by earlier devices like PC5740 */
|
||||
/* PC5740 response */
|
||||
struct WmcCmdNetworkInfoRsp {
|
||||
WmcCmdHeader hdr;
|
||||
u_int8_t _unknown1;
|
||||
@@ -127,12 +144,12 @@ struct WmcCmdNetworkInfoRsp {
|
||||
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 two_g_dbm; /* 0x7D = no signal */
|
||||
u_int8_t _unknown8[37]; /* Always zero */
|
||||
} __attribute__ ((packed));
|
||||
typedef struct WmcCmdNetworkInfoRsp WmcCmdNetworkInfoRsp;
|
||||
|
||||
/* Long-format response used on newer devices like the UML290 */
|
||||
/* UML190 response */
|
||||
struct WmcCmdNetworkInfo2Rsp {
|
||||
WmcCmdHeader hdr;
|
||||
u_int8_t _unknown1; /* 0x00 on LTE, 0x07 or 0x1F on CDMA */
|
||||
@@ -144,23 +161,57 @@ struct WmcCmdNetworkInfo2Rsp {
|
||||
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 two_g_dbm; /* 0x7D = no CDMA signal, 0x6a = no GSM 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 three_g_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];
|
||||
u_int8_t tgpp_opname[8]; /* 3GPP operator name (Zero terminated? Sometimes "MCC MNC" too */
|
||||
u_int8_t _unknown13[4]; /* Always zero */
|
||||
u_int32_t _unknown14; /* 43 75 3a 00 on GSM/WCDMA mode, zero on others */
|
||||
u_int32_t _unknown15; /* 49 7d 3a 00 on GSM/WCDMA mode, zero on others */
|
||||
u_int8_t _unknown16[44]; /* Always zero */
|
||||
u_int32_t mcc_mnc; /* GSM/WCDMA only, see MCC/MNC format note */
|
||||
} __attribute__ ((packed));
|
||||
typedef struct WmcCmdNetworkInfo2Rsp WmcCmdNetworkInfo2Rsp;
|
||||
|
||||
/* UML290 response */
|
||||
struct WmcCmdNetworkInfo3Rsp {
|
||||
WmcCmdHeader hdr;
|
||||
u_int8_t _unknown1; /* 0x00 on LTE, 0x07 or 0x1F on CDMA */
|
||||
u_int8_t _unknown2[3]; /* Always zero */
|
||||
u_int8_t service; /* One of WMC_SERVICE_* */
|
||||
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 two_g_dbm; /* 0x7D = no CDMA signal, 0x6a = no GSM 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 three_g_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 tgpp_opname[8]; /* Zero terminated? Sometimes "MCC MNC" too */
|
||||
u_int8_t _unknown13[4]; /* Always zero */
|
||||
u_int32_t _unknown14; /* 43 75 3a 00 on GSM/WCDMA mode, zero on others */
|
||||
u_int32_t _unknown15; /* 49 7d 3a 00 on GSM/WCDMA mode, zero on others */
|
||||
u_int8_t _unknown16[44]; /* Always zero */
|
||||
u_int32_t mcc_mnc; /* GSM/WCDMA only, see MCC/MNC format note */
|
||||
u_int8_t lte_dbm; /* 0x00 if not in LTE mode */
|
||||
u_int8_t _unknown17[3]; /* Always zero */
|
||||
u_int8_t _unknown18[4];
|
||||
} __attribute__ ((packed));
|
||||
typedef struct WmcCmdNetworkInfo3Rsp WmcCmdNetworkInfo3Rsp;
|
||||
|
||||
/*****************************************************/
|
||||
|
||||
struct WmcCmdConnectionInfoRsp {
|
||||
@@ -179,9 +230,11 @@ typedef struct WmcCmdConnectionInfoRsp WmcCmdConnectionInfoRsp;
|
||||
/*****************************************************/
|
||||
|
||||
enum {
|
||||
WMC_GLOBAL_MODE_CDMA = 0x00,
|
||||
WMC_GLOBAL_MODE_GSM = 0x0A,
|
||||
WMC_GLOBAL_MODE_AUTO = 0x14,
|
||||
WMC_GLOBAL_MODE_CDMA = 0x00,
|
||||
WMC_GLOBAL_MODE_GSM_AUTO = 0x0A,
|
||||
WMC_GLOBAL_MODE_GPRS_ONLY = 0x0B,
|
||||
WMC_GLOBAL_MODE_UMTS_ONLY = 0x0C,
|
||||
WMC_GLOBAL_MODE_AUTO = 0x14,
|
||||
};
|
||||
|
||||
struct WmcCmdGetGlobalMode {
|
||||
@@ -219,4 +272,55 @@ typedef struct WmcCmdSetGlobalModeRsp WmcCmdSetGlobalModeRsp;
|
||||
|
||||
/*****************************************************/
|
||||
|
||||
struct WmcCmdSetOperator {
|
||||
WmcCmdHeader hdr;
|
||||
u_int8_t automatic; /* 0x00 = manual, 0x01 = auto */
|
||||
u_int8_t _unknown1; /* always 0x50 */
|
||||
u_int8_t _unknown2[3]; /* always zero */
|
||||
u_int32_t mcc_mnc; /* MCC/MNC for manual reg (see format note), zero for auto */
|
||||
u_int8_t _unknown3[56]; /* always zero */
|
||||
} __attribute__ ((packed));
|
||||
typedef struct WmcCmdSetOperator WmcCmdSetOperator;
|
||||
|
||||
enum {
|
||||
WMC_SET_OPERATOR_STATUS_OK = 0,
|
||||
WMC_SET_OPERATOR_STATUS_REGISTERING = 0x63,
|
||||
WMC_SET_OPERATOR_STATUS_FAILED = 0x68,
|
||||
};
|
||||
|
||||
struct WmcCmdSetOperatorRsp {
|
||||
WmcCmdHeader hdr;
|
||||
u_int8_t status; /* one of WMC_SET_OPERATOR_STATUS_* */
|
||||
u_int8_t _unknown1[3]; /* always zero */
|
||||
} __attribute__ ((packed));
|
||||
typedef struct WmcCmdSetOperatorRsp WmcCmdSetOperatorRsp;
|
||||
|
||||
/*****************************************************/
|
||||
|
||||
enum {
|
||||
WMC_OPERATOR_SERVICE_UNKNOWN = 0,
|
||||
WMC_OPERATOR_SERVICE_GSM = 1,
|
||||
WMC_OPERATOR_SERVICE_UMTS = 2,
|
||||
};
|
||||
|
||||
/* Response for both GET_FIRST_OPERATOR and GET_NEXT_OPERATOR */
|
||||
struct WmcCmdGetOperatorRsp {
|
||||
WmcCmdHeader hdr;
|
||||
u_int8_t _unknown1; /* Usually 0x50, sometimes 0x00 */
|
||||
u_int8_t _unknown2[3]; /* always zero */
|
||||
u_int32_t mcc_mnc; /* see format note */
|
||||
u_int8_t opname[8];
|
||||
u_int8_t _unknown3[56]; /* always zero */
|
||||
u_int8_t stat; /* follows 3GPP TS27.007 +COPS <stat> ? */
|
||||
u_int8_t _unknown4[3]; /* always zero */
|
||||
u_int8_t service; /* one of WMC_OPERATOR_SERVICE_* */
|
||||
u_int8_t _unknown5[3]; /* always zero */
|
||||
u_int8_t _unknown6; /* 0x63 (GET_FIRST_OP) might mean "wait" */
|
||||
u_int8_t _unknown7; /* 0x00 or 0x01 */
|
||||
u_int8_t _unknown8[2]; /* always zero */
|
||||
} __attribute__ ((packed));
|
||||
typedef struct WmcCmdSetOperatorRsp WmcCmdSetOperatorRsp;
|
||||
|
||||
/*****************************************************/
|
||||
|
||||
#endif /* LIBWMC_PROTOCOL_H */
|
||||
|
@@ -48,7 +48,7 @@ test_com_setup (const char *port, wmcbool uml290, wmcbool debug)
|
||||
|
||||
d = g_malloc0 (sizeof (TestComData));
|
||||
g_assert (d);
|
||||
d->uml290 = uml290;
|
||||
d->uml290 = uml290;
|
||||
d->debug = debug;
|
||||
|
||||
if (getenv ("SERIAL_DEBUG"))
|
||||
@@ -158,7 +158,7 @@ wait_reply (TestComData *d, char *buf, size_t len)
|
||||
fd_set in;
|
||||
int result;
|
||||
struct timeval timeout = { 1, 0 };
|
||||
char readbuf[1024];
|
||||
char readbuf[2048];
|
||||
ssize_t bytes_read;
|
||||
int total = 0, retries = 0;
|
||||
size_t decap_len = 0;
|
||||
@@ -236,7 +236,7 @@ test_com_init (void *f, void *data)
|
||||
size_t reply_len;
|
||||
|
||||
len = wmc_cmd_init_new (buf, sizeof (buf), d->uml290);
|
||||
g_assert (len == 16);
|
||||
g_assert (len);
|
||||
|
||||
/* Send the command */
|
||||
success = send_command (d, buf, sizeof (buf), len);
|
||||
@@ -257,7 +257,7 @@ test_com_device_info (void *f, void *data)
|
||||
{
|
||||
TestComData *d = data;
|
||||
wmcbool success;
|
||||
char buf[1024];
|
||||
char buf[2048];
|
||||
const char *str, *str2;
|
||||
gint len;
|
||||
WmcResult *result;
|
||||
@@ -314,14 +314,53 @@ test_com_device_info (void *f, void *data)
|
||||
wmc_result_unref (result);
|
||||
}
|
||||
|
||||
static const char *
|
||||
service_to_string (u_int8_t service)
|
||||
{
|
||||
switch (service) {
|
||||
case WMC_NETWORK_SERVICE_NONE:
|
||||
return "none";
|
||||
case WMC_NETWORK_SERVICE_AMPS:
|
||||
return "AMPS";
|
||||
case WMC_NETWORK_SERVICE_IS95A:
|
||||
return "IS95-A";
|
||||
case WMC_NETWORK_SERVICE_IS95B:
|
||||
return "IS95-B";
|
||||
case WMC_NETWORK_SERVICE_GSM:
|
||||
return "GSM";
|
||||
case WMC_NETWORK_SERVICE_GPRS:
|
||||
return "GPRS";
|
||||
case WMC_NETWORK_SERVICE_1XRTT:
|
||||
return "1xRTT";
|
||||
case WMC_NETWORK_SERVICE_EVDO_0:
|
||||
return "EVDO r0";
|
||||
case WMC_NETWORK_SERVICE_UMTS:
|
||||
return "UMTS";
|
||||
case WMC_NETWORK_SERVICE_EVDO_A:
|
||||
return "EVDO rA";
|
||||
case WMC_NETWORK_SERVICE_EDGE:
|
||||
return "EDGE";
|
||||
case WMC_NETWORK_SERVICE_HSDPA:
|
||||
return "HSDPA";
|
||||
case WMC_NETWORK_SERVICE_HSUPA:
|
||||
return "HSUPA";
|
||||
case WMC_NETWORK_SERVICE_HSPA:
|
||||
return "HSPA";
|
||||
case WMC_NETWORK_SERVICE_LTE:
|
||||
return "LTE";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_com_status (void *f, void *data)
|
||||
test_com_network_info (void *f, void *data)
|
||||
{
|
||||
TestComData *d = data;
|
||||
wmcbool success;
|
||||
char buf[1024];
|
||||
const char *str;
|
||||
u_int8_t dbm;
|
||||
u_int8_t dbm, service;
|
||||
gint len;
|
||||
WmcResult *result;
|
||||
size_t reply_len;
|
||||
@@ -342,22 +381,87 @@ test_com_status (void *f, void *data)
|
||||
|
||||
g_print ("\n");
|
||||
|
||||
dbm = 0;
|
||||
wmc_result_get_u8 (result, WMC_CMD_NETWORK_INFO_ITEM_CDMA_DBM, &dbm);
|
||||
g_message ("%s: CDMA 1x dBm: %d", __func__, dbm);
|
||||
service = 0;
|
||||
wmc_result_get_u8 (result, WMC_CMD_NETWORK_INFO_ITEM_SERVICE, &service);
|
||||
g_message ("%s: Service: %d (%s)", __func__, service, service_to_string (service));
|
||||
|
||||
dbm = 0;
|
||||
wmc_result_get_u8 (result, WMC_CMD_NETWORK_INFO_ITEM_HDR_DBM, &dbm);
|
||||
g_message ("%s: HDR dBm: %d", __func__, dbm);
|
||||
wmc_result_get_u8 (result, WMC_CMD_NETWORK_INFO_ITEM_2G_DBM, &dbm);
|
||||
g_message ("%s: 2G dBm: -%d", __func__, dbm);
|
||||
|
||||
dbm = 0;
|
||||
wmc_result_get_u8 (result, WMC_CMD_NETWORK_INFO_ITEM_3G_DBM, &dbm);
|
||||
g_message ("%s: 3G dBm: -%d", __func__, dbm);
|
||||
|
||||
dbm = 0;
|
||||
wmc_result_get_u8 (result, WMC_CMD_NETWORK_INFO_ITEM_LTE_DBM, &dbm);
|
||||
g_message ("%s: LTE dBm: %d", __func__, dbm);
|
||||
g_message ("%s: LTE dBm: -%d", __func__, dbm);
|
||||
|
||||
str = NULL;
|
||||
wmc_result_get_string (result, WMC_CMD_NETWORK_INFO_ITEM_OPNAME, &str);
|
||||
g_message ("%s: Operator Name: %s", __func__, str ? str : "(none)");
|
||||
|
||||
str = NULL;
|
||||
wmc_result_get_string (result, WMC_CMD_NETWORK_INFO_ITEM_MCC, &str);
|
||||
g_message ("%s: MCC: %s", __func__, str ? str : "(none)");
|
||||
|
||||
str = NULL;
|
||||
wmc_result_get_string (result, WMC_CMD_NETWORK_INFO_ITEM_MNC, &str);
|
||||
g_message ("%s: MNC: %s", __func__, str ? str : "(none)");
|
||||
|
||||
wmc_result_unref (result);
|
||||
}
|
||||
|
||||
static const char *
|
||||
mode_to_string (u_int8_t service)
|
||||
{
|
||||
switch (service) {
|
||||
case WMC_NETWORK_MODE_CDMA:
|
||||
return "CDMA/EVDO";
|
||||
case WMC_NETWORK_MODE_GSM_AUTO:
|
||||
return "GSM/UMTS Auto";
|
||||
case WMC_NETWORK_MODE_GPRS_ONLY:
|
||||
return "GSM/GPRS/EDGE only";
|
||||
case WMC_NETWORK_MODE_UMTS_ONLY:
|
||||
return "UMTS/HSPA only";
|
||||
case WMC_NETWORK_MODE_AUTO:
|
||||
return "Auto";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_com_get_global_mode (void *f, void *data)
|
||||
{
|
||||
TestComData *d = data;
|
||||
wmcbool success;
|
||||
char buf[1024];
|
||||
u_int8_t mode;
|
||||
gint len;
|
||||
WmcResult *result;
|
||||
size_t reply_len;
|
||||
|
||||
len = wmc_cmd_get_global_mode_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_get_global_mode_result (buf, reply_len);
|
||||
g_assert (result);
|
||||
|
||||
g_print ("\n");
|
||||
|
||||
mode = 0;
|
||||
wmc_result_get_u8 (result, WMC_CMD_GET_GLOBAL_MODE_ITEM_MODE, &mode);
|
||||
g_message ("%s: Mode: %d (%s)", __func__, mode, mode_to_string (mode));
|
||||
|
||||
wmc_result_unref (result);
|
||||
}
|
||||
|
||||
|
@@ -29,7 +29,9 @@ 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);
|
||||
void test_com_network_info (void *f, void *data);
|
||||
|
||||
void test_com_get_global_mode (void *f, void *data);
|
||||
|
||||
#endif /* TEST_WMC_COM_H */
|
||||
|
||||
|
@@ -102,7 +102,8 @@ 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));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_network_info, data->com_data));
|
||||
g_test_suite_add (suite, TESTCASE (test_com_get_global_mode, data->com_data));
|
||||
}
|
||||
|
||||
result = g_test_run ();
|
||||
|
Reference in New Issue
Block a user