Index: plugins/modemmgr.c |
diff --git a/plugins/modemmgr.c b/plugins/modemmgr.c |
index 05b9c7b30b49cc9df9b17b6c8b6d10886b1b7694..88e06622ddbb5c9d83f0cd74211a8287c7f78ecd 100644 |
--- a/plugins/modemmgr.c |
+++ b/plugins/modemmgr.c |
@@ -159,8 +159,6 @@ enum modem_event { |
ME_CONNECT_FAILED, |
ME_DISCONNECT_SUCCEEDED, |
ME_DISCONNECT_FAILED, |
- ME_GET_STATUS_SUCCEEDED, |
- ME_GET_STATUS_FAILED, |
ME_GET_SIGNALQUALITY_SUCCEEDED, |
ME_GET_SIGNALQUALITY_FAILED, |
ME_GET_SERVING_SYSTEM_SUCCEEDED, |
@@ -235,6 +233,8 @@ struct modem_data { |
char *operator_name; /* GSM: operator name */ |
char *unlock_required; /* GSM: modem needs to be unlocked? */ |
guint unlock_retries; /* GSM: # unlock retries allowed */ |
+ enum connman_network_cellular_technology |
+ network_technology; /* EDGE, UMTS, etc. */ |
char *olp_url; /* online payment url */ |
char *usage_url; /* data usage url */ |
char *device; |
@@ -328,10 +328,18 @@ static void modem_get_info_task(struct modem_data *); |
static void modem_connect_task(struct modem_data *); |
static void modem_disconnect_task(struct modem_data *); |
static void modem_get_properties_task(struct modem_data *); |
+static void modem_get_gsm_properties_task(struct modem_data *modem); |
static void modem_create_device_task(struct modem_data *); |
static void modem_get_registration_state_task(struct modem_data *); |
static void modem_register_task(struct modem_data *); |
+static struct modem_task_work initialize_modem_work = { |
+ "initialize", { |
+ modem_get_properties_task, |
+ modem_get_identifiers_task, |
+ modem_create_device_task, |
+ 0}}; |
+ |
static struct modem_task_work enable_cdma_modem_work = { |
"enable_cdma", { |
modem_enable_task, |
@@ -351,6 +359,7 @@ static struct modem_task_work enable_gsm_modem_work = { |
modem_enable_task, |
modem_register_task, |
modem_get_status_task, |
+ modem_get_gsm_properties_task, |
modem_get_info_task, |
modem_get_registration_state_task, |
0}}; |
@@ -369,13 +378,6 @@ static struct modem_task_work disable_modem_work = { |
modem_disable_task, |
0}}; |
-static struct modem_task_work initialize_modem_work = { |
- "initialize", { |
- modem_get_properties_task, |
- modem_get_identifiers_task, |
- modem_create_device_task, |
- 0}}; |
- |
static struct modem_task_work connect_modem_work = { |
"connect", { |
modem_connect_task, |
@@ -767,10 +769,10 @@ static struct connman_network *create_network(struct modem_data *modem) |
_DBG_MODEMMGR("path %s", modem->dbus_path); |
- if (modem->operator_name != NULL) { |
- net_display_name = modem->operator_name; |
- } else if (modem->configured_carrier != NULL) { |
+ if (modem->configured_carrier != NULL) { |
net_display_name = modem->configured_carrier; |
+ } else if (modem->operator_name != NULL) { |
+ net_display_name = modem->operator_name; |
} else { |
snprintf(namebuf, sizeof(namebuf), "%s%d", NETWORK_NAME, netid); |
netid++; |
@@ -818,8 +820,11 @@ static struct connman_network *create_network(struct modem_data *modem) |
connman_network_set_protocol(network, CONNMAN_NETWORK_PROTOCOL_IP); |
connman_network_set_name(network, net_display_name); |
connman_network_set_scangen(network, ++modem->scangen); |
- connman_network_set_strength(network, modem->signal_strength); |
connman_network_set_group(network, "cellular_service_group"); |
+ connman_network_set_strength(network, modem->signal_strength); |
+ connman_network_set_registration_info(network, |
+ modem->network_technology, |
+ CONNMAN_NETWORK_ROAMING_STATE_UNKNOWN); |
if (modem->type == MM_MODEM_TYPE_CDMA) { |
connman_network_set_activation_state(network, |
modem->activation_state, |
@@ -1344,6 +1349,18 @@ static void modem_create_device_task(struct modem_data *modem) |
if (modem->imsi != NULL) |
connman_device_set_string(device, "Cellular.IMSI", |
modem->imsi); |
+ switch (modem->type) { |
+ case MM_MODEM_TYPE_CDMA: |
+ /* |
+ * TODO(jglasgow): phone numnber should come |
+ * from configuration information |
+ */ |
+ modem->phone_number = g_strdup("#777"); |
+ break; |
+ case MM_MODEM_TYPE_GSM: |
+ modem->phone_number = g_strdup("*99#"); |
+ break; |
+ } |
/* We are now done with the creation, and we leave modem DISABLED */ |
modem_task_completed(modem); |
@@ -1462,8 +1479,10 @@ static void modem_get_gsm_registration_state_reply(DBusPendingCall *call, void * |
&modem->gsm_registration_state); |
dbus_message_iter_next(&values_iter); |
dbus_message_iter_get_basic(&values_iter, &operator_code); |
+ g_free(modem->operator_code); |
modem->operator_code = g_strdup(operator_code); |
dbus_message_iter_next(&values_iter); |
+ g_free(modem->operator_name); |
dbus_message_iter_get_basic(&values_iter, &operator_name); |
modem->operator_name = g_strdup(operator_name); |
dbus_message_iter_next(&values_iter); |
@@ -1540,7 +1559,7 @@ static void modem_get_signal_quality_reply( |
* modem_get_signal_quality |
* @modem: modem object |
* |
- * Send a DBUS message to find the registration state/info of a modem |
+ * Send a DBUS message to find the signal quality of a modem |
*/ |
static void modem_get_signal_quality(struct modem_data *modem) |
{ |
@@ -1570,7 +1589,23 @@ static void modem_get_signal_quality(struct modem_data *modem) |
} |
+typedef void (*prop_reply_fn)(DBusPendingCall *, void *); |
+ |
+static void modem_get_properties(struct modem_data *modem, |
+ const char *interface, |
+ prop_reply_fn reply_fn) |
+{ |
+ modem_dbus_send_message(modem, |
+ MM_DBUS_PROPERTIES_INTERFACE, DBUS_METHOD_GETALL, |
+ reply_fn, ME_GET_PROPERTIES_FAILED, |
+ DBUS_TYPE_STRING, &interface, |
+ DBUS_TYPE_INVALID); |
+} |
+ |
static void modem_get_properties_reply(DBusPendingCall *call, void *user_data); |
+static void modem_get_gsm_properties_reply(DBusPendingCall *call, void *user_data); |
+static void modem_get_cdma_properties_reply(DBusPendingCall *call, void *user_data); |
+ |
/** |
* modem_get_properties_task: |
* @modem: modem object |
@@ -1579,13 +1614,16 @@ static void modem_get_properties_reply(DBusPendingCall *call, void *user_data); |
*/ |
static void modem_get_properties_task(struct modem_data *modem) |
{ |
- const char *interface = MM_MODEM_INTERFACE; |
+ modem_get_properties(modem, |
+ MM_MODEM_INTERFACE, |
+ modem_get_properties_reply); |
+} |
- modem_dbus_send_message(modem, |
- MM_DBUS_PROPERTIES_INTERFACE, DBUS_METHOD_GETALL, |
- modem_get_properties_reply, ME_GET_PROPERTIES_FAILED, |
- DBUS_TYPE_STRING, &interface, |
- DBUS_TYPE_INVALID); |
+static void modem_get_gsm_properties_task(struct modem_data *modem) |
+{ |
+ modem_get_properties(modem, |
+ MM_MODEM_GSM_NETWORK_INTERFACE, |
+ modem_get_gsm_properties_reply); |
} |
static connman_bool_t check_property(const char *wanted_key, |
@@ -1677,19 +1715,95 @@ static connman_bool_t modem_dbus_extract_string(const char *wanted_key, |
return FALSE; |
} |
+typedef gint (*property_handler)(struct modem_data *, |
+ const char *, |
+ DBusMessageIter *); |
+ |
+static enum connman_network_cellular_technology |
+ mm_gsm_technology_to_connman_technology(); |
+ |
+static gint handle_modem_property(struct modem_data *modem, |
+ const char *key, |
+ DBusMessageIter *value) |
+{ |
+ gint extract_err = 0; |
+ |
+ if (modem_dbus_extract_string( |
+ "Device", key, value, &modem->device, |
+ &extract_err)) |
+ return extract_err; |
+ if (modem_dbus_extract_string( |
+ "MasterDevice", key, value, |
+ &modem->master_device, &extract_err)) |
+ return extract_err; |
+ if (modem_dbus_extract_string( |
+ "Driver", key, value, &modem->driver, |
+ &extract_err)) |
+ return extract_err; |
+ if (modem_dbus_extract_uint32( |
+ "Type", key, value, |
+ (guint *)&modem->type, |
+ &extract_err)) |
+ return extract_err; |
+ if (modem_dbus_extract_uint32( |
+ "IpMethod", key, value, |
+ (guint *)&modem->ip_method, |
+ &extract_err)) |
+ return extract_err; |
+ if (modem_dbus_extract_string( |
+ "UnlockRequired", key, value, |
+ &modem->unlock_required, &extract_err)) |
+ return extract_err; |
+ if (modem_dbus_extract_uint32( |
+ "UnlockRetries", key, value, |
+ &modem->unlock_retries, &extract_err)) |
+ return extract_err; |
+ return extract_err; |
+} |
+ |
+static gint handle_cdma_property(struct modem_data *modem, |
+ const char *key, |
+ DBusMessageIter *value) |
+{ |
+ gint extract_err = 0; |
+ |
+ modem_dbus_extract_string("MEID", key, value, &modem->meid, |
+ &extract_err); |
+ return extract_err; |
+} |
+ |
+static gint handle_gsm_property(struct modem_data *modem, |
+ const char *key, |
+ DBusMessageIter *value) |
+{ |
+ guint technology; |
+ gint extract_err = 0; |
+ |
+ if (modem_dbus_extract_uint32("AccessTechnology", key, value, |
+ &technology, &extract_err)) { |
+ modem->network_technology = |
+ mm_gsm_technology_to_connman_technology(technology); |
+ } |
+ return extract_err; |
+} |
+ |
/** |
- * modem_get_properties_reply: |
- * @modem: modem object |
+ * handle_get_properties_reply: |
* |
- * Process the reply from the DBUS Get (property) call |
+ * Process the reply from the DBUS Get (property) call, using |
+ * the supplied property handler function to look for a specific |
+ * set of properties. |
*/ |
-static void modem_get_properties_reply(DBusPendingCall *call, void *user_data) |
+static void handle_get_properties_reply(DBusPendingCall *call, void *user_data, |
+ property_handler prop_handler) |
{ |
struct modem_data *modem = (struct modem_data *)user_data; |
DBusMessage *reply; |
DBusError error; |
gint extract_err = 0; |
enum modem_event event = ME_GET_PROPERTIES_FAILED; |
+ DBusMessageIter array, dict; |
+ gint type; |
_DBG_MODEMMGR("modem %s", modem->dbus_path); |
@@ -1707,13 +1821,10 @@ static void modem_get_properties_reply(DBusPendingCall *call, void *user_data) |
goto done; |
} |
- DBusMessageIter array, dict; |
- |
if (dbus_message_iter_init(reply, &array) == FALSE) { |
_DBG_MODEMMGR("Could not iterate on reply %s", modem->dbus_path); |
goto done; |
} |
- gint type; |
if ((type = dbus_message_iter_get_arg_type(&array)) != DBUS_TYPE_ARRAY) { |
_DBG_MODEMMGR("Expected array, got %x", type); |
goto done; |
@@ -1733,70 +1844,35 @@ static void modem_get_properties_reply(DBusPendingCall *call, void *user_data) |
dbus_message_iter_recurse(&entry, &value); |
_DBG_MODEMMGR("Saw key: %s", key); |
- if (modem_dbus_extract_string( |
- "Device", key, &value, &modem->device, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "MasterDevice", key, &value, |
- &modem->master_device, &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "Driver", key, &value, &modem->driver, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_uint32( |
- "Type", key, &value, |
- (guint *)&modem->type, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_uint32( |
- "IpMethod", key, &value, |
- (guint *)&modem->ip_method, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "MEID", key, &value, &modem->meid, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "UnlockRequired", key, &value, |
- &modem->unlock_required, &extract_err)) |
- goto next; |
- if (modem_dbus_extract_uint32( |
- "UnlockRetries", key, &value, |
- &modem->unlock_retries, &extract_err)) |
- goto next; |
- /* |
- * TODO(rochberg): do we want to verify that all |
- * fields have appeared? |
- */ |
- next: |
+ extract_err = prop_handler(modem, key, &value); |
+ |
dbus_message_iter_next(&dict); |
} |
if (extract_err == 0) { |
event = ME_GET_PROPERTIES_SUCCEEDED; |
- |
- switch (modem->type) { |
- case MM_MODEM_TYPE_CDMA: |
- /* |
- * TODO(jglasgow): phone numnber should come |
- * from configuration information |
- */ |
- modem->phone_number = g_strdup("#777"); |
- break; |
- case MM_MODEM_TYPE_GSM: |
- modem->phone_number = g_strdup("*99#"); |
- break; |
- } |
} |
done: |
- dbus_error_free(&error); |
dbus_message_unref(reply); |
done_no_reply: |
+ dbus_error_free(&error); |
modem_handle_event(modem, event); |
} |
+static void modem_get_properties_reply(DBusPendingCall *call, void *user_data) |
+{ |
+ handle_get_properties_reply(call, user_data, handle_modem_property); |
+} |
+ |
+void modem_get_gsm_properties_reply(DBusPendingCall *call, void *user_data) |
+{ |
+ handle_get_properties_reply(call, user_data, handle_gsm_property); |
+} |
+ |
+void modem_get_cdma_properties_reply(DBusPendingCall *call, void *user_data) |
+{ |
+ handle_get_properties_reply(call, user_data, handle_cdma_property); |
+} |
+ |
static void modem_get_gsm_identifier_reply(DBusPendingCall *call, void *user_data); |
/** |
@@ -1808,18 +1884,11 @@ static void modem_get_gsm_identifier_reply(DBusPendingCall *call, void *user_dat |
*/ |
static void modem_get_identifiers_task(struct modem_data *modem) |
{ |
- const char *interface; |
- |
switch (modem->type) { |
case MM_MODEM_TYPE_CDMA: |
- interface = MM_MODEM_CDMA_INTERFACE; |
- modem_dbus_send_message(modem, |
- MM_DBUS_PROPERTIES_INTERFACE, |
- DBUS_METHOD_GETALL, |
- modem_get_properties_reply, |
- ME_GET_PROPERTIES_FAILED, |
- DBUS_TYPE_STRING, &interface, |
- DBUS_TYPE_INVALID); |
+ modem_get_properties(modem, |
+ MM_MODEM_CDMA_INTERFACE, |
+ modem_get_cdma_properties_reply); |
break; |
case MM_MODEM_TYPE_GSM: |
/* We first request the IMEI, then the IMSI */ |
@@ -1923,21 +1992,14 @@ static void modem_get_status_task(struct modem_data *modem) |
MM_MODEM_SIMPLE_INTERFACE, |
MM_MODEM_SIMPLE_METHOD_GETSTATUS, |
modem_get_status_reply, |
- ME_GET_STATUS_FAILED, |
+ ME_GET_PROPERTIES_FAILED, |
DBUS_TYPE_INVALID); |
} |
-/** |
- * modem_get_status_reply: |
- * @modem: modem object |
- * |
- * Process the reply from the DBUS GetStatus call |
- */ |
-static void modem_get_status_reply(DBusPendingCall *call, void *user_data) |
+static gint handle_status_property(struct modem_data *modem, |
+ const char *key, |
+ DBusMessageIter *value) |
{ |
- struct modem_data *modem = (struct modem_data *)user_data; |
- DBusMessage *reply; |
- DBusError error; |
dbus_uint32_t modem_state = MM_MODEM_STATE_UNKNOWN; |
dbus_uint32_t mm_activation_state = |
MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED; |
@@ -1951,167 +2013,101 @@ static void modem_get_status_reply(DBusPendingCall *call, void *user_data) |
char *firmware_revision = NULL; |
char *olp_url = NULL; |
char *usage_url = NULL; |
- enum modem_event event = ME_GET_STATUS_FAILED; |
dbus_uint16_t prl_version = 0; |
- |
- _DBG_MODEMMGR("modem %s", modem->dbus_path); |
- |
- dbus_error_init(&error); |
- |
- reply = dbus_pending_call_steal_reply(call); |
- if (reply == NULL) { |
- CONNMAN_ERROR("Failed steal reply"); |
- goto done_no_reply; |
- } |
- |
- if (dbus_set_error_from_message(&error, reply)) { |
- CONNMAN_ERROR("DBus Error: %s:%s", |
- error.name, error.message); |
- goto done; |
- } |
- |
- DBusMessageIter array, dict; |
- |
- if (dbus_message_iter_init(reply, &array) == FALSE) { |
- _DBG_MODEMMGR("Could not iterate on reply %s", modem->dbus_path); |
- goto done; |
- } |
- gint type; |
- if ((type = dbus_message_iter_get_arg_type(&array)) != DBUS_TYPE_ARRAY) { |
- _DBG_MODEMMGR("Expected array, got %x", type); |
- goto done; |
- } |
- |
- dbus_message_iter_recurse(&array, &dict); |
gint extract_err = 0; |
- while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY && |
- extract_err == 0) { |
- DBusMessageIter entry, value; |
- const char *key; |
- |
- dbus_message_iter_recurse(&dict, &entry); |
- dbus_message_iter_get_basic(&entry, &key); |
- |
- dbus_message_iter_next(&entry); |
- dbus_message_iter_recurse(&entry, &value); |
- _DBG_MODEMMGR("Saw status key: %s", key); |
- |
- if (modem_dbus_extract_string( |
- "carrier", key, &value, &carrier, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "meid", key, &value, &meid, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "imei", key, &value, &imei, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "imsi", key, &value, &imsi, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "esn", key, &value, &esn, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "mdn", key, &value, &mdn, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "min", key, &value, &min, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "payment_url", key, &value, &olp_url, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_string( |
- "usage_url", key, &value, &usage_url, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_uint16( |
- "prl_version", key, &value, &prl_version, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_uint32( |
- "state", key, &value, &modem_state, |
- &extract_err)) |
- goto next; |
- if (modem_dbus_extract_uint32( |
- "activation_state", key, &value, |
- &mm_activation_state, &extract_err)) { |
- modem->activation_state = |
- convert_activation_state(mm_activation_state); |
- goto next; |
- } |
- if (modem_dbus_extract_string( |
- "firmware_revision", key, &value, &firmware_revision, |
- &extract_err)) |
- goto next; |
- next: |
- dbus_message_iter_next(&dict); |
- } |
- if (extract_err == 0) { |
- event = ME_GET_STATUS_SUCCEEDED; |
- } |
- /* |
- * TODO(ers) All of the following can now be done inline as |
- * we extract each property from the dictionary, now that |
- * the extract functions return a boolean indicating whether |
- * the property was extracted. |
- */ |
- if (carrier != NULL && modem->configured_carrier == NULL) { |
+ if (modem_dbus_extract_string( |
+ "carrier", key, value, &carrier, |
+ &extract_err)) { |
modem->configured_carrier = g_strdup(carrier); |
- connman_device_set_string(modem->cm_device, "Cellular.Carrier", |
+ connman_device_set_string(modem->cm_device, |
+ "Cellular.Carrier", |
modem->configured_carrier); |
- } |
- if (meid != NULL && modem->meid == NULL) { |
+ } else if (modem_dbus_extract_string( |
+ "meid", key, value, &meid, |
+ &extract_err)) { |
+ g_free(modem->meid); |
modem->meid = g_strdup(meid); |
- connman_device_set_string(modem->cm_device, "Cellular.MEID", |
+ connman_device_set_string(modem->cm_device, |
+ "Cellular.MEID", |
modem->meid); |
- } |
- if (imei != NULL && modem->imei == NULL) { |
+ } else if (modem_dbus_extract_string( |
+ "imei", key, value, &imei, |
+ &extract_err)) { |
+ g_free(modem->imei); |
modem->imei = g_strdup(imei); |
- connman_device_set_string(modem->cm_device, "Cellular.IMEI", |
+ connman_device_set_string(modem->cm_device, |
+ "Cellular.IMEI", |
modem->imei); |
- } |
- if (imsi != NULL && modem->imsi == NULL) { |
+ } else if (modem_dbus_extract_string( |
+ "imsi", key, value, &imsi, |
+ &extract_err)) { |
+ g_free(modem->imsi); |
modem->imsi = g_strdup(imsi); |
- connman_device_set_string(modem->cm_device, "Cellular.IMSI", |
+ connman_device_set_string(modem->cm_device, |
+ "Cellular.IMSI", |
modem->imsi); |
- } |
- if (esn != NULL) |
- connman_device_set_string(modem->cm_device, "Cellular.ESN", esn); |
- if (mdn != NULL) |
- connman_device_set_string(modem->cm_device, "Cellular.MDN", mdn); |
- if (min != NULL) |
- connman_device_set_string(modem->cm_device, "Cellular.MIN", min); |
- if (olp_url != NULL) { |
+ } else if (modem_dbus_extract_string( |
+ "esn", key, value, &esn, |
+ &extract_err)) { |
+ connman_device_set_string(modem->cm_device, |
+ "Cellular.ESN", esn); |
+ } else if (modem_dbus_extract_string( |
+ "mdn", key, value, &mdn, |
+ &extract_err)) { |
+ connman_device_set_string(modem->cm_device, |
+ "Cellular.MDN", mdn); |
+ } else if (modem_dbus_extract_string( |
+ "min", key, value, &min, |
+ &extract_err)) { |
+ connman_device_set_string(modem->cm_device, |
+ "Cellular.MIN", min); |
+ } else if (modem_dbus_extract_string( |
+ "payment_url", key, value, &olp_url, |
+ &extract_err)) { |
g_free(modem->olp_url); |
modem->olp_url = g_strdup(olp_url); |
- } |
- if (usage_url != NULL) { |
+ } else if (modem_dbus_extract_string( |
+ "usage_url", key, value, &usage_url, |
+ &extract_err)) { |
g_free(modem->usage_url); |
modem->usage_url = g_strdup(usage_url); |
- } |
- if (firmware_revision != NULL) |
+ } else if (modem_dbus_extract_uint16( |
+ "prl_version", key, value, &prl_version, |
+ &extract_err)) { |
+ connman_device_set_prl_version(modem->cm_device, |
+ prl_version); |
+ } else if (modem_dbus_extract_uint32( |
+ "state", key, value, &modem_state, |
+ &extract_err)) { |
+ if (modem_state == MM_MODEM_STATE_CONNECTED) { |
+ _DBG_MODEMMGR("modem starts out in CONNECTED state"); |
+ modem->connect_needed = TRUE; |
+ } |
+ } else if (modem_dbus_extract_uint32( |
+ "activation_state", key, value, |
+ &mm_activation_state, &extract_err)) { |
+ modem->activation_state = |
+ convert_activation_state(mm_activation_state); |
+ } else if (modem_dbus_extract_string( |
+ "firmware_revision", key, value, &firmware_revision, |
+ &extract_err)) { |
connman_device_set_string(modem->cm_device, |
"Cellular.FirmwareRevision", |
firmware_revision); |
- connman_device_set_prl_version(modem->cm_device, prl_version); |
- if (modem_state == MM_MODEM_STATE_CONNECTED) { |
- _DBG_MODEMMGR("modem starts out in CONNECTED state"); |
- modem->connect_needed = TRUE; |
} |
-done: |
- dbus_error_free(&error); |
- dbus_message_unref(reply); |
-done_no_reply: |
- modem_handle_event(modem, event); |
+ return extract_err; |
+} |
+ |
+/** |
+ * modem_get_status_reply: |
+ * @modem: modem object |
+ * |
+ * Process the reply from the DBUS GetStatus call |
+ */ |
+static void modem_get_status_reply(DBusPendingCall *call, void *user_data) |
+{ |
+ handle_get_properties_reply(call, user_data, handle_status_property); |
} |
static void modem_get_info_reply(DBusPendingCall *call, void *user_data) |
@@ -2218,6 +2214,44 @@ static enum connman_network_cellular_roaming_state mm_cdma_roaming_to_connman_ro |
return CONNMAN_NETWORK_ROAMING_STATE_UNKNOWN; |
} |
+static enum connman_network_cellular_roaming_state mm_gsm_regstate_to_connman_roaming( |
+ guint mm_gsm_regstate) |
+{ |
+ switch (mm_gsm_regstate) { |
+ case MM_MODEM_GSM_NETWORK_REG_STATUS_HOME: |
+ return CONNMAN_NETWORK_ROAMING_STATE_HOME; |
+ case MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING: |
+ return CONNMAN_NETWORK_ROAMING_STATE_ROAMING; |
+ default: |
+ return CONNMAN_NETWORK_ROAMING_STATE_UNKNOWN; |
+ } |
+} |
+ |
+static enum connman_network_cellular_technology mm_gsm_technology_to_connman_technology( |
+ guint mm_technology) { |
+ switch (mm_technology) { |
+ case MM_MODEM_GSM_ACCESS_TECH_GSM: |
+ case MM_MODEM_GSM_ACCESS_TECH_GSM_COMPACT: |
+ return CONNMAN_NETWORK_TECHNOLOGY_GSM; |
+ break; |
+ case MM_MODEM_GSM_ACCESS_TECH_GPRS: |
+ return CONNMAN_NETWORK_TECHNOLOGY_GPRS; |
+ break; |
+ case MM_MODEM_GSM_ACCESS_TECH_EDGE: |
+ return CONNMAN_NETWORK_TECHNOLOGY_EDGE; |
+ break; |
+ case MM_MODEM_GSM_ACCESS_TECH_UMTS: |
+ return CONNMAN_NETWORK_TECHNOLOGY_UMTS; |
+ break; |
+ case MM_MODEM_GSM_ACCESS_TECH_HSDPA: |
+ case MM_MODEM_GSM_ACCESS_TECH_HSUPA: |
+ case MM_MODEM_GSM_ACCESS_TECH_HSPA: |
+ return CONNMAN_NETWORK_TECHNOLOGY_HSPA; |
+ break; |
+ } |
+ return CONNMAN_NETWORK_TECHNOLOGY_UNKNOWN; |
+} |
+ |
/** |
* Return TRUE if the modem is registered on a network |
* |
@@ -2288,7 +2322,11 @@ static int modem_registration_state_change(struct modem_data *modem) |
connman_network_set_string(network, |
"Network Type", |
"GSM"); |
- /* TODO(ers) connman_network_set_registration_info */ |
+ connman_network_set_registration_info( |
+ network, |
+ modem->network_technology, |
+ mm_gsm_regstate_to_connman_roaming( |
+ modem->gsm_registration_state)); |
} |
connman_network_set_available(network, TRUE); |
connman_network_set_scangen(network, ++modem->scangen); |
@@ -2417,14 +2455,12 @@ static void modem_handle_event(struct modem_data *modem, |
case ME_DISABLE_SUCCEEDED: |
case ME_GETINFO_SUCCEEDED: |
case ME_GET_PROPERTIES_SUCCEEDED: |
- case ME_GET_STATUS_SUCCEEDED: |
modem_task_run(modem); |
return; |
case ME_ENABLE_FAILED: |
case ME_DISABLE_FAILED: |
case ME_GETINFO_FAILED: |
case ME_GET_PROPERTIES_FAILED: |
- case ME_GET_STATUS_FAILED: |
case ME_CREATE_DEVICE_FAILED: |
modem->state = MODEM_STATE_FAILED; |
modem_task_completed(modem); |
@@ -2539,10 +2575,10 @@ static void modem_handle_event(struct modem_data *modem, |
case ME_SIGNAL_QUALITY_CHANGED: |
modem_update_signal_quality(modem); |
return; |
- case ME_GET_STATUS_SUCCEEDED: |
- case ME_GET_STATUS_FAILED: |
case ME_GETINFO_SUCCEEDED: |
case ME_GETINFO_FAILED: |
+ case ME_GET_PROPERTIES_SUCCEEDED: |
+ case ME_GET_PROPERTIES_FAILED: |
modem_task_run(modem); |
return; |
default: |
@@ -2606,10 +2642,10 @@ static void modem_handle_event(struct modem_data *modem, |
case ME_SIGNAL_QUALITY_CHANGED: |
modem_update_signal_quality(modem); |
return; |
- case ME_GET_STATUS_SUCCEEDED: |
- case ME_GET_STATUS_FAILED: |
case ME_GETINFO_SUCCEEDED: |
case ME_GETINFO_FAILED: |
+ case ME_GET_PROPERTIES_SUCCEEDED: |
+ case ME_GET_PROPERTIES_FAILED: |
modem_task_run(modem); |
return; |
default: |
@@ -2699,8 +2735,6 @@ static const char *eventToString(enum modem_event event) |
case ME_CONNECT_FAILED: return "CONNECT_FAILED"; |
case ME_DISCONNECT_SUCCEEDED: return "DISCONNECT_SUCCEEDED"; |
case ME_DISCONNECT_FAILED: return "DISCONNECT_FAILED"; |
- case ME_GET_STATUS_SUCCEEDED: return "GET_STATUS_SUCCEEDED"; |
- case ME_GET_STATUS_FAILED: return "GET_STATUS_FAILED"; |
case ME_GET_SIGNALQUALITY_SUCCEEDED: return "GET_SIGNALQUALITY_SUCCEEDED"; |
case ME_GET_SIGNALQUALITY_FAILED: return "GET_SIGNALQUALITY_FAILED"; |
case ME_GET_SERVING_SYSTEM_SUCCEEDED: return "GET_SERVING_SYSTEM_SUCCEEDED"; |
@@ -2812,6 +2846,7 @@ static void add_modem(const char *owner, const char *path) |
modem->type = 0; |
modem->state = MODEM_STATE_UNINITIALIZED; |
modem->signal_strength = 0; |
+ modem->network_technology = CONNMAN_NETWORK_TECHNOLOGY_UNKNOWN; |
/* Set IP method to an invalid type */ |
modem->ip_method = -1; |
@@ -2843,8 +2878,6 @@ static void remove_modem(gpointer data) |
connman_device_unref(modem->cm_device); |
} |
g_free(modem->owner); |
- g_free(modem->operator_name); |
- g_free(modem->operator_code); |
g_free(modem->dbus_path); |
g_free(modem->phone_number); |
g_free(modem->olp_url); |
@@ -2855,6 +2888,7 @@ static void remove_modem(gpointer data) |
g_free(modem->network_dbus_name); |
g_free(modem->configured_carrier); |
g_free(modem->operator_name); |
+ g_free(modem->operator_code); |
g_free(modem->meid); |
g_free(modem->imei); |
g_free(modem->imsi); |
@@ -3142,9 +3176,11 @@ static void gsm_registration_state_changed( |
dbus_message_iter_get_basic(&iter, &modem->gsm_registration_state); |
dbus_message_iter_next(&iter); |
dbus_message_iter_get_basic(&iter, &operator_code); |
+ g_free(modem->operator_code); |
modem->operator_code = g_strdup(operator_code); |
dbus_message_iter_next(&iter); |
dbus_message_iter_get_basic(&iter, &operator_name); |
+ g_free(modem->operator_name); |
modem->operator_name = g_strdup(operator_name); |
dbus_message_iter_next(&iter); |
@@ -3268,6 +3304,59 @@ static void modem_activation_state_changed(struct modem_data *modem, |
convert_activation_error(mm_error)); |
} |
+static void mm_properties_changed(struct modem_data *modem, |
+ DBusMessage *msg) |
+{ |
+ DBusMessageIter iter; |
+ DBusMessageIter dict; |
+ char *interface; |
+ guint technology; |
+ struct connman_network *network = get_network(modem); |
+ |
+ if (network == NULL) |
+ return; |
+ |
+ dbus_message_iter_init(msg, &iter); |
+ |
+ dbus_message_iter_get_basic(&iter, &interface); |
+ dbus_message_iter_next(&iter); |
+ _DBG_MODEMMGR("MmPropertiesChanged for interface %s", interface); |
+ |
+ gint type; |
+ if ((type = dbus_message_iter_get_arg_type(&iter)) != DBUS_TYPE_ARRAY) { |
+ _DBG_MODEMMGR("Expected array, got %x", type); |
+ return; |
+ } |
+ |
+ dbus_message_iter_recurse(&iter, &dict); |
+ gint extract_err = 0; |
+ |
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY && |
+ extract_err == 0) { |
+ DBusMessageIter entry, value; |
+ const char *key; |
+ |
+ dbus_message_iter_recurse(&dict, &entry); |
+ dbus_message_iter_get_basic(&entry, &key); |
+ |
+ dbus_message_iter_next(&entry); |
+ dbus_message_iter_recurse(&entry, &value); |
+ _DBG_MODEMMGR(" Saw property key: %s", key); |
+ |
+ if (modem_dbus_extract_uint32( |
+ "AccessTechnology", key, &value, |
+ &technology, &extract_err)) { |
+ _DBG_MODEMMGR(" value: %u", technology); |
+ enum connman_network_cellular_technology tech = |
+ mm_gsm_technology_to_connman_technology(technology); |
+ connman_network_set_registration_info( |
+ network, tech, |
+ CONNMAN_NETWORK_ROAMING_STATE_UNKNOWN); |
+ } |
+ dbus_message_iter_next(&dict); |
+ } |
+} |
+ |
static DBusHandlerResult modemmgr_filter(DBusConnection *conn, |
DBusMessage *msg, |
void *data) |
@@ -3280,17 +3369,19 @@ static DBusHandlerResult modemmgr_filter(DBusConnection *conn, |
* we are interested. |
*/ |
interface = dbus_message_get_interface(msg); |
- if (interface == NULL || |
- !g_str_has_prefix(interface, MM_MODEMMANAGER_INTERFACE)) { |
+ if (interface == NULL) |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
- } |
- |
/* The signal that has been sent */ |
member = dbus_message_get_member(msg); |
if (member == NULL) { |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
} |
+ if (!g_str_has_prefix(interface, MM_MODEMMANAGER_INTERFACE) && |
+ !g_str_equal(member, MM_MANAGER_SIGNAL_MMPROPERTIESCHANGED)) { |
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
+ } |
+ |
/* The path of the device (sending the message) */ |
path = dbus_message_get_path(msg); |
if (path == NULL) { |
@@ -3360,6 +3451,11 @@ static DBusHandlerResult modemmgr_filter(DBusConnection *conn, |
else if (g_str_equal(member, |
MM_MODEM_GSM_NETWORK_SIGNAL_NETWORKMODE)) |
network_mode_changed(modem, msg); |
+ } else if (g_strcmp0(interface, |
+ MM_DBUS_PROPERTIES_INTERFACE) == 0) { |
+ if (g_str_equal(member, MM_MANAGER_SIGNAL_MMPROPERTIESCHANGED)) { |
+ mm_properties_changed(modem, msg); |
+ } |
} |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
@@ -3371,6 +3467,9 @@ static const char *modem_rule = "type=signal,interface=" MM_MODEM_INTERFACE; |
static const char *cdma_rule = "type=signal,interface=" MM_MODEM_CDMA_INTERFACE; |
static const char *gsm_network_rule = |
"type=signal,interface=" MM_MODEM_GSM_NETWORK_INTERFACE; |
+static const char *mm_properties_rule = |
+ "type=signal,interface=" MM_DBUS_PROPERTIES_INTERFACE |
+ ",member=MmPropertiesChanged"; |
/** |
* modemmgr_connect: Handle a new connection from modem manager |
@@ -3596,6 +3695,7 @@ static int modemmgr_init(void) |
dbus_bus_add_match(connection, modem_rule, NULL); |
dbus_bus_add_match(connection, cdma_rule, NULL); |
dbus_bus_add_match(connection, gsm_network_rule, NULL); |
+ dbus_bus_add_match(connection, mm_properties_rule, NULL); |
dbus_connection_flush(connection); |
/* watch for connections from modem managers */ |
@@ -3643,8 +3743,10 @@ static void modemmgr_exit(void) |
modem_manager_watches = NULL; |
} |
dbus_bus_remove_match(connection, modemmgr_rule, NULL); |
+ dbus_bus_remove_match(connection, modem_rule, NULL); |
dbus_bus_remove_match(connection, cdma_rule, NULL); |
dbus_bus_remove_match(connection, gsm_network_rule, NULL); |
+ dbus_bus_remove_match(connection, mm_properties_rule, NULL); |
dbus_connection_remove_filter(connection, modemmgr_filter, NULL); |
dbus_connection_unref(connection); |
connection = NULL; |