altair-lte: migrate from SubscriptionState to Pco property
In preparation of deprecating the SubscriptionState property in the Modem3gpp interface, this CL updates the altair-lte plugin to update the Pco property in the Modem3gpp interface upon receiving %PCOINFO notification.
This commit is contained in:
@@ -67,6 +67,8 @@ struct _MMBroadbandModemAltairLtePrivate {
|
||||
GRegex *statcm_regex;
|
||||
/* Regex for PCO notifications */
|
||||
GRegex *pcoinfo_regex;
|
||||
|
||||
GList *pco_list;
|
||||
};
|
||||
|
||||
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
|
||||
@@ -413,6 +415,29 @@ modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self,
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
}
|
||||
|
||||
static void
|
||||
simulate_unprovisioned_subscription_pco_update (MMBroadbandModemAltairLte *self)
|
||||
{
|
||||
MMPco *pco;
|
||||
|
||||
/* Simulate a %PCOINFO notification issued to the IMS PDN that indicates an
|
||||
* unprovisioned Verizon SIM. See mm_altair_parse_vendor_pco_info() for the
|
||||
* detailed format of a %PCOINFO response.
|
||||
*
|
||||
* 1,FF00,13018405 is constructed as follows:
|
||||
*
|
||||
* 1: CID for IMS PDN
|
||||
* FF 00: Container ID for the Verizon-specific PCO content
|
||||
* 13 01 84: Binary coded decimal representation of Verizon MCC/MNC 311/084
|
||||
* 05: Value indicating an unprovisioned SIM
|
||||
*/
|
||||
pco = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,FF00,13018405", NULL);
|
||||
g_assert (pco != NULL);
|
||||
self->priv->pco_list = mm_pco_list_add (self->priv->pco_list, pco);
|
||||
mm_iface_modem_3gpp_update_pco_list (MM_IFACE_MODEM_3GPP (self), self->priv->pco_list);
|
||||
g_object_unref (pco);
|
||||
}
|
||||
|
||||
static void
|
||||
run_registration_checks_subscription_state_ready (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res,
|
||||
@@ -449,7 +474,7 @@ run_registration_checks_subscription_state_ready (MMIfaceModem3gpp *self,
|
||||
|
||||
if (g_strcmp0 ("EPS_AND_NON_EPS_SERVICES_NOT_ALLOWED", ceer_response) == 0) {
|
||||
mm_dbg ("Registration failed due to unprovisioned SIM.");
|
||||
mm_iface_modem_3gpp_update_subscription_state (self, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNPROVISIONED);
|
||||
simulate_unprovisioned_subscription_pco_update (MM_BROADBAND_MODEM_ALTAIR_LTE (self));
|
||||
} else {
|
||||
mm_dbg ("Failed to find a better reason for registration failure.");
|
||||
}
|
||||
@@ -1098,162 +1123,31 @@ modem_3gpp_load_operator_name (MMIfaceModem3gpp *self,
|
||||
user_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Subscription State loading (3GPP interface) */
|
||||
|
||||
typedef struct {
|
||||
gchar *pco_info;
|
||||
} LoadSubscriptionStateContext;
|
||||
|
||||
static void
|
||||
load_subscription_state_context_free (LoadSubscriptionStateContext *ctx)
|
||||
{
|
||||
g_free (ctx->pco_info);
|
||||
g_slice_free (LoadSubscriptionStateContext, ctx);
|
||||
}
|
||||
|
||||
static MMModem3gppSubscriptionState
|
||||
altair_vzw_pco_value_to_mm_modem_3gpp_subscription_state (guint pco_value)
|
||||
{
|
||||
switch (pco_value) {
|
||||
case 0:
|
||||
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_PROVISIONED;
|
||||
case 3:
|
||||
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_OUT_OF_DATA;
|
||||
case 5:
|
||||
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNPROVISIONED;
|
||||
default:
|
||||
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static MMModem3gppSubscriptionState
|
||||
modem_3gpp_load_subscription_state_finish (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GError *inner_error = NULL;
|
||||
gssize value;
|
||||
|
||||
value = g_task_propagate_int (G_TASK (res), &inner_error);
|
||||
if (inner_error) {
|
||||
g_propagate_error (error, inner_error);
|
||||
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
|
||||
}
|
||||
return (MMModem3gppSubscriptionState)value;
|
||||
}
|
||||
|
||||
static void
|
||||
altair_get_subscription_state (MMIfaceModem3gpp *self,
|
||||
GTask *task)
|
||||
{
|
||||
LoadSubscriptionStateContext *ctx;
|
||||
guint pco_value = -1;
|
||||
GError *error = NULL;
|
||||
MMModem3gppSubscriptionState subscription_state;
|
||||
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
mm_dbg ("Parsing vendor PCO info: %s", ctx->pco_info);
|
||||
pco_value = mm_altair_parse_vendor_pco_info (ctx->pco_info, &error);
|
||||
if (error) {
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
mm_dbg ("PCO value = %d", pco_value);
|
||||
|
||||
subscription_state = altair_vzw_pco_value_to_mm_modem_3gpp_subscription_state (pco_value);
|
||||
g_task_return_int (task, subscription_state);
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
altair_load_vendor_pco_info_ready (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
LoadSubscriptionStateContext *ctx;
|
||||
const gchar *response;
|
||||
GError *error = NULL;
|
||||
|
||||
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
|
||||
if (error) {
|
||||
mm_dbg ("Failed to load vendor PCO info.");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
g_assert (response);
|
||||
ctx = g_task_get_task_data (task);
|
||||
ctx->pco_info = g_strdup (response);
|
||||
altair_get_subscription_state (self, task);
|
||||
}
|
||||
|
||||
static void
|
||||
modem_3gpp_load_subscription_state (MMIfaceModem3gpp *self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
LoadSubscriptionStateContext *ctx;
|
||||
GTask *task;
|
||||
|
||||
ctx = g_slice_new0 (LoadSubscriptionStateContext);
|
||||
|
||||
task = g_task_new (self, NULL, callback, user_data);
|
||||
g_task_set_task_data (task, ctx, (GDestroyNotify)load_subscription_state_context_free);
|
||||
|
||||
mm_dbg ("Loading vendor PCO info...");
|
||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||
"%PCOINFO?",
|
||||
6,
|
||||
FALSE,
|
||||
(GAsyncReadyCallback)altair_load_vendor_pco_info_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* PCOINFO unsolicited event handler */
|
||||
|
||||
static void
|
||||
altair_get_subscription_state_ready (MMBroadbandModemAltairLte *self,
|
||||
GAsyncResult *res,
|
||||
gpointer *user_data)
|
||||
{
|
||||
GError *error = NULL;
|
||||
MMModem3gppSubscriptionState subscription_state;
|
||||
|
||||
subscription_state = (MMModem3gppSubscriptionState)g_task_propagate_int (G_TASK (res), &error);
|
||||
if (error) {
|
||||
mm_warn ("Couldn't load Subscription State: '%s'", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (subscription_state != MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN)
|
||||
mm_iface_modem_3gpp_update_subscription_state (MM_IFACE_MODEM_3GPP (self), subscription_state);
|
||||
}
|
||||
|
||||
static void
|
||||
altair_pco_info_changed (MMPortSerialAt *port,
|
||||
GMatchInfo *match_info,
|
||||
MMBroadbandModemAltairLte *self)
|
||||
{
|
||||
LoadSubscriptionStateContext *ctx;
|
||||
const gchar *response;
|
||||
GTask *task;
|
||||
const gchar *pco_info;
|
||||
MMPco *pco;
|
||||
GError *error = NULL;
|
||||
|
||||
ctx = g_slice_new0 (LoadSubscriptionStateContext);
|
||||
response = g_match_info_fetch (match_info, 0);
|
||||
ctx->pco_info = g_strdup (response);
|
||||
pco_info = g_match_info_fetch (match_info, 0);
|
||||
|
||||
task = g_task_new (self,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)altair_get_subscription_state_ready,
|
||||
NULL);
|
||||
g_task_set_task_data (task, ctx, (GDestroyNotify)load_subscription_state_context_free);
|
||||
mm_dbg ("Parsing vendor PCO info: %s", pco_info);
|
||||
pco = mm_altair_parse_vendor_pco_info (pco_info, &error);
|
||||
if (error) {
|
||||
mm_warn ("Error parsing vendor PCO info: %s", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
altair_get_subscription_state (MM_IFACE_MODEM_3GPP (self), task);
|
||||
self->priv->pco_list = mm_pco_list_add (self->priv->pco_list, pco);
|
||||
mm_iface_modem_3gpp_update_pco_list (MM_IFACE_MODEM_3GPP (self), self->priv->pco_list);
|
||||
g_object_unref (pco);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -1413,8 +1307,6 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
|
||||
iface->load_operator_code_finish = modem_3gpp_load_operator_code_finish;
|
||||
iface->load_operator_name = modem_3gpp_load_operator_name;
|
||||
iface->load_operator_name_finish = modem_3gpp_load_operator_name_finish;
|
||||
iface->load_subscription_state = modem_3gpp_load_subscription_state;
|
||||
iface->load_subscription_state_finish = modem_3gpp_load_subscription_state_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -141,62 +141,17 @@ mm_altair_parse_cid (const gchar *response, GError **error)
|
||||
/*****************************************************************************/
|
||||
/* %PCOINFO response parser */
|
||||
|
||||
typedef enum {
|
||||
MM_VZW_PCO_PROVISIONED = 0,
|
||||
MM_VZW_PCO_LIMIT_REACHED = 1,
|
||||
MM_VZW_PCO_OUT_OF_DATA = 3,
|
||||
MM_VZW_PCO_UNPROVISIONED = 5
|
||||
} MMVzwPco;
|
||||
|
||||
static guint
|
||||
altair_extract_vzw_pco_value (const gchar *pco_payload, GError **error)
|
||||
{
|
||||
GRegex *regex;
|
||||
GMatchInfo *match_info;
|
||||
guint pco_value = -1;
|
||||
|
||||
/* Extract PCO value from PCO payload.
|
||||
* The PCO value in the VZW network is after the VZW PLMN (MCC+MNC 311-480).
|
||||
*/
|
||||
regex = g_regex_new ("130184(\\d+)", G_REGEX_RAW, 0, NULL);
|
||||
g_assert (regex);
|
||||
if (!g_regex_match_full (regex,
|
||||
pco_payload,
|
||||
strlen (pco_payload),
|
||||
0,
|
||||
0,
|
||||
&match_info,
|
||||
error)) {
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (regex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!g_match_info_matches (match_info) ||
|
||||
!mm_get_uint_from_match_info (match_info, 1, &pco_value))
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Failed to parse PCO value from PCO payload: '%s'",
|
||||
pco_payload);
|
||||
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (regex);
|
||||
|
||||
return pco_value;
|
||||
}
|
||||
|
||||
guint
|
||||
MMPco *
|
||||
mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
|
||||
{
|
||||
GRegex *regex;
|
||||
GMatchInfo *match_info;
|
||||
guint pco_value = -1;
|
||||
MMPco *pco = NULL;
|
||||
gint num_matches;
|
||||
|
||||
if (!pco_info[0])
|
||||
/* No APNs configured, all done */
|
||||
return -1;
|
||||
return NULL;
|
||||
|
||||
/* Expected %PCOINFO response:
|
||||
*
|
||||
@@ -210,7 +165,7 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
|
||||
if (!g_regex_match_full (regex, pco_info, strlen (pco_info), 0, 0, &match_info, error)) {
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (regex);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
num_matches = g_match_info_get_match_count (match_info);
|
||||
@@ -222,13 +177,19 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
|
||||
num_matches);
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (regex);
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (g_match_info_matches (match_info)) {
|
||||
guint pco_cid;
|
||||
gchar *pco_id;
|
||||
gchar *pco_payload;
|
||||
gsize pco_payload_len;
|
||||
gchar *pco_payload_bytes = NULL;
|
||||
gsize pco_payload_bytes_len;
|
||||
guint8 pco_prefix[6];
|
||||
GByteArray *pco_raw;
|
||||
gsize pco_raw_len;
|
||||
|
||||
if (!mm_get_uint_from_match_info (match_info, 1, &pco_cid)) {
|
||||
g_set_error (error,
|
||||
@@ -239,6 +200,12 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
|
||||
break;
|
||||
}
|
||||
|
||||
/* We are only interested in IMS and Internet PDN PCO. */
|
||||
if (pco_cid != MM_ALTAIR_IMS_PDN_CID && pco_cid != MM_ALTAIR_INTERNET_PDN_CID) {
|
||||
g_match_info_next (match_info, error);
|
||||
continue;
|
||||
}
|
||||
|
||||
pco_id = mm_get_string_unquoted_from_match_info (match_info, 3);
|
||||
if (!pco_id) {
|
||||
g_set_error (error,
|
||||
@@ -265,20 +232,64 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
|
||||
break;
|
||||
}
|
||||
|
||||
pco_value = altair_extract_vzw_pco_value (pco_payload, error);
|
||||
pco_payload_len = strlen (pco_payload);
|
||||
if (pco_payload_len % 2 == 0)
|
||||
pco_payload_bytes = mm_utils_hexstr2bin (pco_payload, &pco_payload_bytes_len);
|
||||
|
||||
g_free (pco_payload);
|
||||
|
||||
/* We are only interested in IMS and Internet PDN PCO. */
|
||||
if (pco_cid == MM_ALTAIR_IMS_PDN_CID || pco_cid == MM_ALTAIR_INTERNET_PDN_CID) {
|
||||
if (!pco_payload_bytes) {
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Invalid PCO payload from PCO info: '%s'",
|
||||
pco_info);
|
||||
break;
|
||||
}
|
||||
|
||||
pco_value = -1;
|
||||
g_match_info_next (match_info, error);
|
||||
/* Protocol Configuration Options (PCO) is an information element with an
|
||||
* identifier (IEI) 0x27 and contains between 3 and 253 octets. See 3GPP TS
|
||||
* 24.008 for more details on PCO.
|
||||
*
|
||||
* NOTE: The standard uses one-based indexing, but to better correlate to the
|
||||
* code, zero-based indexing is used in the description hereinafter.
|
||||
*
|
||||
* Octet | Value
|
||||
* --------+--------------------------------------------
|
||||
* 0 | PCO IEI (= 0x27)
|
||||
* 1 | Length of PCO contents (= total length - 2)
|
||||
* 2 | bit 7 : ext
|
||||
* | bit 6 to 3 : spare (= 0b0000)
|
||||
* | bit 2 to 0 : Configuration protocol
|
||||
* 3 to 4 | Element 1 ID
|
||||
* 5 | Length of element 1 contents
|
||||
* 6 to m | Element 1 contents
|
||||
* ... |
|
||||
*/
|
||||
pco_raw_len = sizeof (pco_prefix) + pco_payload_bytes_len;
|
||||
pco_prefix[0] = 0x27;
|
||||
pco_prefix[1] = pco_raw_len - 2;
|
||||
pco_prefix[2] = 0x80;
|
||||
/* Verizon uses element ID 0xFF00 for carrier-specific PCO content. */
|
||||
pco_prefix[3] = 0xFF;
|
||||
pco_prefix[4] = 0x00;
|
||||
pco_prefix[5] = pco_payload_bytes_len;
|
||||
|
||||
pco_raw = g_byte_array_sized_new (pco_raw_len);
|
||||
g_byte_array_append (pco_raw, pco_prefix, sizeof (pco_prefix));
|
||||
g_byte_array_append (pco_raw, (guint8 *)pco_payload_bytes, pco_payload_bytes_len);
|
||||
g_free (pco_payload_bytes);
|
||||
|
||||
pco = mm_pco_new ();
|
||||
mm_pco_set_session_id (pco, pco_cid);
|
||||
mm_pco_set_complete (pco, TRUE);
|
||||
mm_pco_set_data (pco, pco_raw->data, pco_raw->len);
|
||||
g_byte_array_unref (pco_raw);
|
||||
break;
|
||||
}
|
||||
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (regex);
|
||||
|
||||
return pco_value;
|
||||
return pco;
|
||||
}
|
||||
|
@@ -19,6 +19,9 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#define _LIBMM_INSIDE_MM
|
||||
#include <libmm-glib.h>
|
||||
|
||||
/* Bands response parser */
|
||||
GArray *mm_altair_parse_bands_response (const gchar *response);
|
||||
|
||||
@@ -30,6 +33,6 @@ gchar *mm_altair_parse_ceer_response (const gchar *response,
|
||||
guint mm_altair_parse_cid (const gchar *response, GError **error);
|
||||
|
||||
/* %PCOINFO response parser */
|
||||
guint mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error);
|
||||
MMPco *mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error);
|
||||
|
||||
#endif /* MM_MODEM_HELPERS_ALTAIR_H */
|
||||
|
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <locale.h>
|
||||
@@ -59,7 +60,7 @@ typedef struct {
|
||||
} CeerTest;
|
||||
|
||||
static const CeerTest ceer_tests[] = {
|
||||
{ "", "" }, /* Special case, sometimes the response is empty, treat it as a valid response. */
|
||||
{ "", "" }, /* Special case, sometimes the response is empty, treat it as a good response. */
|
||||
{ "+CEER:", "" },
|
||||
{ "+CEER: EPS_AND_NON_EPS_SERVICES_NOT_ALLOWED", "EPS_AND_NON_EPS_SERVICES_NOT_ALLOWED" },
|
||||
{ "+CEER: NO_SUITABLE_CELLS_IN_TRACKING_AREA", "NO_SUITABLE_CELLS_IN_TRACKING_AREA" },
|
||||
@@ -97,45 +98,81 @@ test_parse_cid (void)
|
||||
g_assert (mm_altair_parse_cid ("%CGINFO:blah", NULL) == -1);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test %PCOINFO responses */
|
||||
|
||||
typedef struct {
|
||||
const gchar *pco_info;
|
||||
guint32 session_id;
|
||||
gsize pco_data_size;
|
||||
guint8 pco_data[50];
|
||||
} TestValidPcoInfo;
|
||||
|
||||
static const TestValidPcoInfo good_pco_infos[] = {
|
||||
/* Valid PCO values */
|
||||
{ "%PCOINFO: 1,1,FF00,13018400", 1, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x00 } },
|
||||
{ "%PCOINFO: 1,1,FF00,13018403", 1, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
|
||||
{ "%PCOINFO: 1,1,FF00,13018405", 1, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x05 } },
|
||||
{ "%PCOINFO: 1,3,FF00,13018400", 3, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x00 } },
|
||||
{ "%PCOINFO: 1,3,FF00,13018403", 3, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
|
||||
{ "%PCOINFO: 1,3,FF00,13018405", 3, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x05 } },
|
||||
{ "%PCOINFO:1,FF00,13018400", 1, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x00 } },
|
||||
{ "%PCOINFO:1,FF00,13018403", 1, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
|
||||
{ "%PCOINFO:1,FF00,13018405", 1, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x05 } },
|
||||
/* Different payload */
|
||||
{ "%PCOINFO: 1,3,FF00,130185", 3, 9,
|
||||
{ 0x27, 0x07, 0x80, 0xFF, 0x00, 0x03, 0x13, 0x01, 0x85 } },
|
||||
/* Multiline PCO info */
|
||||
{ "%PCOINFO: 1,2,FF00,13018400\r\n%PCOINFO: 1,3,FF00,13018403", 3, 10,
|
||||
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
|
||||
};
|
||||
|
||||
static const gchar *bad_pco_infos[] = {
|
||||
/* Different container */
|
||||
"%PCOINFO: 1,3,F000,13018401",
|
||||
/* Ingood CID */
|
||||
"%PCOINFO: 1,2,FF00,13018401",
|
||||
/* Bad PCO info */
|
||||
"%PCOINFO: blah,blah,FF00,13018401",
|
||||
/* Bad PCO payload */
|
||||
"%PCOINFO: 1,1,FF00,130184011",
|
||||
};
|
||||
|
||||
static void
|
||||
test_parse_vendor_pco_info (void)
|
||||
{
|
||||
guint pco_value;
|
||||
MMPco *pco;
|
||||
guint i;
|
||||
|
||||
/* Valid PCO values */
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,1,FF00,13018400", NULL);
|
||||
g_assert (pco_value == 0);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,1,FF00,13018403", NULL);
|
||||
g_assert (pco_value == 3);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,1,FF00,13018405", NULL);
|
||||
g_assert (pco_value == 5);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018400", NULL);
|
||||
g_assert (pco_value == 0);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018403", NULL);
|
||||
g_assert (pco_value == 3);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018405", NULL);
|
||||
g_assert (pco_value == 5);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO:1,FF00,13018400", NULL);
|
||||
g_assert (pco_value == 0);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO:1,FF00,13018403", NULL);
|
||||
g_assert (pco_value == 3);
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO:1,FF00,13018405", NULL);
|
||||
g_assert (pco_value == 5);
|
||||
/* Different container */
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,F000,13018401", NULL);
|
||||
g_assert (pco_value == -1);
|
||||
/* Invalid CID */
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,2,FF00,13018401", NULL);
|
||||
g_assert (pco_value == -1);
|
||||
/* Different payload */
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018501", NULL);
|
||||
g_assert (pco_value == -1);
|
||||
/* Bad PCO info */
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: blah,blah,FF00,13018401", NULL);
|
||||
g_assert (pco_value == -1);
|
||||
/* Multiline PCO info */
|
||||
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,2,FF00,13018400\r\n%PCOINFO: 1,3,FF00,13018403", NULL);
|
||||
g_assert (pco_value == 3);
|
||||
for (i = 0; i < G_N_ELEMENTS (good_pco_infos); ++i) {
|
||||
const guint8 *pco_data;
|
||||
gsize pco_data_size;
|
||||
|
||||
pco = mm_altair_parse_vendor_pco_info (good_pco_infos[i].pco_info, NULL);
|
||||
g_assert (pco != NULL);
|
||||
g_assert_cmpuint (mm_pco_get_session_id (pco), ==, good_pco_infos[i].session_id);
|
||||
g_assert (mm_pco_is_complete (pco));
|
||||
pco_data = mm_pco_get_data (pco, &pco_data_size);
|
||||
g_assert (pco_data != NULL);
|
||||
g_assert_cmpuint (pco_data_size, ==, good_pco_infos[i].pco_data_size);
|
||||
g_assert_cmpmem (pco_data, pco_data_size,
|
||||
good_pco_infos[i].pco_data, good_pco_infos[i].pco_data_size);
|
||||
g_object_unref (pco);
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (bad_pco_infos); ++i) {
|
||||
pco = mm_altair_parse_vendor_pco_info (bad_pco_infos[i], NULL);
|
||||
g_assert (pco == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
Reference in New Issue
Block a user