| 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;
|
|
|