Re: [patch 6/6] Allow gsmdial to use gatchat ppp support
Hi Kristen, static GAtChat *control; static GAtChat *modem; static GMainLoop *event_loop; +static GAtPPP *ppp; I hate myself for this nitpick, but please group GAtPPP *ppp with the others before the mainloop variable. +static void print_ip_address(guint32 ip_addr) +{ + struct in_addr addr; + addr.s_addr = ip_addr; + g_print(%s\n, inet_ntoa(addr)); +} Please use print_ip_address(const char *label, guint32 ip_addr) as mentioned in the previous review. + /* open ppp */ + ppp = g_at_ppp_new(channel); + if (!ppp) { + g_print(Unable to obtain PPP object\n); + return; + } I would call it Unable to create PPP object, because you are creating. My understanding is the obtaining means that it would be there in the first place. It is a nitpick. Regards Marcel ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [patch 3/6] LCP support
Hi Kristen, Makefile.am |6 - gatchat/gatppp.c | 53 + gatchat/gatppp_internal.h |8 + gatchat/gatppplcp.c | 244 ++ this should be gatchat/ppp_lcp.c +void __ppp_set_auth(GAtPPP *ppp, guint8* auth_data) +{ + guint16 proto = ntohs(*(guint16 *)auth_data); This are again one of these constructs that will break on non-x86 hardware. I think you need to create ppp_get_unaligned and ppp_put_unaligned. If all of them are be16 anyway, you could do ppp_get_unaligned_be16 etc. Regards Marcel ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 02/11] Add framework of server parser
a. The parser fetch and parse one command per loop. The prefix is the command prefix without parameter. For example, the prefix of AT+CLIP=1 is +CLIP. b. Search registered notification node in command_list. Invoke the callback if found. c. Termiate the execution if the result is an error. Otherwise, parse next command. --- gatchat/gatserver.c | 95 +++ 1 files changed, 95 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index 46fa423..fb82ad4 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -173,8 +173,103 @@ static void g_at_server_send_final(GAtServer *server, GAtServerResult result) send_common(server, buf, MIN(len, sizeof(buf)-1)); } +static inline gboolean is_extended_command_prefix(const char c) +{ + switch (c) { + case '+': + case '*': + case '!': + case '%': + return TRUE; + default: + return FALSE; + } +} + +static gboolean is_basic_command_prefix(const char *buf) +{ + if (g_ascii_isalpha(buf[0])) + return TRUE; + + if (buf[0] == '' g_ascii_isalpha(buf[1])) + return TRUE; + + return FALSE; +} + +static GAtServerResult at_command_notify(GAtServer *server, char *command, + char *prefix) +{ + GAtServerResult res = G_AT_SERVER_RESULT_ERROR; + + return res; +} + +static char *parse_extended_command(GAtServer *server, const char *buf, + char *prefix) +{ + return NULL; +} + +static char *parse_basic_command(GAtServer *server, const char *buf, + char *prefix) +{ + return NULL; +} + +static char *parse_next_command(GAtServer *server, const char *buf, + char *prefix) +{ + char *command = NULL; + char c = *buf; + + /* fetch one command and get its prefix */ + if (is_extended_command_prefix(c)) + command = parse_extended_command(server, buf, prefix); + else if (is_basic_command_prefix(buf)) + command = parse_basic_command(server, buf, prefix); + + return command; +} + static void server_parse_line(GAtServer *server, char *line) { + GAtServerResult res = G_AT_SERVER_RESULT_ERROR; + char *buf = line; + char *command = NULL; + char prefix[20]; + + while (buf) { + char c = *buf; + + /* skip semicolon */ + if (c == ';') + c = *(++buf); + + if (c == '\0') { + res = G_AT_SERVER_RESULT_OK; + break; + } + + command = parse_next_command(server, buf, prefix); + if (!command) { + res = G_AT_SERVER_RESULT_ERROR; + break; + } + + res = at_command_notify(server, command, prefix); + if (res != G_AT_SERVER_RESULT_OK) { + g_free(command); + break; + } + + buf += strlen(command); + + g_free(command); + } + + g_at_server_send_final(server, res); + g_free(line); } -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 05/11] Add server at command data structure
--- gatchat/gatserver.c | 27 +++ gatchat/gatserver.h | 22 ++ 2 files changed, 49 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index f3807eb..bbaef52 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -88,6 +88,13 @@ struct v250_settings { unsigned int c108; /* set by Dval */ }; +/* AT command set that server supported */ +struct at_command { + GAtServerNotifyFunc notify; + gpointer user_data; + GDestroyNotify destroy_notify; +}; + struct _GAtServer { gint ref_count; /* Ref count */ struct v250_settings v250; /* V.250 command setting */ @@ -99,6 +106,7 @@ struct _GAtServer { gpointer user_disconnect_data; /* User disconnect data */ GAtDebugFunc debugf;/* Debugging output function */ gpointer debug_data;/* Data to pass to debug func */ + GHashTable *command_list; /* List of supported at command */ struct ring_buffer *read_buf; /* Current read buffer */ GQueue *write_queue;/* Write buffer queue */ guint max_read_attempts;/* Max reads per select */ @@ -733,6 +741,9 @@ static void g_at_server_cleanup(GAtServer *server) /* Cleanup pending data to write */ write_queue_free(server-write_queue); + g_hash_table_destroy(server-command_list); + server-command_list = NULL; + server-channel = NULL; } @@ -778,6 +789,16 @@ static void v250_settings_create(struct v250_settings *v250) v250-c108 = 0; } +static void at_notify_node_destroy(gpointer data) +{ + struct at_command *node = data; + + if (node-destroy_notify) + node-destroy_notify(node-user_data); + + g_free(node); +} + GAtServer *g_at_server_new(GIOChannel *io) { GAtServer *server; @@ -792,6 +813,9 @@ GAtServer *g_at_server_new(GIOChannel *io) server-ref_count = 1; v250_settings_create(server-v250); server-channel = io; + server-command_list = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, + at_notify_node_destroy); server-read_buf = ring_buffer_new(BUF_SIZE); if (!server-read_buf) goto error; @@ -816,6 +840,9 @@ GAtServer *g_at_server_new(GIOChannel *io) return server; error: + if (server-command_list) + g_hash_table_destroy(server-command_list); + if (server-read_buf) ring_buffer_free(server-read_buf); diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h index 698f7e0..1c12a0d 100644 --- a/gatchat/gatserver.h +++ b/gatchat/gatserver.h @@ -26,6 +26,7 @@ extern C { #endif +#include gatresult.h #include gatutil.h struct _GAtServer; @@ -46,6 +47,27 @@ enum _GAtServerResult { typedef enum _GAtServerResult GAtServerResult; +/* Types of AT command: + * COMMAND_ONLY: command without any sub-parameters, e.g. ATA, AT+CLCC + * QUERY: command followed by '?', e.g. AT+CPIN? + * SUPPORT: command followed by '=?', e.g. AT+CSMS=? + * SET: command followed by '=', e.g. AT+CLIP=1 + * or, basic command followed with sub-parameters, e.g. ATD12345; + */ +enum _GAtServerRequestType { + G_AT_SERVER_REQUEST_TYPE_ERROR, + G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY, + G_AT_SERVER_REQUEST_TYPE_QUERY, + G_AT_SERVER_REQUEST_TYPE_SUPPORT, + G_AT_SERVER_REQUEST_TYPE_SET, +}; + +typedef enum _GAtServerRequestType GAtServerRequestType; + +typedef GAtServerResult (*GAtServerNotifyFunc)(GAtServerRequestType type, + GAtResult *result, + gpointer user_data); + GAtServer *g_at_server_new(GIOChannel *io); GAtServer *g_at_server_ref(GAtServer *server); -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 07/11] Add g_at_server_register and unregister callback
--- gatchat/gatserver.c | 48 gatchat/gatserver.h |6 ++ 2 files changed, 54 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index 6e3347c..c17a7b5 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -970,3 +970,51 @@ gboolean g_at_server_set_debug(GAtServer *server, GAtDebugFunc func, return TRUE; } + +gboolean g_at_server_register(GAtServer *server, char *prefix, + GAtServerNotifyFunc notify, + gpointer user_data, + GDestroyNotify destroy_notify) +{ + struct at_command *node; + + if (server == NULL || server-command_list == NULL) + return FALSE; + + if (notify == NULL) + return FALSE; + + if (prefix == NULL || strlen(prefix) == 0) + return FALSE; + + node = g_try_new0(struct at_command, 1); + if (!node) + return FALSE; + + node-notify = notify; + node-user_data = user_data; + node-destroy_notify = destroy_notify; + + g_hash_table_replace(server-command_list, g_strdup(prefix), node); + + return TRUE; +} + +gboolean g_at_server_unregister(GAtServer *server, const char *prefix) +{ + struct at_command *node; + + if (server == NULL || server-command_list == NULL) + return FALSE; + + if (prefix == NULL || strlen(prefix) == 0) + return FALSE; + + node = g_hash_table_lookup(server-command_list, prefix); + if (!node) + return FALSE; + + g_hash_table_remove(server-command_list, prefix); + + return TRUE; +} diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h index 1c12a0d..5e9eb62 100644 --- a/gatchat/gatserver.h +++ b/gatchat/gatserver.h @@ -81,6 +81,12 @@ gboolean g_at_server_set_debug(GAtServer *server, GAtDebugFunc func, gpointer user); +gboolean g_at_server_register(GAtServer *server, char *prefix, + GAtServerNotifyFunc notify, + gpointer user_data, + GDestroyNotify destroy_notify); +gboolean g_at_server_unregister(GAtServer *server, const char *prefix); + #ifdef __cplusplus } #endif -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 08/11] Add G_AT_SERVER_RESULT_EXT_ERROR
--- gatchat/gatserver.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.h b/gatchat/gatserver.h index 5e9eb62..6fb78bd 100644 --- a/gatchat/gatserver.h +++ b/gatchat/gatserver.h @@ -43,6 +43,7 @@ enum _GAtServerResult { G_AT_SERVER_RESULT_NO_DIALTONE = 6, G_AT_SERVER_RESULT_BUSY = 7, G_AT_SERVER_RESULT_NO_ANSWER = 8, + G_AT_SERVER_RESULT_EXT_ERROR = 256, }; typedef enum _GAtServerResult GAtServerResult; -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 01/11] Rename g_at_server_send_result
Hi On 03/17/2010 10:30 PM, Zhang, Zhenhua wrote: Rename it to g_at_server_send_final. --- gatchat/gatserver.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) Sorry, I forgot the first patch. Please review the first patch as attached. Otherwise, these patches could not be applied. Thanks. Zhenhua From 588126076e1fc10f57b75afe734d51046ab46d6d Mon Sep 17 00:00:00 2001 From: Zhenhua Zhang zhenhua.zh...@intel.com Date: Wed, 17 Mar 2010 16:36:22 +0800 Subject: [PATCH] Remove old server_parse_line --- gatchat/gatserver.c | 49 - 1 files changed, 0 insertions(+), 49 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index 079451f..7577de2 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -173,57 +173,8 @@ static void g_at_server_send_result(GAtServer *server, GAtServerResult result) send_common(server, buf, MIN(len, sizeof(buf)-1)); } -static inline gboolean is_at_command_prefix(const char c) -{ - switch (c) { - case '+': - case '*': - case '!': - case '%': - return TRUE; - default: - return FALSE; - } -} - -static void parse_at_command(GAtServer *server, char *buf) -{ - g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR); -} - -static void parse_v250_settings(GAtServer *server, char *buf) -{ - g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR); -} - static void server_parse_line(GAtServer *server, char *line) { - gsize i = 0; - char c; - - if (line == NULL) { - g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR); - goto done; - } - - if (line[0] == '\0') { - g_at_server_send_result(server, G_AT_SERVER_RESULT_OK); - goto done; - } - - c = line[i]; - /* skip semicolon */ - if (c == ';') - c = line[++i]; - - if (is_at_command_prefix(c) || c == 'A' || c == 'D' || c == 'H') - parse_at_command(server, line + i); - else if (g_ascii_isalpha(c) || c == '') - parse_v250_settings(server, line + i); - else - g_at_server_send_result(server, G_AT_SERVER_RESULT_ERROR); - -done: g_free(line); } -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 1/6] Add register S3 basic command callback
--- gatchat/gatserver.c | 54 +++ 1 files changed, 54 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index 06ea912..80e6d45 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -233,6 +233,53 @@ void g_at_server_send_info_text(GAtServer *server, GSList *text) send_common(server, buf, len); } +static GAtServerResult at_s3_cb(GAtServerRequestType type, GAtResult *result, + gpointer user_data) +{ + GAtServerResult res = G_AT_SERVER_RESULT_ERROR; + GAtServer *server = user_data; + GSList *text = NULL; + char buf[20]; + + if (type == G_AT_SERVER_REQUEST_TYPE_SET) { + GAtResultIter iter; + int val = 13; + + g_at_result_iter_init(iter, result); + + if (!g_at_result_iter_next(iter, S3=)) + goto done; + + if (!g_at_result_iter_next_number(iter, val)) + goto done; + + if (val 0 || val 127) + goto done; + + server-v250.s3 = val; + + res = G_AT_SERVER_RESULT_OK; + } else if (type == G_AT_SERVER_REQUEST_TYPE_QUERY) { + sprintf(buf, %03d, server-v250.s3); + text = g_slist_append(NULL, buf); + g_at_server_send_info_text(server, text); + + res = G_AT_SERVER_RESULT_OK; + } else if (type == G_AT_SERVER_REQUEST_TYPE_SUPPORT) { + sprintf(buf, S3: (0-127)); + text = g_slist_append(NULL, buf); + g_at_server_send_info_text(server, text); + + res = G_AT_SERVER_RESULT_OK; + } + + if (text) + g_slist_free(text); + +done: + return res; +} + static inline gboolean is_extended_command_prefix(const char c) { switch (c) { @@ -889,6 +936,11 @@ static void at_notify_node_destroy(gpointer data) g_free(node); } +static void basic_command_register(GAtServer *server) +{ + g_at_server_register(server, S3, at_s3_cb, server, NULL); +} + GAtServer *g_at_server_new(GIOChannel *io) { GAtServer *server; @@ -927,6 +979,8 @@ GAtServer *g_at_server_new(GIOChannel *io) received_data, server, (GDestroyNotify)read_watcher_destroy_notify); + basic_command_register(server); + return server; error: -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 0/6] Add test cases for GAtServer
These patches register callback functions for each AT command. Patch #1-#5 register basic commands into gatserver.c. Patch #6 add a simple voice call test case in test-server.c. TODO: 1. ATE,ATV,ATQ could share a template function. 2. Register more basic commands defined in 27.007. ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 2/6] Add register S5 basic command callback
--- gatchat/gatserver.c | 48 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index 80e6d45..1a8ac58 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -280,6 +280,53 @@ done: return res; } +static GAtServerResult at_s5_cb(GAtServerRequestType type, GAtResult *result, + gpointer user_data) +{ + GAtServerResult res = G_AT_SERVER_RESULT_ERROR; + GAtServer *server = user_data; + GSList *text = NULL; + char buf[20]; + + if (type == G_AT_SERVER_REQUEST_TYPE_SET) { + GAtResultIter iter; + int val; + + g_at_result_iter_init(iter, result); + + if (!g_at_result_iter_next(iter, S5=)) + goto done; + + if (!g_at_result_iter_next_number(iter, val)) + goto done; + + if (val 0 || val 127) + goto done; + + server-v250.s5 = val; + + res = G_AT_SERVER_RESULT_OK; + } else if (type == G_AT_SERVER_REQUEST_TYPE_QUERY) { + sprintf(buf, %03d, server-v250.s5); + text = g_slist_append(NULL, buf); + g_at_server_send_info_text(server, text); + + res = G_AT_SERVER_RESULT_OK; + } else if (type == G_AT_SERVER_REQUEST_TYPE_SUPPORT) { + sprintf(buf, S5: (0-127)); + text = g_slist_append(NULL, buf); + g_at_server_send_info_text(server, text); + + res = G_AT_SERVER_RESULT_OK; + } + + if (text) + g_slist_free(text); + +done: + return res; +} + static inline gboolean is_extended_command_prefix(const char c) { switch (c) { @@ -939,6 +986,7 @@ static void at_notify_node_destroy(gpointer data) static void basic_command_register(GAtServer *server) { g_at_server_register(server, S3, at_s3_cb, server, NULL); + g_at_server_register(server, S5, at_s5_cb, server, NULL); } GAtServer *g_at_server_new(GIOChannel *io) -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
[PATCH 5/6] Add register ATV basic command callback
--- gatchat/gatserver.c | 51 +++ 1 files changed, 51 insertions(+), 0 deletions(-) diff --git a/gatchat/gatserver.c b/gatchat/gatserver.c index e9b1cf4..5a234d6 100644 --- a/gatchat/gatserver.c +++ b/gatchat/gatserver.c @@ -427,6 +427,56 @@ done: return res; } +static GAtServerResult at_v_cb(GAtServerRequestType type, GAtResult *result, + gpointer user_data) +{ + GAtServerResult res = G_AT_SERVER_RESULT_ERROR; + GAtServer *server = user_data; + GSList *text = NULL; + char buf[20]; + + if (type == G_AT_SERVER_REQUEST_TYPE_SET) { + GAtResultIter iter; + int val; + + g_at_result_iter_init(iter, result); + + if (!g_at_result_iter_next(iter, V)) + goto done; + + if (!g_at_result_iter_next_number(iter, val)) + goto done; + + if (val 0 || val 1) + goto done; + + server-v250.is_v1 = val; + + res = G_AT_SERVER_RESULT_OK; + } else if (type == G_AT_SERVER_REQUEST_TYPE_QUERY) { + sprintf(buf, V: %u, server-v250.is_v1); + text = g_slist_append(NULL, buf); + g_at_server_send_info_text(server, text); + + res = G_AT_SERVER_RESULT_OK; + } else if (type == G_AT_SERVER_REQUEST_TYPE_SUPPORT) { + sprintf(buf, V: (0-1)); + text = g_slist_append(NULL, buf); + g_at_server_send_info_text(server, text); + + res = G_AT_SERVER_RESULT_OK; + } else if (type == G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY) { + server-v250.is_v1 = 1; + res = G_AT_SERVER_RESULT_OK; + } + + if (text) + g_slist_free(text); + +done: + return res; +} + static inline gboolean is_extended_command_prefix(const char c) { switch (c) { @@ -1089,6 +1139,7 @@ static void basic_command_register(GAtServer *server) g_at_server_register(server, S5, at_s5_cb, server, NULL); g_at_server_register(server, E, at_e_cb, server, NULL); g_at_server_register(server, Q, at_q_cb, server, NULL); + g_at_server_register(server, V, at_v_cb, server, NULL); } GAtServer *g_at_server_new(GIOChannel *io) -- 1.6.6.1 ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 5/8][RFC] STATUS, FETCH and TERMINAL RESPONSE for AT driver.
Hi Andrew, Fix ENVELOPE implementation. @@ -753,7 +794,7 @@ static void at_sim_envelope(struct ofono_sim *sim, int length, ofono_sim_read_cb_t cb, void *data) { struct sim_data *sd = ofono_sim_get_data(sim); - struct cb_data *cbd = cb_data_new(cb, data); + struct sim_cb_data *cbd = sim_cb_data_new(sd, cb, data); char *buf = g_try_new(char, 64 + length * 2); int len, ret; @@ -761,12 +802,14 @@ static void at_sim_envelope(struct ofono_sim *sim, int length, goto error; len = sprintf(buf, AT+CSIM=%i,A0C2%02hhX, - 10 + length * 2, length); + 12 + length * 2, length); for (; length; length--) len += sprintf(buf + len, %02hhX, *command++); - ret = g_at_chat_send(sd-chat, buf, crsm_prefix, + len += sprintf(buf + len, FF); + + ret = g_at_chat_send(sd-chat, buf, csim_prefix, at_csim_envelope_cb, cbd, g_free); I really need more detailed explanation why appending FF here is necessary. And this really belongs in a separate patch. g_free(buf); @@ -785,6 +828,219 @@ error: CALLBACK_WITH_FAILURE(cb, NULL, 0, data); } Regards, -Denis ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 7/8][RFC] Invalidate SIM manager properties when SIM extracted, add Present property.
Hi Andrew, --- src/sim.c | 107 ++--- 1 files changed, 95 insertions(+), 12 deletions(-) diff --git a/src/sim.c b/src/sim.c index cddb3e4..fe535bb 100644 --- a/src/sim.c +++ b/src/sim.c @@ -285,6 +285,7 @@ static DBusMessage *sim_get_properties(DBusConnection *conn, char **service_numbers; char **locked_pins; const char *pin_name; + dbus_bool_t present = sim-inserted; reply = dbus_message_new_method_return(msg); if (!reply) @@ -296,6 +297,8 @@ static DBusMessage *sim_get_properties(DBusConnection *conn, OFONO_PROPERTIES_ARRAY_SIGNATURE, dict); + ofono_dbus_dict_append(dict, Present, DBUS_TYPE_BOOLEAN, present); + I suggest you simply skip the rest of the properties if Present is false and skip checking each and every one afterwards. @@ -992,6 +1001,8 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi, void *data) { struct ofono_sim *sim = data; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(sim-atom); if (error-type != OFONO_ERROR_TYPE_NO_ERROR) { ofono_error(Unable to read IMSI, emergency calls only); @@ -1000,6 +1011,11 @@ static void sim_imsi_cb(const struct ofono_error *error, const char *imsi, sim-imsi = g_strdup(imsi); + ofono_dbus_signal_property_changed(conn, path, + SIM_MANAGER_INTERFACE, + SubscriberIdentity, + DBUS_TYPE_STRING, sim-imsi); + /* Read CPHS-support bits, this is still part of the SIM * initialisation but no order is specified for it. */ ofono_sim_read(sim, SIM_EF_CPHS_INFORMATION_FILEID, @@ -1755,9 +1771,21 @@ const unsigned char *ofono_sim_get_cphs_service_table(struct ofono_sim *sim) return sim-cphs_service_table; } +static void sim_inserted_update(struct ofono_sim *sim) +{ + dbus_bool_t present = sim-inserted; + DBusConnection *conn = ofono_dbus_get_connection(); + const char *path = __ofono_atom_get_path(sim-atom); + + ofono_dbus_signal_property_changed(conn, path, + SIM_MANAGER_INTERFACE, Present, + DBUS_TYPE_BOOLEAN, present); +} + void ofono_sim_inserted(struct ofono_sim *sim) { sim-inserted = TRUE; + sim_inserted_update(sim); /* Perform SIM initialization according to 3GPP 31.102 Section 5.1.1.2 * The assumption here is that if sim manager is being initialized, @@ -1781,6 +1809,18 @@ void ofono_sim_inserted(struct ofono_sim *sim) sim_determine_phase(sim); } +static void sim_file_op_fail(struct sim_file_op *op) +{ + if (op-is_read == TRUE) + ((ofono_sim_file_read_cb_t) op-cb) + (0, 0, 0, 0, 0, op-userdata); + else + ((ofono_sim_file_write_cb_t) op-cb) + (0, op-userdata); + + sim_file_op_free(op); +} + void ofono_sim_removed(struct ofono_sim *sim) { GSList *l; @@ -1790,18 +1830,61 @@ void ofono_sim_removed(struct ofono_sim *sim) return; sim-inserted = FALSE; + sim_inserted_update(sim); if (sim-ready == FALSE) return; sim-ready = FALSE; + if (sim-simop_source) { + g_source_remove(sim-simop_source); + sim-simop_source = 0; + } + + if (sim-simop_q) { + /* NOTE: there's an assumption here that the op's callback + * does not queue new ops on failure... */ + g_queue_foreach(sim-simop_q, (GFunc) sim_file_op_fail, NULL); + g_queue_free(sim-simop_q); + sim-simop_q = NULL; + } + You have to be really careful here, it is possible that we have an operation pending with the driver, so the driver will call back for that one. Also, since you're removing everything anyway I see no need to call the error callback. for (l = sim-removed_watches-items; l; l = l-next) { struct ofono_watchlist_item *item = l-data; notify = item-notify; notify(item-notify_data); } + + if (sim-imsi) { + g_free(sim-imsi); + sim-imsi = NULL; + } + + if (sim-own_numbers) { + g_slist_foreach(sim-own_numbers, (GFunc)g_free, NULL); + g_slist_free(sim-own_numbers); + sim-own_numbers = NULL; + } + + if (sim-service_numbers) { + g_slist_foreach(sim-service_numbers, + (GFunc)service_number_free, NULL); + g_slist_free(sim-service_numbers); + sim-service_numbers = NULL; + } + + if (sim-efli) { + g_free(sim-efli); + sim-efli = NULL; +
SIM ToolKit support
Hi, Is there anybody can share me some information about SIM Toolkit support by ofono? Current status, any schedule to support STK? Regards, Johnson ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [PATCH 3/8][RFC] Release calls when SIM is removed.
Hi Andrew, --- src/voicecall.c | 63 -- 1 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/voicecall.c b/src/voicecall.c index 18b923f..eef924c 100644 --- a/src/voicecall.c +++ b/src/voicecall.c @@ -57,6 +57,8 @@ struct ofono_voicecall { gint emit_calls_source; gint emit_multi_source; unsigned int sim_watch; + unsigned int sim_ready_watch; + unsigned int sim_removed_watch; const struct ofono_voicecall_driver *driver; void *driver_data; struct ofono_atom *atom; @@ -1788,6 +1790,10 @@ static void voicecall_unregister(struct ofono_atom *atom) static void voicecall_remove(struct ofono_atom *atom) { struct ofono_voicecall *vc = __ofono_atom_get_data(atom); + struct ofono_modem *modem = __ofono_atom_get_modem(vc-atom); + struct ofono_atom *sim_atom = + __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM); + struct ofono_sim *sim = NULL; DBG(atom: %p, atom); @@ -1809,6 +1815,19 @@ static void voicecall_remove(struct ofono_atom *atom) vc-new_en_list = NULL; } + if (sim_atom __ofono_atom_get_registered(sim_atom)) + sim = __ofono_atom_get_data(sim_atom); + + if (sim vc-sim_ready_watch) { + ofono_sim_remove_ready_watch(sim, vc-sim_ready_watch); + vc-sim_ready_watch = 0; + } + + if (sim vc-sim_removed_watch) { + ofono_sim_remove_removed_watch(sim, vc-sim_removed_watch); + vc-sim_removed_watch = 0; + } + g_free(vc); } @@ -1847,6 +1866,34 @@ struct ofono_voicecall *ofono_voicecall_create(struct ofono_modem *modem, return vc; } +static void sim_ready_watch(void *user) +{ + struct ofono_voicecall *vc = user; + struct ofono_modem *modem = __ofono_atom_get_modem(vc-atom); + struct ofono_atom *sim_atom = + __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM); + struct ofono_sim *sim = __ofono_atom_get_data(sim_atom); + + /* Try both formats, only one or none will work */ + ofono_sim_read(sim, SIM_EFECC_FILEID, + OFONO_SIM_FILE_STRUCTURE_TRANSPARENT, + ecc_g2_read_cb, vc); + ofono_sim_read(sim, SIM_EFECC_FILEID, + OFONO_SIM_FILE_STRUCTURE_FIXED, + ecc_g3_read_cb, vc); +} So does sim_ready now have a different semantic than it used to? (e.g. PIN entered successfully) EFecc has to be read when sim is inserted, not when the SIM is truly ready. + +static void sim_removed_watch(void *user) +{ + struct ofono_voicecall *vc = user; + + vc-flags |= VOICECALLS_FLAG_MULTI_RELEASE; + + /* TODO: Don't hang up emergency calls */ + voicecalls_release_queue(vc, vc-call_list); + voicecalls_release_next(vc); For now I suggest relying on the modem to tells us which calls have been removed. You must also reset and signal the emergency number list. +} + static void sim_watch(struct ofono_atom *atom, enum ofono_atom_watch_condition cond, void *data) { @@ -1854,16 +1901,18 @@ static void sim_watch(struct ofono_atom *atom, struct ofono_sim *sim = __ofono_atom_get_data(atom); if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) { + vc-sim_ready_watch = 0; + vc-sim_removed_watch = 0; return; } - /* Try both formats, only one or none will work */ - ofono_sim_read(sim, SIM_EFECC_FILEID, - OFONO_SIM_FILE_STRUCTURE_TRANSPARENT, - ecc_g2_read_cb, vc); - ofono_sim_read(sim, SIM_EFECC_FILEID, - OFONO_SIM_FILE_STRUCTURE_FIXED, - ecc_g3_read_cb, vc); + vc-sim_ready_watch = ofono_sim_add_ready_watch(sim, + sim_ready_watch, vc, NULL); + vc-sim_removed_watch = ofono_sim_add_removed_watch(sim, + sim_removed_watch, vc, NULL); + + if (ofono_sim_get_ready(sim)) + sim_ready_watch(vc); } void ofono_voicecall_register(struct ofono_voicecall *vc) ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono
Re: [patch 5/6] IP support for PPP
On Tue, 16 Mar 2010 23:38:33 -0700 Marcel Holtmann mar...@holtmann.org wrote: +static guint32 bytes_to_32(guint8 *bytes) +{ + union addr { + guint8 bytes[4]; + guint32 word; + } a; + + memcpy(a.bytes, bytes, 4); + return(ntohl(a.word)); +} This works, but is pretty ugly. Doesn't GLib has functions to ensure retrieve unaligned data? BlueZ has the GCC magic that is required to do this right. I have looked everywhere for something nice from glib, but I'm not seeing it. As far as I can tell, most people just do the bit shifting manually -- but that's what I had originally and you didn't like it. So I'm only seeing 2 options here, this way or the original way. If you know of the glib function to use, please let me know what it is. ___ ofono mailing list ofono@ofono.org http://lists.ofono.org/listinfo/ofono