mirror of git://git.sysmocom.de/ofono
Refactor phonebook code
This commit is contained in:
parent
72345b4175
commit
8d47b8f36d
|
@ -46,23 +46,14 @@
|
|||
#define CHARSET_SUPPORT (CHARSET_UTF8 | CHARSET_UCS2)
|
||||
|
||||
static const char *none_prefix[] = { NULL };
|
||||
static const char *entries_prefix[] = { "+CPBR:", NULL };
|
||||
static const char *charset_prefix[] = { "+CSCS:", NULL };
|
||||
|
||||
static void at_select_storage(struct ofono_modem *modem,
|
||||
ofono_generic_cb_t cb, void *data);
|
||||
static void at_select_charset(struct ofono_modem *modem,
|
||||
ofono_generic_cb_t cb, void *data);
|
||||
static const char *cpbr_prefix[] = { "+CPBR:", NULL };
|
||||
static const char *cscs_prefix[] = { "+CSCS:", NULL };
|
||||
static const char *cpbs_prefix[] = { "+CPBS:", NULL };
|
||||
|
||||
struct pb_data {
|
||||
const char *storage;
|
||||
int index_min, index_max;
|
||||
int charset_origin;
|
||||
const char *charset_origin_str;
|
||||
int charset_current;
|
||||
int charset_list;
|
||||
int charset_need_restore;
|
||||
int has_charset_info;
|
||||
char *old_charset;
|
||||
int supported;
|
||||
};
|
||||
|
||||
static struct pb_data *phonebook_create()
|
||||
|
@ -73,28 +64,51 @@ static struct pb_data *phonebook_create()
|
|||
|
||||
static void phonebook_destroy(struct pb_data *data)
|
||||
{
|
||||
g_free((char *)data->charset_origin_str);
|
||||
if (data->old_charset)
|
||||
g_free(data->old_charset);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static const char *ucs2_to_utf8(const char *str)
|
||||
static char *ucs2_to_utf8(const char *str)
|
||||
{
|
||||
long len;
|
||||
unsigned char *ucs2;
|
||||
const char *utf8;
|
||||
char *utf8;
|
||||
ucs2 = decode_hex(str, -1, &len, 0);
|
||||
utf8 = g_convert(ucs2, len, "UTF-8//TRANSLIT", "UCS-2BE",
|
||||
utf8 = g_convert((char *)ucs2, len, "UTF-8//TRANSLIT", "UCS-2BE",
|
||||
NULL, NULL, NULL);
|
||||
g_free(ucs2);
|
||||
return utf8;
|
||||
}
|
||||
|
||||
static const char *best_charset(int supported)
|
||||
{
|
||||
const char *charset = "Invalid";
|
||||
|
||||
if (supported & CHARSET_UCS2)
|
||||
charset = "UCS2";
|
||||
|
||||
if (supported & CHARSET_UTF8)
|
||||
charset = "UTF-8";
|
||||
|
||||
return charset;
|
||||
}
|
||||
|
||||
static void at_cpbr_notify(GAtResult *result, gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
GAtResultIter iter;
|
||||
int current;
|
||||
|
||||
dump_response("at_cbpr_notify", 1, result);
|
||||
|
||||
if (at->pb->supported & CHARSET_UCS2)
|
||||
current = CHARSET_UCS2;
|
||||
|
||||
if (at->pb->supported & CHARSET_UTF8)
|
||||
current = CHARSET_UTF8;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
|
@ -103,20 +117,14 @@ static void at_cpbr_notify(GAtResult *result, gpointer user_data)
|
|||
const char *number;
|
||||
int type;
|
||||
const char *text;
|
||||
const char *text_utf8;
|
||||
int hidden = -1;
|
||||
const char *group = NULL;
|
||||
const char *group_utf8 = NULL;
|
||||
const char *adnumber = NULL;
|
||||
int adtype = -1;
|
||||
const char *secondtext = NULL;
|
||||
const char *secondtext_utf8 = NULL;
|
||||
const char *email = NULL;
|
||||
const char *email_utf8 = NULL;
|
||||
const char *sip_uri = NULL;
|
||||
const char *sip_uri_utf8 = NULL;
|
||||
const char *tel_uri = NULL;
|
||||
const char *tel_uri_utf8 = NULL;
|
||||
|
||||
if (!g_at_result_iter_next_number(&iter, &index))
|
||||
continue;
|
||||
|
@ -140,7 +148,14 @@ static void at_cpbr_notify(GAtResult *result, gpointer user_data)
|
|||
g_at_result_iter_next_string(&iter, &tel_uri);
|
||||
|
||||
/* charset_current is either CHARSET_UCS2 or CHARSET_UTF8 */
|
||||
if (at->pb->charset_current & CHARSET_UCS2) {
|
||||
if (current == CHARSET_UCS2) {
|
||||
char *text_utf8;
|
||||
char *group_utf8 = NULL;
|
||||
char *secondtext_utf8 = NULL;
|
||||
char *email_utf8 = NULL;
|
||||
char *sip_uri_utf8 = NULL;
|
||||
char *tel_uri_utf8 = NULL;
|
||||
|
||||
text_utf8 = ucs2_to_utf8(text);
|
||||
if (group)
|
||||
group_utf8 = ucs2_to_utf8(group);
|
||||
|
@ -152,31 +167,47 @@ static void at_cpbr_notify(GAtResult *result, gpointer user_data)
|
|||
sip_uri_utf8 = ucs2_to_utf8(sip_uri);
|
||||
if (tel_uri)
|
||||
tel_uri_utf8 = ucs2_to_utf8(tel_uri);
|
||||
} else {
|
||||
text_utf8 = text;
|
||||
group_utf8 = group;
|
||||
secondtext_utf8 = secondtext;
|
||||
email_utf8 = email;
|
||||
sip_uri_utf8 = sip_uri;
|
||||
tel_uri_utf8 = tel_uri;
|
||||
}
|
||||
|
||||
ofono_phonebook_entry(cbd->modem, index, number, type,
|
||||
ofono_phonebook_entry(cbd->modem, index, number, type,
|
||||
text_utf8, hidden, group_utf8, adnumber,
|
||||
adtype, secondtext_utf8, email_utf8,
|
||||
sip_uri_utf8, tel_uri_utf8);
|
||||
|
||||
if (at->pb->charset_current & CHARSET_UCS2) {
|
||||
g_free((char *)text_utf8);
|
||||
g_free((char *)group_utf8);
|
||||
g_free((char *)secondtext_utf8);
|
||||
g_free((char *)email_utf8);
|
||||
g_free((char *)sip_uri_utf8);
|
||||
g_free((char *)tel_uri_utf8);
|
||||
g_free(text_utf8);
|
||||
g_free(group_utf8);
|
||||
g_free(secondtext_utf8);
|
||||
g_free(email_utf8);
|
||||
g_free(sip_uri_utf8);
|
||||
g_free(tel_uri_utf8);
|
||||
} else {
|
||||
ofono_phonebook_entry(cbd->modem, index, number, type,
|
||||
text, hidden, group, adnumber,
|
||||
adtype, secondtext, email,
|
||||
sip_uri, tel_uri);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void export_failed(struct cb_data *cbd)
|
||||
{
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
ofono_generic_cb_t cb = cbd->cb;
|
||||
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
|
||||
g_free(cbd);
|
||||
|
||||
if (at->pb->old_charset) {
|
||||
g_free(at->pb->old_charset);
|
||||
at->pb->old_charset = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void at_read_entries_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
@ -184,102 +215,94 @@ static void at_read_entries_cb(gboolean ok, GAtResult *result,
|
|||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
ofono_generic_cb_t cb = cbd->cb;
|
||||
|
||||
if (at->pb->charset_current != at->pb->charset_origin)
|
||||
at_select_charset(modem, cb, modem);
|
||||
else {
|
||||
struct ofono_error error;
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void at_read_entries(struct ofono_modem *modem, ofono_generic_cb_t cb,
|
||||
void *data)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
struct cb_data *cbd = cb_data_new(modem, cb, data);
|
||||
const char *charset;
|
||||
struct ofono_error error;
|
||||
char buf[32];
|
||||
|
||||
if (!cbd)
|
||||
goto error;
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
g_free(cbd);
|
||||
|
||||
sprintf(buf, "AT+CPBR=%d,%d", at->pb->index_min, at->pb->index_max);
|
||||
if (g_at_chat_send_listing(at->parser, buf, entries_prefix,
|
||||
at_cpbr_notify, at_read_entries_cb,
|
||||
cbd, g_free) > 0)
|
||||
return;
|
||||
charset = best_charset(at->pb->supported);
|
||||
|
||||
error:
|
||||
if (cbd)
|
||||
g_free(cbd);
|
||||
|
||||
if (at->pb->charset_origin != at->pb->charset_current)
|
||||
/* restore the charset */
|
||||
at_select_charset(modem, cb, modem);
|
||||
else {
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, data);
|
||||
if (strcmp(at->pb->old_charset, charset)) {
|
||||
sprintf(buf, "AT+CSCS=\"%s\"", at->pb->old_charset);
|
||||
g_at_chat_send(at->parser, buf, none_prefix, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
g_free(at->pb->old_charset);
|
||||
at->pb->old_charset = NULL;
|
||||
}
|
||||
|
||||
static void at_select_charset_cb(gboolean ok, GAtResult *result,
|
||||
static void at_read_entries(struct cb_data *cbd)
|
||||
{
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
char buf[32];
|
||||
|
||||
sprintf(buf, "AT+CPBR=%d,%d", at->pb->index_min, at->pb->index_max);
|
||||
if (g_at_chat_send_listing(at->parser, buf, cpbr_prefix,
|
||||
at_cpbr_notify, at_read_entries_cb,
|
||||
cbd, NULL) > 0)
|
||||
return;
|
||||
|
||||
/* If we get here, then most likely connection to the modem dropped
|
||||
* and we can't really restore the charset anyway
|
||||
*/
|
||||
export_failed(cbd);
|
||||
}
|
||||
|
||||
static void at_set_charset_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
|
||||
if (!ok) {
|
||||
export_failed(cbd);
|
||||
return;
|
||||
}
|
||||
|
||||
at_read_entries(cbd);
|
||||
}
|
||||
|
||||
static void at_read_charset_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
ofono_generic_cb_t cb = cbd->cb;
|
||||
struct ofono_error error;
|
||||
GAtResultIter iter;
|
||||
const char *charset;
|
||||
char buf[32];
|
||||
|
||||
dump_response("at_read_charset_cb", ok, result);
|
||||
|
||||
if (!ok)
|
||||
goto out;
|
||||
goto error;
|
||||
|
||||
at->pb->charset_need_restore ^= 1;
|
||||
if (at->pb->charset_need_restore) {
|
||||
at_read_entries(modem, cb, modem);
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+CSCS:"))
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_next_string(&iter, &charset);
|
||||
|
||||
at->pb->old_charset = g_strdup(charset);
|
||||
|
||||
charset = best_charset(at->pb->supported);
|
||||
|
||||
if (!strcmp(at->pb->old_charset, charset)) {
|
||||
at_read_entries(cbd);
|
||||
return;
|
||||
}
|
||||
|
||||
out:
|
||||
decode_at_error(&error, g_at_result_final_response(result));
|
||||
cb(&error, cbd->data);
|
||||
return;
|
||||
}
|
||||
|
||||
static void at_select_charset(struct ofono_modem *modem,
|
||||
ofono_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
struct cb_data *cbd = cb_data_new(modem, cb, data);
|
||||
char buf[32];
|
||||
const char *charset;
|
||||
|
||||
if (!cbd)
|
||||
goto error;
|
||||
|
||||
if (at->pb->charset_need_restore)
|
||||
charset = at->pb->charset_origin_str;
|
||||
else if (at->pb->charset_current == CHARSET_UTF8)
|
||||
charset = "UTF-8";
|
||||
else
|
||||
charset = "UCS2";
|
||||
|
||||
sprintf(buf, "AT+CSCS=%s", charset);
|
||||
sprintf(buf, "AT+CSCS=\"%s\"", charset);
|
||||
if (g_at_chat_send(at->parser, buf, none_prefix,
|
||||
at_select_charset_cb, cbd, g_free) > 0)
|
||||
at_set_charset_cb, cbd, NULL) > 0)
|
||||
return;
|
||||
|
||||
error:
|
||||
if (cbd)
|
||||
g_free(cbd);
|
||||
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
if (at->pb->charset_need_restore)
|
||||
ofono_error("Phonebook: character can't be restored!");
|
||||
cb(&error, data);
|
||||
}
|
||||
export_failed(cbd);
|
||||
}
|
||||
|
||||
static void at_list_indices_cb(gboolean ok, GAtResult *result,
|
||||
|
@ -288,7 +311,6 @@ static void at_list_indices_cb(gboolean ok, GAtResult *result,
|
|||
struct cb_data *cbd = user_data;
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
ofono_generic_cb_t cb = cbd->cb;
|
||||
GAtResultIter iter;
|
||||
|
||||
if (!ok)
|
||||
|
@ -311,41 +333,12 @@ static void at_list_indices_cb(gboolean ok, GAtResult *result,
|
|||
if (!g_at_result_iter_close_list(&iter))
|
||||
goto error;
|
||||
|
||||
if (at->pb->charset_origin != at->pb->charset_current)
|
||||
at_select_charset(modem, cb, modem);
|
||||
else
|
||||
at_read_entries(modem, cb, modem);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
{
|
||||
DECLARE_FAILURE(e);
|
||||
cb(&e, cbd->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void at_list_indices(struct ofono_modem *modem,
|
||||
ofono_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
struct cb_data *cbd = cb_data_new(modem, cb, data);
|
||||
|
||||
if (!cbd)
|
||||
goto error;
|
||||
|
||||
if (g_at_chat_send(at->parser, "AT+CPBR=?", entries_prefix,
|
||||
at_list_indices_cb, cbd, g_free) > 0)
|
||||
if (g_at_chat_send(at->parser, "AT+CSCS?", cscs_prefix,
|
||||
at_read_charset_cb, cbd, NULL) > 0)
|
||||
return;
|
||||
|
||||
error:
|
||||
if (cbd)
|
||||
g_free(cbd);
|
||||
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, data);
|
||||
}
|
||||
export_failed(cbd);
|
||||
}
|
||||
|
||||
static void at_select_storage_cb(gboolean ok, GAtResult *result,
|
||||
|
@ -353,18 +346,22 @@ static void at_select_storage_cb(gboolean ok, GAtResult *result,
|
|||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
ofono_generic_cb_t cb = cbd->cb;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
|
||||
if (!ok) {
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, cbd->data);
|
||||
dump_response("at_select_storage_cb", ok, result);
|
||||
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
if (g_at_chat_send(at->parser, "AT+CPBR=?", cpbr_prefix,
|
||||
at_list_indices_cb, cbd, NULL) > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
at_list_indices(modem, cb, modem);
|
||||
error:
|
||||
export_failed(cbd);
|
||||
}
|
||||
|
||||
static void at_select_storage(struct ofono_modem *modem,
|
||||
static void at_export_entries(struct ofono_modem *modem, const char *storage,
|
||||
ofono_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
|
@ -374,162 +371,15 @@ static void at_select_storage(struct ofono_modem *modem,
|
|||
if (!cbd)
|
||||
goto error;
|
||||
|
||||
sprintf(buf, "AT+CPBS=%s", at->pb->storage);
|
||||
sprintf(buf, "AT+CPBS=\"%s\"", storage);
|
||||
if (g_at_chat_send(at->parser, buf, none_prefix,
|
||||
at_select_storage_cb, cbd, g_free) > 0)
|
||||
at_select_storage_cb, cbd, NULL) > 0)
|
||||
return;
|
||||
|
||||
error:
|
||||
if (cbd)
|
||||
g_free(cbd);
|
||||
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void at_read_charset_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
ofono_generic_cb_t cb = cbd->cb;
|
||||
GAtResultIter iter;
|
||||
const char *charset;
|
||||
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
|
||||
if (!g_at_result_iter_next(&iter, "+CSCS:"))
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_next_string(&iter, &charset);
|
||||
at->pb->charset_origin_str = g_strdup(charset);
|
||||
if (!strcmp(charset, "UCS2"))
|
||||
at->pb->charset_origin = CHARSET_UCS2;
|
||||
else if (!strcmp(charset, "UTF-8"))
|
||||
at->pb->charset_origin = CHARSET_UTF8;
|
||||
|
||||
if (at->pb->charset_origin & CHARSET_SUPPORT)
|
||||
at->pb->charset_current = at->pb->charset_origin;
|
||||
else if (at->pb->charset_list & CHARSET_UTF8)
|
||||
at->pb->charset_current = CHARSET_UTF8;
|
||||
else
|
||||
at->pb->charset_current = CHARSET_UCS2;
|
||||
|
||||
at_select_storage(modem, cb, modem);
|
||||
return;
|
||||
|
||||
error:
|
||||
ofono_error("Phonebook: at_read_charset_cb failed");
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void at_read_charset(struct ofono_modem *modem,
|
||||
ofono_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
struct cb_data *cbd = cb_data_new(modem, cb, data);
|
||||
|
||||
if (g_at_chat_send(at->parser, "AT+CSCS?", charset_prefix,
|
||||
at_read_charset_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, data);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean is_valid_charset_list(struct pb_data *pb)
|
||||
{
|
||||
if (!(pb->charset_list & CHARSET_SUPPORT)) {
|
||||
ofono_error("Phonebook: not a valid charset_list");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void at_list_charsets_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_modem *modem = cbd->modem;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
ofono_generic_cb_t cb = cbd->cb;
|
||||
GAtResultIter iter;
|
||||
const char *charset;
|
||||
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
if (!g_at_result_iter_next(&iter, "+CSCS:"))
|
||||
goto error;
|
||||
|
||||
while (g_at_result_iter_next_string(&iter, &charset)) {
|
||||
if (!strcmp(charset, "UTF-8"))
|
||||
at->pb->charset_list |= CHARSET_UTF8;
|
||||
else if (!strcmp(charset, "UCS2"))
|
||||
at->pb->charset_list |= CHARSET_UCS2;
|
||||
}
|
||||
|
||||
if (!is_valid_charset_list(at->pb))
|
||||
goto error;
|
||||
|
||||
at_read_charset(modem, cb, modem);
|
||||
return;
|
||||
|
||||
error:
|
||||
ofono_error("Phonebook: at_list_charsets_cb failed");
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
}
|
||||
|
||||
static void at_list_charsets(struct ofono_modem *modem,
|
||||
ofono_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
struct cb_data *cbd = cb_data_new(modem, cb, data);
|
||||
|
||||
if (g_at_chat_send(at->parser, "AT+CSCS=?", charset_prefix,
|
||||
at_list_charsets_cb, cbd, g_free) > 0)
|
||||
return;
|
||||
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, data);
|
||||
}
|
||||
}
|
||||
|
||||
static void at_export_entries(struct ofono_modem *modem, const char *storage,
|
||||
ofono_generic_cb_t cb, void *data)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
|
||||
at->pb->storage = storage;
|
||||
|
||||
if (at->pb->has_charset_info) {
|
||||
if (!is_valid_charset_list(at->pb))
|
||||
goto error;
|
||||
at_select_storage(modem, cb, modem);
|
||||
} else {
|
||||
at->pb->has_charset_info = 1;
|
||||
at_list_charsets(modem, cb, data);
|
||||
}
|
||||
return;
|
||||
|
||||
error:
|
||||
{
|
||||
DECLARE_FAILURE(error);
|
||||
cb(&error, data);
|
||||
|
@ -540,12 +390,121 @@ static struct ofono_phonebook_ops ops = {
|
|||
.export_entries = at_export_entries
|
||||
};
|
||||
|
||||
static void phonebook_not_supported(struct ofono_modem *modem)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
|
||||
ofono_error("Phonebook not supported by this modem. If this is in "
|
||||
"error please submit patches to support this hardware");
|
||||
if (at->pb) {
|
||||
phonebook_destroy(at->pb);
|
||||
at->pb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void at_list_storages_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
gboolean sm_supported = FALSE;
|
||||
gboolean me_supported = FALSE;
|
||||
gboolean in_list = FALSE;
|
||||
GAtResultIter iter;
|
||||
const char *storage;
|
||||
|
||||
dump_response("at_list_storages_cb", ok, result);
|
||||
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
if (!g_at_result_iter_next(&iter, "+CPBS:"))
|
||||
goto error;
|
||||
|
||||
/* Some modems don't report CPBS in a proper list */
|
||||
if (g_at_result_iter_open_list(&iter))
|
||||
in_list = TRUE;
|
||||
|
||||
while (g_at_result_iter_next_string(&iter, &storage)) {
|
||||
if (!strcmp(storage, "ME"))
|
||||
me_supported = TRUE;
|
||||
else if (!strcmp(storage, "SM"))
|
||||
sm_supported = TRUE;
|
||||
}
|
||||
|
||||
if (in_list && !g_at_result_iter_close_list(&iter))
|
||||
goto error;
|
||||
|
||||
if (!me_supported && !sm_supported)
|
||||
goto error;
|
||||
|
||||
ofono_phonebook_register(modem, &ops);
|
||||
return;
|
||||
|
||||
error:
|
||||
phonebook_not_supported(modem);
|
||||
}
|
||||
|
||||
static void at_list_charsets_cb(gboolean ok, GAtResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
struct ofono_modem *modem = user_data;
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
gboolean in_list = FALSE;
|
||||
GAtResultIter iter;
|
||||
const char *charset;
|
||||
|
||||
dump_response("at_list_charsets_cb", ok, result);
|
||||
|
||||
if (!ok)
|
||||
goto error;
|
||||
|
||||
g_at_result_iter_init(&iter, result);
|
||||
if (!g_at_result_iter_next(&iter, "+CSCS:"))
|
||||
goto error;
|
||||
|
||||
/* Some modems don't report CPBS in a proper list */
|
||||
if (g_at_result_iter_open_list(&iter))
|
||||
in_list = TRUE;
|
||||
|
||||
while (g_at_result_iter_next_string(&iter, &charset)) {
|
||||
if (!strcmp(charset, "UTF-8"))
|
||||
at->pb->supported |= CHARSET_UTF8;
|
||||
else if (!strcmp(charset, "UCS2"))
|
||||
at->pb->supported |= CHARSET_UCS2;
|
||||
}
|
||||
|
||||
if (in_list && g_at_result_iter_close_list(&iter))
|
||||
goto error;
|
||||
|
||||
if (!(at->pb->supported & CHARSET_SUPPORT))
|
||||
goto error;
|
||||
|
||||
if (g_at_chat_send(at->parser, "AT+CPBS=?", cpbs_prefix,
|
||||
at_list_storages_cb, modem, NULL) > 0)
|
||||
return;
|
||||
|
||||
error:
|
||||
phonebook_not_supported(modem);
|
||||
}
|
||||
|
||||
static void at_list_charsets(struct ofono_modem *modem)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
|
||||
if (g_at_chat_send(at->parser, "AT+CSCS=?", cscs_prefix,
|
||||
at_list_charsets_cb, modem, NULL) > 0)
|
||||
return;
|
||||
|
||||
phonebook_not_supported(modem);
|
||||
}
|
||||
|
||||
void at_phonebook_init(struct ofono_modem *modem)
|
||||
{
|
||||
struct at_data *at = ofono_modem_userdata(modem);
|
||||
|
||||
ofono_phonebook_register(modem, &ops);
|
||||
at->pb = phonebook_create();
|
||||
at_list_charsets(modem);
|
||||
}
|
||||
|
||||
void at_phonebook_exit(struct ofono_modem *modem)
|
||||
|
|
Loading…
Reference in New Issue