summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAki Niemi <aki.niemi@nokia.com>2010-11-14 18:34:15 +0200
committerAki Niemi <aki.niemi@nokia.com>2010-12-22 17:13:46 +0200
commit332afc9cbccfac8c00c0df285a1a5ea8b297a3a4 (patch)
treec037ebc3ebbfd95ba348e394442cc123a3092e96 /drivers
parent90f31a1cb920ebeba768a351008ac0beafe608f9 (diff)
downloadofono-332afc9cbccfac8c00c0df285a1a5ea8b297a3a4.tar.bz2
isimodem: Adapt and refactor phonebook driver
Diffstat (limited to 'drivers')
-rw-r--r--drivers/isimodem/phonebook.c265
1 files changed, 132 insertions, 133 deletions
diff --git a/drivers/isimodem/phonebook.c b/drivers/isimodem/phonebook.c
index 5ee43152..9eb9c079 100644
--- a/drivers/isimodem/phonebook.c
+++ b/drivers/isimodem/phonebook.c
@@ -30,6 +30,7 @@
#include <glib.h>
#include <gisi/client.h>
+#include <gisi/message.h>
#include <gisi/iter.h>
#include <ofono/log.h>
@@ -46,9 +47,80 @@ struct pb_data {
GIsiClient *client;
};
-static int decode_read_response(const unsigned char *msg, size_t len,
- struct ofono_phonebook *pb)
+struct read_resp {
+ uint8_t service_type;
+ uint8_t sb_count;
+ uint8_t data[];
+};
+
+static gboolean parse_adn(GIsiSubBlockIter *iter, uint16_t *location,
+ char **name, char **number)
+{
+ uint8_t namelen;
+ uint8_t numlen;
+
+ if (!g_isi_sb_iter_get_word(iter, location, 4) ||
+ !g_isi_sb_iter_get_byte(iter, &namelen, 6) ||
+ !g_isi_sb_iter_get_byte(iter, &numlen, 7))
+ return FALSE;
+
+ if (!g_isi_sb_iter_get_alpha_tag(iter, name, namelen * 2, 8))
+ return FALSE;
+
+ if (!g_isi_sb_iter_get_alpha_tag(iter, number, numlen * 2,
+ 8 + namelen * 2)) {
+ g_free(*name);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean parse_sne(GIsiSubBlockIter *iter, char **sne)
+{
+ uint8_t len;
+
+ if (!g_isi_sb_iter_get_byte(iter, &len, 6))
+ return FALSE;
+
+ if (!g_isi_sb_iter_get_alpha_tag(iter, sne, len * 2, 8))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean parse_anr(GIsiSubBlockIter *iter, char **anr)
+{
+ uint8_t len;
+
+ if (!g_isi_sb_iter_get_byte(iter, &len, 6))
+ return FALSE;
+
+ if (!g_isi_sb_iter_get_alpha_tag(iter, anr, len * 2, 8))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean parse_email(GIsiSubBlockIter *iter, char **email)
{
+ uint8_t len;
+
+ if (!g_isi_sb_iter_get_byte(iter, &len, 6))
+ return FALSE;
+
+ if (!g_isi_sb_iter_get_alpha_tag(iter, email, len * 2, 8))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean decode_response(const GIsiMessage *msg, uint16_t *location,
+ void *data)
+{
+ struct ofono_phonebook *pb = data;
+ const struct read_resp *resp = g_isi_msg_data(msg);
+ size_t len = g_isi_msg_data_len(msg);
+
GIsiSubBlockIter iter;
char *name = NULL;
@@ -57,84 +129,48 @@ static int decode_read_response(const unsigned char *msg, size_t len,
char *anr = NULL;
char *email = NULL;
- int location = -1;
- guint8 status = 0;
+ uint8_t status = 0;
+ gboolean success = FALSE;
- if (len < 3 || msg[0] != SIM_PB_RESP_SIM_PB_READ)
- goto error;
-
- if (msg[1] != SIM_PB_READ)
- goto error;
+ if (g_isi_msg_id(msg) != SIM_PB_RESP_SIM_PB_READ ||
+ resp == NULL || len < sizeof(struct read_resp) ||
+ resp->service_type != SIM_PB_READ)
+ return FALSE;
- for (g_isi_sb_iter_init_full(&iter, msg, len, 3, TRUE, msg[2]);
- g_isi_sb_iter_is_valid(&iter);
- g_isi_sb_iter_next(&iter)) {
+ for (g_isi_sb_iter_init_full(&iter, msg, 2, TRUE, resp->sb_count);
+ g_isi_sb_iter_is_valid(&iter);
+ g_isi_sb_iter_next(&iter)) {
switch (g_isi_sb_iter_get_id(&iter)) {
+ case SIM_PB_ADN:
- case SIM_PB_ADN: {
- guint16 loc;
- guint8 namelen;
- guint8 numberlen;
-
- if (!g_isi_sb_iter_get_word(&iter, &loc, 4) ||
- !g_isi_sb_iter_get_byte(&iter, &namelen, 6) ||
- !g_isi_sb_iter_get_byte(&iter, &numberlen, 7))
- goto error;
-
- if (!g_isi_sb_iter_get_alpha_tag(&iter, &name,
- namelen * 2, 8))
- goto error;
-
- if (!g_isi_sb_iter_get_alpha_tag(&iter, &number,
- numberlen * 2, 8 + namelen * 2))
+ if (!parse_adn(&iter, location, &name, &number))
goto error;
-
- location = loc;
+ success = TRUE;
break;
- }
- case SIM_PB_SNE: {
- guint8 snelen;
+ case SIM_PB_SNE:
- if (!g_isi_sb_iter_get_byte(&iter, &snelen, 6))
- goto error;
-
- if (!g_isi_sb_iter_get_alpha_tag(&iter, &sne,
- snelen * 2, 8))
+ if (!parse_sne(&iter, &sne))
goto error;
break;
- }
- case SIM_PB_ANR: {
- guint8 anrlen;
+ case SIM_PB_ANR:
- if (!g_isi_sb_iter_get_byte(&iter, &anrlen, 6))
- goto error;
-
- if (!g_isi_sb_iter_get_alpha_tag(&iter, &anr,
- anrlen * 2, 8))
+ if (!parse_anr(&iter, &anr))
goto error;
break;
- }
- case SIM_PB_EMAIL: {
- guint8 emaillen;
+ case SIM_PB_EMAIL:
- if (!g_isi_sb_iter_get_byte(&iter, &emaillen, 6))
- goto error;
-
- if (!g_isi_sb_iter_get_alpha_tag(&iter, &email,
- emaillen * 2, 8))
+ if (!parse_email(&iter, &email))
goto error;
break;
- }
case SIM_PB_STATUS:
if (!g_isi_sb_iter_get_byte(&iter, &status, 4))
goto error;
-
break;
default:
@@ -145,15 +181,9 @@ static int decode_read_response(const unsigned char *msg, size_t len,
}
}
- if (status != SIM_SERV_OK) {
- DBG("Request failed: %s (0x%02X)",
- sim_isi_cause_name(status), status);
- goto error;
- }
-
- ofono_phonebook_entry(pb, -1, number, -1, name, -1, NULL,
- anr, -1, sne, email, NULL, NULL);
-
+ if (status == SIM_SERV_OK)
+ ofono_phonebook_entry(pb, -1, number, -1, name, -1, NULL,
+ anr, -1, sne, email, NULL, NULL);
error:
g_free(name);
g_free(number);
@@ -161,15 +191,15 @@ error:
g_free(anr);
g_free(email);
- return location;
+ return success;
}
-static void read_next_entry(GIsiClient *client, int location,
- GIsiResponseFunc read_cb,
- struct isi_cb_data *cbd)
+static void read_next_entry(GIsiClient *client, uint16_t location,
+ GIsiNotifyFunc notify, void *data)
{
+ struct isi_cb_data *cbd = data;
ofono_phonebook_cb_t cb = cbd->cb;
- const unsigned char msg[] = {
+ const uint8_t msg[] = {
SIM_PB_REQ_SIM_PB_READ,
SIM_PB_READ,
2, /* number of subblocks */
@@ -195,8 +225,8 @@ static void read_next_entry(GIsiClient *client, int location,
if (cbd == NULL)
goto error;
- if (g_isi_request_make(client, msg, sizeof(msg), SIM_TIMEOUT,
- read_cb, cbd))
+ if (g_isi_client_send(client, msg, sizeof(msg), SIM_TIMEOUT,
+ notify, cbd, NULL))
return;
error:
@@ -204,35 +234,28 @@ error:
g_free(cbd);
}
-static gboolean read_resp_cb(GIsiClient *client,
- const void *restrict data, size_t len,
- uint16_t object, void *opaque)
+static void read_resp_cb(const GIsiMessage *msg, void *data)
{
- const unsigned char *msg = data;
- struct isi_cb_data *cbd = opaque;
+ struct isi_cb_data *cbd = data;
+ struct ofono_phonebook *pb = cbd->user;
+ struct pb_data *pbd = ofono_phonebook_get_data(pb);
+
ofono_phonebook_cb_t cb = cbd->cb;
- int location;
+ uint16_t location;
- if (!msg) {
- DBG("ISI client error: %d", g_isi_client_error(client));
- goto error;
+ if (g_isi_msg_error(msg) < 0) {
+ CALLBACK_WITH_FAILURE(cb, cbd->data);
+ g_free(cbd);
+ return;
}
- location = decode_read_response(data, len, cbd->user);
- if (location != -1) {
- read_next_entry(client, location, read_resp_cb, cbd);
- return TRUE;
+ if (decode_response(msg, &location, cbd->user)) {
+ read_next_entry(pbd->client, location, read_resp_cb, cbd);
+ return;
}
CALLBACK_WITH_SUCCESS(cb, cbd->data);
- goto out;
-
-error:
- CALLBACK_WITH_FAILURE(cb, cbd->data);
-
-out:
g_free(cbd);
- return TRUE;
}
static void isi_export_entries(struct ofono_phonebook *pb, const char *storage,
@@ -240,7 +263,7 @@ static void isi_export_entries(struct ofono_phonebook *pb, const char *storage,
{
struct pb_data *pbd = ofono_phonebook_get_data(pb);
struct isi_cb_data *cbd = isi_cb_data_new(pb, cb, data);
- const unsigned char msg[] = {
+ const uint8_t msg[] = {
SIM_PB_REQ_SIM_PB_READ,
SIM_PB_READ,
2, /* number of subblocks */
@@ -259,65 +282,41 @@ static void isi_export_entries(struct ofono_phonebook *pb, const char *storage,
0, 0 /* filler */
};
- if (cbd == NULL || pbd == NULL)
- goto error;
-
- if (strcmp(storage, "SM"))
+ if (cbd == NULL || pbd == NULL || strcmp(storage, "SM") != 0)
goto error;
- if (g_isi_request_make(pbd->client, msg, sizeof(msg), SIM_TIMEOUT,
- read_resp_cb, cbd))
+ if (g_isi_client_send(pbd->client, msg, sizeof(msg), SIM_TIMEOUT,
+ read_resp_cb, cbd, NULL))
return;
error:
- if (cbd)
- g_free(cbd);
-
CALLBACK_WITH_FAILURE(cb, data);
+ g_free(cbd);
}
-static gboolean isi_phonebook_register(gpointer user)
-{
- struct ofono_phonebook *pb = user;
-
- ofono_phonebook_register(pb);
-
- return FALSE;
-}
-
-static void reachable_cb(GIsiClient *client, gboolean alive, uint16_t object,
- void *opaque)
+static void reachable_cb(const GIsiMessage *msg, void *data)
{
- struct ofono_phonebook *pb = opaque;
- const char *debug = NULL;
+ struct ofono_phonebook *pb = data;
- if (!alive) {
- DBG("Unable to bootstrap phonebook driver");
+ 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);
- debug = getenv("OFONO_ISI_DEBUG");
- if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "sim") == 0))
- g_isi_client_set_debug(client, sim_debug, NULL);
-
- g_idle_add(isi_phonebook_register, pb);
+ ofono_phonebook_register(pb);
}
static int isi_phonebook_probe(struct ofono_phonebook *pb, unsigned int vendor,
void *user)
{
- GIsiModem *idx = user;
- struct pb_data *data = g_try_new0(struct pb_data, 1);
+ GIsiModem *modem = user;
+ struct pb_data *data;
+ data = g_try_new0(struct pb_data, 1);
if (data == NULL)
return -ENOMEM;
- data->client = g_isi_client_create(idx, PN_SIM);
+ data->client = g_isi_client_create(modem, PN_SIM);
if (data->client == NULL) {
g_free(data);
return -ENOMEM;
@@ -325,8 +324,7 @@ static int isi_phonebook_probe(struct ofono_phonebook *pb, unsigned int vendor,
ofono_phonebook_set_data(pb, data);
- if (!g_isi_verify(data->client, reachable_cb, pb))
- DBG("Unable to verify reachability");
+ g_isi_client_verify(data->client, reachable_cb, pb, NULL);
return 0;
}
@@ -335,10 +333,11 @@ static void isi_phonebook_remove(struct ofono_phonebook *pb)
{
struct pb_data *data = ofono_phonebook_get_data(pb);
+ ofono_phonebook_set_data(pb, NULL);
+
if (data == NULL)
return;
- ofono_phonebook_set_data(pb, NULL);
g_isi_client_destroy(data->client);
g_free(data);
}