summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/isimodem/radio-settings.c222
1 files changed, 100 insertions, 122 deletions
diff --git a/drivers/isimodem/radio-settings.c b/drivers/isimodem/radio-settings.c
index 01c67195..f7eaffde 100644
--- a/drivers/isimodem/radio-settings.c
+++ b/drivers/isimodem/radio-settings.c
@@ -48,7 +48,9 @@
#define PN_WRAN 0xb4
struct radio_data {
- GIsiClient *client;
+ GIsiClient *gss_client;
+ GIsiClient *gpds_client;
+ GIsiClient *wran_client;
uint16_t wran_object;
uint16_t quick_release:1;
};
@@ -81,69 +83,57 @@ static int ofono_mode_to_isi_mode(enum ofono_radio_access_mode mode)
}
}
-static gboolean rat_mode_read_resp_cb(GIsiClient *client,
- const void *restrict data, size_t len,
- uint16_t object,
- void *opaque)
+static void rat_mode_read_resp_cb(const GIsiMessage *msg, void *opaque)
{
- const unsigned char *msg = data;
struct isi_cb_data *cbd = opaque;
ofono_radio_settings_rat_mode_query_cb_t cb = cbd->cb;
int mode = -1;
+ GIsiSubBlockIter iter;
- if (!msg) {
- DBG("ISI client error: %d", g_isi_client_error(client));
+ if (g_isi_msg_error(msg) < 0) {
+ DBG("message error");
goto error;
}
- if (len < 3) {
- DBG("truncated message");
- return FALSE;
- }
-
- if (msg[0] == GSS_CS_SERVICE_FAIL_RESP)
+ if (g_isi_msg_id(msg) == GSS_CS_SERVICE_FAIL_RESP)
goto error;
- if (msg[0] == GSS_CS_SERVICE_RESP) {
- GIsiSubBlockIter iter;
+ if (g_isi_msg_id(msg) != GSS_CS_SERVICE_RESP)
+ return;
- for (g_isi_sb_iter_init(&iter, msg, len, 3);
- g_isi_sb_iter_is_valid(&iter);
- g_isi_sb_iter_next(&iter)) {
+ 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)) {
+ switch (g_isi_sb_iter_get_id(&iter)) {
- case GSS_RAT_INFO: {
- guint8 info;
+ case GSS_RAT_INFO: {
+ guint8 info;
- if (!g_isi_sb_iter_get_byte(&iter, &info, 2))
- goto error;
+ if (!g_isi_sb_iter_get_byte(&iter, &info, 2))
+ goto error;
- mode = isi_mode_to_ofono_mode(info);
+ mode = isi_mode_to_ofono_mode(info);
- break;
- }
- default:
- DBG("Skipping sub-block: %s (%zu bytes)",
- gss_subblock_name(
- g_isi_sb_iter_get_id(&iter)),
- g_isi_sb_iter_get_len(&iter));
- break;
- }
+ break;
+ }
+ default:
+ DBG("Skipping sub-block: %s (%zu bytes)",
+ gss_subblock_name(
+ g_isi_sb_iter_get_id(&iter)),
+ g_isi_sb_iter_get_len(&iter));
+ break;
}
-
- CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
- goto out;
}
- return FALSE;
+ CALLBACK_WITH_SUCCESS(cb, mode, cbd->data);
+ g_free(cbd);
+ return;
error:
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
-
-out:
g_free(cbd);
- return TRUE;
+ return;
}
static void isi_query_rat_mode(struct ofono_radio_settings *rs,
@@ -162,8 +152,8 @@ static void isi_query_rat_mode(struct ofono_radio_settings *rs,
if (cbd == NULL || rd == NULL)
goto error;
- if (g_isi_request_make(rd->client, msg, sizeof(msg), GSS_TIMEOUT,
- rat_mode_read_resp_cb, cbd))
+ if (g_isi_client_send(rd->gss_client, msg, sizeof(msg), GSS_TIMEOUT,
+ rat_mode_read_resp_cb, cbd, NULL))
return;
error:
@@ -171,40 +161,30 @@ error:
g_free(cbd);
}
-static gboolean mode_write_resp_cb(GIsiClient *client,
- const void *restrict data, size_t len,
- uint16_t object, void *opaque)
+static void mode_write_resp_cb(const GIsiMessage *msg, void *opaque)
{
- const unsigned char *msg = data;
struct isi_cb_data *cbd = opaque;
ofono_radio_settings_rat_mode_set_cb_t cb = cbd->cb;
- if (!msg) {
- DBG("ISI client error: %d", g_isi_client_error(client));
+ if (g_isi_msg_error(msg) < 0) {
+ DBG("message error");
goto error;
}
- if (len < 3) {
- DBG("truncated message");
- return FALSE;
- }
-
- if (msg[0] == GSS_CS_SERVICE_FAIL_RESP)
+ if (g_isi_msg_id(msg) == GSS_CS_SERVICE_FAIL_RESP)
goto error;
- if (msg[0] == GSS_CS_SERVICE_RESP) {
- CALLBACK_WITH_SUCCESS(cb, cbd->data);
- goto out;
- }
+ if (g_isi_msg_id(msg) != GSS_CS_SERVICE_RESP)
+ return;
- return FALSE;
+ CALLBACK_WITH_SUCCESS(cb, cbd->data);
+ g_free(cbd);
+ return;
error:
CALLBACK_WITH_FAILURE(cb, cbd->data);
-
-out:
g_free(cbd);
- return TRUE;
+ return;
}
static void isi_set_rat_mode(struct ofono_radio_settings *rs,
@@ -232,8 +212,8 @@ static void isi_set_rat_mode(struct ofono_radio_settings *rs,
if (isi_mode == -1)
goto error;
- if (g_isi_request_make(rd->client, msg, sizeof(msg), GSS_TIMEOUT,
- mode_write_resp_cb, cbd))
+ if (g_isi_client_send(rd->gss_client, msg, sizeof(msg), GSS_TIMEOUT,
+ mode_write_resp_cb, cbd, NULL))
return;
error:
@@ -243,6 +223,8 @@ error:
static void update_fast_dormancy(struct radio_data *rd)
{
+ GIsiModem *modem;
+
struct sockaddr_pn dst = {
.spn_family = AF_PHONET,
.spn_resource = 0x3a,
@@ -253,29 +235,29 @@ static void update_fast_dormancy(struct radio_data *rd)
if (!rd->wran_object)
return;
+ modem = g_isi_client_modem(rd->wran_client);
+
if (rd->quick_release) {
const unsigned char msg[] = {
- 0x1f, 0x00, 0x01, 0x01, 0x01, 0x00
+ 0x00, 0x1f, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00
};
- g_isi_sendto(rd->client, &dst, msg, sizeof(msg), 0,
- NULL, NULL, NULL);
+ g_isi_modem_sendto(modem, &dst, msg, sizeof(msg));
} else {
const unsigned char msg[] = {
- 0x1f, 0x00, 0x01, 0x01, 0x02, 0x0a
+ 0x00, 0x1f, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02,
+ 0x00, 0x0a, 0x00, 0x00
};
- g_isi_sendto(rd->client, &dst, msg, sizeof(msg), 0,
- NULL, NULL, NULL);
+ g_isi_modem_sendto(modem, &dst, msg, sizeof(msg));
}
DBG("3G PS quick release %s",
rd->quick_release ? "enabled" : "disabled");
}
-static void gpds_context_activating_ind_cb(GIsiClient *client,
- const void *restrict data, size_t len,
- uint16_t object, void *opaque)
+static void gpds_context_activating_ind_cb(const GIsiMessage *msg, void *opaque)
{
struct radio_data *rd = opaque;
update_fast_dormancy(rd);
@@ -300,95 +282,91 @@ static void isi_set_fast_dormancy(struct ofono_radio_settings *rs,
CALLBACK_WITH_SUCCESS(cb, data);
}
-static gboolean isi_radio_settings_register(gpointer user)
-{
- struct ofono_radio_settings *rs = user;
- struct radio_data *rd = ofono_radio_settings_get_data(rs);
-
- const char *debug = getenv("OFONO_ISI_DEBUG");
-
- if (debug && (g_strcmp0(debug, "all") == 0
- || g_strcmp0(debug, "gss") == 0))
- g_isi_client_set_debug(rd->client, gss_debug, NULL);
-
- ofono_radio_settings_register(rs);
-
- g_isi_add_subscription(rd->client,
- PN_GPDS, GPDS_CONTEXT_ACTIVATING_IND,
- gpds_context_activating_ind_cb, rd);
- g_isi_commit_subscriptions(rd->client);
-
- return FALSE;
-}
-
-static void wran_reachable_cb(GIsiClient *client, gboolean alive,
- uint16_t object, void *opaque)
+static void wran_reachable_cb(const GIsiMessage *msg, void *opaque)
{
struct radio_data *rd = opaque;
- if (!alive) {
- DBG("fast dormancy support disabled");
+ if (g_isi_msg_error(msg) < 0)
return;
- }
- rd->wran_object = object;
+ ISI_VERSION_DBG(msg);
+
+ rd->wran_object = g_isi_msg_object(msg);
- DBG("PN_WRAN reachable, object=0x%04x", object);
+ DBG("PN_WRAN object = 0x%04x", rd->wran_object);
update_fast_dormancy(rd);
+
+ g_isi_client_ind_subscribe(rd->gpds_client,
+ GPDS_CONTEXT_ACTIVATING_IND,
+ gpds_context_activating_ind_cb, rd);
}
-static void reachable_cb(GIsiClient *client, gboolean alive, uint16_t object,
- void *opaque)
+static void gss_reachable_cb(const GIsiMessage *msg, void *opaque)
{
struct ofono_radio_settings *rs = opaque;
+ struct radio_data *rd = ofono_radio_settings_get_data(rs);
+ const char *debug = getenv("OFONO_ISI_DEBUG");
- if (!alive) {
- DBG("radio access driver bootstrap failed");
+ if (g_isi_msg_error(msg) < 0)
return;
- }
- DBG("%s (v%03d.%03d) reachable",
- pn_resource_name(g_isi_client_resource(client)),
- g_isi_version_major(client),
- g_isi_version_minor(client));
+ ISI_VERSION_DBG(msg);
- g_idle_add(isi_radio_settings_register, rs);
+ ofono_radio_settings_register(rs);
}
static int isi_radio_settings_probe(struct ofono_radio_settings *rs,
unsigned int vendor,
void *user)
{
- GIsiModem *idx = user;
+ GIsiModem *modem = user;
struct radio_data *rd = g_try_new0(struct radio_data, 1);
if (rd == NULL)
return -ENOMEM;
- rd->client = g_isi_client_create(idx, PN_GSS);
- if (rd->client == NULL) {
- g_free(rd);
- return -ENOMEM;
- }
+ rd->gss_client = g_isi_client_create(modem, PN_GSS);
+ if (rd->gss_client == NULL)
+ goto nomem;
+
+ rd->gpds_client = g_isi_client_create(modem, PN_GPDS);
+ if (rd->gpds_client == NULL)
+ goto nomem;
+
+ rd->wran_client = g_isi_client_create(modem, PN_WRAN);
+ if (rd->wran_client == NULL)
+ goto nomem;
ofono_radio_settings_set_data(rs, rd);
- g_isi_verify(rd->client, reachable_cb, rs);
- g_isi_verify_resource(rd->client, PN_WRAN, wran_reachable_cb, rd);
+ g_isi_client_verify(rd->gss_client, gss_reachable_cb, rs, NULL);
+ g_isi_client_verify(rd->wran_client, wran_reachable_cb, rd, NULL);
return 0;
+nomem:
+ if (rd->gss_client)
+ g_isi_client_destroy(rd->gss_client);
+ if (rd->wran_client)
+ g_isi_client_destroy(rd->wran_client);
+ if (rd->gpds_client)
+ g_isi_client_destroy(rd->gpds_client);
+ g_free(rd);
+ return -ENOMEM;
}
static void isi_radio_settings_remove(struct ofono_radio_settings *rs)
{
struct radio_data *rd = ofono_radio_settings_get_data(rs);
+ ofono_radio_settings_set_data(rs, NULL);
+
if (rd == NULL)
return;
- ofono_radio_settings_set_data(rs, NULL);
- g_isi_client_destroy(rd->client);
+ g_isi_client_destroy(rd->gss_client);
+ g_isi_client_destroy(rd->wran_client);
+ g_isi_client_destroy(rd->gpds_client);
g_free(rd);
}