summaryrefslogtreecommitdiffstats
path: root/drivers/isimodem
diff options
context:
space:
mode:
authorAki Niemi <aki.niemi@nokia.com>2011-02-16 15:47:27 +0200
committerAki Niemi <aki.niemi@nokia.com>2011-02-18 16:17:13 +0200
commitdfc78c0ca081f6e255c2fe12821a08ec761e2af5 (patch)
treea0295bcd21f0b23dad48c69ddb6ce5671a024441 /drivers/isimodem
parent8250c1edad055976bb48ebd4aaa49aa078e8ec93 (diff)
downloadofono-dfc78c0ca081f6e255c2fe12821a08ec761e2af5.tar.bz2
isimodem: Refactor netreg driver a bit more
Split the driver into two separate drivers, one for each resource ID used.
Diffstat (limited to 'drivers/isimodem')
-rw-r--r--drivers/isimodem/network-registration.c253
1 files changed, 119 insertions, 134 deletions
diff --git a/drivers/isimodem/network-registration.c b/drivers/isimodem/network-registration.c
index ffda7c83..a30fc8c5 100644
--- a/drivers/isimodem/network-registration.c
+++ b/drivers/isimodem/network-registration.c
@@ -75,8 +75,6 @@ struct network_time {
struct netreg_data {
GIsiClient *client;
- GIsiClient *primary;
- GIsiClient *secondary;
struct reg_info reg;
struct gsm_info gsm;
struct rat_info rat;
@@ -382,51 +380,48 @@ error:
g_free(cbd);
}
-static void name_get_resp_cb(const GIsiMessage *msg, void *data)
+static void cell_info_resp_cb(const GIsiMessage *msg, void *data)
{
struct isi_cb_data *cbd = data;
ofono_netreg_operator_cb_t cb = cbd->cb;
+ struct ofono_netreg *netreg = cbd->user;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
struct ofono_network_operator op;
-
GIsiSubBlockIter iter;
- uint8_t len = 0;
- char *tag = NULL;
memset(&op, 0, sizeof(struct ofono_network_operator));
- if (!check_response_status(msg, NET_OPER_NAME_READ_RESP))
+ if (!check_response_status(msg, NET_CELL_INFO_GET_RESP))
goto error;
- for (g_isi_sb_iter_init(&iter, msg, 6);
+ for (g_isi_sb_iter_init(&iter, msg, 2);
g_isi_sb_iter_is_valid(&iter);
g_isi_sb_iter_next(&iter)) {
switch (g_isi_sb_iter_get_id(&iter)) {
- case NET_GSM_OPERATOR_INFO:
+ case NET_GSM_CELL_INFO:
- if (!g_isi_sb_iter_get_oper_code(&iter, op.mcc,
- op.mnc, 2))
+ if (!g_isi_sb_iter_get_oper_code(&iter, op.mcc, op.mnc,
+ 12))
goto error;
- break;
- case NET_OPER_NAME_INFO:
-
- if (!g_isi_sb_iter_get_byte(&iter, &len, 3))
- goto error;
+ op.tech = 0;
+ break;
- /* Name is UCS-2 encoded */
- len *= 2;
+ case NET_WCDMA_CELL_INFO:
- if (!g_isi_sb_iter_get_alpha_tag(&iter, &tag, len, 4))
+ if (!g_isi_sb_iter_get_oper_code(&iter, op.mcc, op.mnc,
+ 12))
goto error;
- strncpy(op.name, tag, OFONO_MAX_OPERATOR_NAME_LENGTH);
- op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
- g_free(tag);
+ op.tech = 2;
break;
}
}
+ if (nd->nitz_name[0] != '\0')
+ strcpy(op.name, nd->nitz_name);
+
CALLBACK_WITH_SUCCESS(cb, &op, cbd->data);
return;
@@ -434,64 +429,74 @@ error:
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
}
-static gboolean send_name_read_req(GIsiClient *client, void *cbd,
- GDestroyNotify destroy)
+static void wg_current_operator(struct ofono_netreg *netreg,
+ ofono_netreg_operator_cb_t cb,
+ void *data)
{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct isi_cb_data *cbd = isi_cb_data_new(netreg, cb, data);
+
const uint8_t msg[] = {
- NET_OPER_NAME_READ_REQ,
- NET_HARDCODED_LATIN_OPER_NAME,
- OFONO_MAX_OPERATOR_NAME_LENGTH,
- 0x00, 0x00, /* Index not used */
- 0x00, /* Filler */
- 0x00, /* No sub-blocks */
+ NET_CELL_INFO_GET_REQ,
};
- return g_isi_client_send(client, msg, sizeof(msg), name_get_resp_cb,
- cbd, destroy);
+ if (cbd == NULL || nd == NULL)
+ goto error;
+
+ if (g_isi_client_send(nd->client, msg, sizeof(msg), cell_info_resp_cb,
+ cbd, g_free))
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, data);
+ g_free(cbd);
}
-static void cell_info_resp_cb(const GIsiMessage *msg, void *data)
+static void name_get_resp_cb(const GIsiMessage *msg, void *data)
{
struct isi_cb_data *cbd = data;
ofono_netreg_operator_cb_t cb = cbd->cb;
- struct ofono_netreg *netreg = cbd->user;
- struct netreg_data *nd = ofono_netreg_get_data(netreg);
struct ofono_network_operator op;
+
GIsiSubBlockIter iter;
+ uint8_t len = 0;
+ char *tag = NULL;
memset(&op, 0, sizeof(struct ofono_network_operator));
- if (!check_response_status(msg, NET_CELL_INFO_GET_RESP))
+ if (!check_response_status(msg, NET_OPER_NAME_READ_RESP))
goto error;
- for (g_isi_sb_iter_init(&iter, msg, 2);
+ for (g_isi_sb_iter_init(&iter, msg, 6);
g_isi_sb_iter_is_valid(&iter);
g_isi_sb_iter_next(&iter)) {
switch (g_isi_sb_iter_get_id(&iter)) {
- case NET_GSM_CELL_INFO:
+ case NET_GSM_OPERATOR_INFO:
- if (!g_isi_sb_iter_get_oper_code(&iter, op.mcc, op.mnc,
- 12))
+ if (!g_isi_sb_iter_get_oper_code(&iter, op.mcc,
+ op.mnc, 2))
goto error;
-
- op.tech = 0;
break;
- case NET_WCDMA_CELL_INFO:
+ case NET_OPER_NAME_INFO:
- if (!g_isi_sb_iter_get_oper_code(&iter, op.mcc, op.mnc,
- 12))
+ if (!g_isi_sb_iter_get_byte(&iter, &len, 3))
goto error;
- op.tech = 2;
+ /* Name is UCS-2 encoded */
+ len *= 2;
+
+ if (!g_isi_sb_iter_get_alpha_tag(&iter, &tag, len, 4))
+ goto error;
+
+ strncpy(op.name, tag, OFONO_MAX_OPERATOR_NAME_LENGTH);
+ op.name[OFONO_MAX_OPERATOR_NAME_LENGTH] = '\0';
+ g_free(tag);
break;
}
}
- if (nd->nitz_name[0] != '\0')
- strcpy(op.name, nd->nitz_name);
-
CALLBACK_WITH_SUCCESS(cb, &op, cbd->data);
return;
@@ -499,17 +504,6 @@ error:
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
}
-static gboolean send_cell_info_req(GIsiClient *client, void *cbd,
- GDestroyNotify destroy)
-{
- const uint8_t msg[] = {
- NET_CELL_INFO_GET_REQ,
- };
-
- return g_isi_client_send(client, msg, sizeof(msg), cell_info_resp_cb,
- cbd, destroy);
-}
-
static void isi_current_operator(struct ofono_netreg *netreg,
ofono_netreg_operator_cb_t cb,
void *data)
@@ -517,21 +511,21 @@ static void isi_current_operator(struct ofono_netreg *netreg,
struct netreg_data *nd = ofono_netreg_get_data(netreg);
struct isi_cb_data *cbd = isi_cb_data_new(netreg, cb, data);
+ const uint8_t msg[] = {
+ NET_OPER_NAME_READ_REQ,
+ NET_HARDCODED_LATIN_OPER_NAME,
+ OFONO_MAX_OPERATOR_NAME_LENGTH,
+ 0x00, 0x00, /* Index not used */
+ 0x00, /* Filler */
+ 0x00, /* No sub-blocks */
+ };
+
if (cbd == NULL || nd == NULL)
goto error;
- /*
- * PN_MODEM_NETWORK provides no operator name info, so getting
- * the current operator information relies on cell info
- * instead.
- */
- if (g_isi_client_resource(nd->client) == PN_MODEM_NETWORK) {
- if (send_cell_info_req(nd->client, cbd, g_free))
- return;
- } else {
- if (send_name_read_req(nd->client, cbd, g_free))
- return;
- }
+ if (g_isi_client_send(nd->client, msg, sizeof(msg), name_get_resp_cb,
+ cbd, g_free))
+ return;
error:
CALLBACK_WITH_FAILURE(cb, NULL, data);
@@ -802,10 +796,12 @@ static gboolean parse_nettime(GIsiSubBlockIter *iter,
info->min = time->min != NET_INVALID_TIME ? time->min : -1;
info->sec = time->sec != NET_INVALID_TIME ? time->sec : -1;
- /* Most significant bit set indicates negative offset. The
+ /*
+ * Most significant bit set indicates negative offset. The
* second most significant bit is 'reserved'. The value is the
* offset from UTCin a count of 15min intervals, possibly
- * including the current DST adjustment. */
+ * including the current DST adjustment.
+ */
info->utcoff = (time->utc & 0x3F) * 15 * 60;
if (time->utc & 0x80)
info->utcoff *= -1;
@@ -929,9 +925,19 @@ error:
g_free(cbd);
}
-static void common_client_setup(struct ofono_netreg *netreg,
- struct netreg_data *nd)
+static void reachable_cb(const GIsiMessage *msg, void *data)
{
+ struct ofono_netreg *netreg = data;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+
+ if (g_isi_msg_error(msg) < 0)
+ return;
+
+ ISI_VERSION_DBG(msg);
+
+ if (nd == NULL)
+ return;
+
g_isi_client_ind_subscribe(nd->client, NET_RSSI_IND, rssi_ind_cb,
netreg);
g_isi_client_ind_subscribe(nd->client, NET_NITZ_NAME_IND, name_ind_cb,
@@ -939,6 +945,7 @@ static void common_client_setup(struct ofono_netreg *netreg,
g_isi_client_ind_subscribe(nd->client, NET_RAT_IND, rat_ind_cb, netreg);
g_isi_client_ind_subscribe(nd->client, NET_TIME_IND, time_ind_cb,
netreg);
+
g_isi_client_ind_subscribe(nd->client, NET_MODEM_REG_STATUS_IND,
reg_status_ind_cb, netreg);
g_isi_client_ind_subscribe(nd->client, NET_REG_STATUS_IND,
@@ -947,44 +954,8 @@ static void common_client_setup(struct ofono_netreg *netreg,
ofono_netreg_register(netreg);
}
-static void primary_reachable_cb(const GIsiMessage *msg, void *data)
-{
- struct ofono_netreg *netreg = data;
- struct netreg_data *nd = ofono_netreg_get_data(netreg);
-
- if (g_isi_msg_error(msg) < 0)
- return;
-
- ISI_VERSION_DBG(msg);
-
- if (nd == NULL || nd->client != NULL)
- return;
-
- nd->client = nd->primary;
-
- common_client_setup(netreg, nd);
-}
-
-static void secondary_reachable_cb(const GIsiMessage *msg, void *data)
-{
- struct ofono_netreg *netreg = data;
- struct netreg_data *nd = ofono_netreg_get_data(netreg);
-
- if (g_isi_msg_error(msg) < 0)
- return;
-
- ISI_VERSION_DBG(msg);
-
- if (nd == NULL || nd->client != NULL)
- return;
-
- nd->client = nd->secondary;
-
- common_client_setup(netreg, nd);
-}
-
-static int isi_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
- void *user)
+static int netreg_probe(struct ofono_netreg *netreg, uint8_t resource,
+ void *user)
{
GIsiModem *modem = user;
struct netreg_data *nd;
@@ -993,28 +964,29 @@ static int isi_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
if (nd == NULL)
return -ENOMEM;
- nd->primary = g_isi_client_create(modem, PN_MODEM_NETWORK);
- if (nd->primary == NULL)
- goto nomem;
-
- nd->secondary = g_isi_client_create(modem, PN_NETWORK);
- if (nd->secondary == NULL)
- goto nomem;
+ nd->client = g_isi_client_create(modem, resource);
+ if (nd->client == NULL) {
+ g_free(nd);
+ return -ENOMEM;
+ }
ofono_netreg_set_data(netreg, nd);
- g_isi_client_verify(nd->primary, primary_reachable_cb, netreg, NULL);
- g_isi_client_verify(nd->secondary, secondary_reachable_cb, netreg,
- NULL);
+ g_isi_client_verify(nd->client, reachable_cb, netreg, NULL);
return 0;
+}
-nomem:
- g_isi_client_destroy(nd->primary);
- g_isi_client_destroy(nd->secondary);
+static int wg_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
+ void *user)
+{
+ return netreg_probe(netreg, PN_MODEM_NETWORK, user);
+}
- g_free(nd);
- return -ENOMEM;
+static int isi_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
+ void *user)
+{
+ return netreg_probe(netreg, PN_NETWORK, user);
}
static void isi_netreg_remove(struct ofono_netreg *netreg)
@@ -1026,12 +998,11 @@ static void isi_netreg_remove(struct ofono_netreg *netreg)
if (data == NULL)
return;
- g_isi_client_destroy(data->primary);
- g_isi_client_destroy(data->secondary);
+ g_isi_client_destroy(data->client);
g_free(data);
}
-static struct ofono_netreg_driver driver = {
+static struct ofono_netreg_driver isimodem = {
.name = "isimodem",
.probe = isi_netreg_probe,
.remove = isi_netreg_remove,
@@ -1043,12 +1014,26 @@ static struct ofono_netreg_driver driver = {
.strength = isi_strength,
};
+static struct ofono_netreg_driver wgmodem = {
+ .name = "wgmodem2.5",
+ .probe = wg_netreg_probe,
+ .remove = isi_netreg_remove,
+ .registration_status = isi_registration_status,
+ .current_operator = wg_current_operator,
+ .list_operators = isi_list_operators,
+ .register_auto = isi_register_auto,
+ .register_manual = isi_register_manual,
+ .strength = isi_strength,
+};
+
void isi_netreg_init(void)
{
- ofono_netreg_driver_register(&driver);
+ ofono_netreg_driver_register(&isimodem);
+ ofono_netreg_driver_register(&wgmodem);
}
void isi_netreg_exit(void)
{
- ofono_netreg_driver_unregister(&driver);
+ ofono_netreg_driver_unregister(&isimodem);
+ ofono_netreg_driver_unregister(&wgmodem);
}