Crash in network-registration.c/creg_notify() when receiving unsolicited +CREG: 0

2010-08-10 Thread Berthier, Emmanuel
Hi,

I use ofono 0.25 and encounter a segmentation fault when trying to put the 
modem OffLine (flight mode).
The AT command sent to modem is:
AT+CFUN=4
The modem replies with:
OK
+CREG=0

Then, in creg_notify(), the user_data points to uninitialized (deallocated?) 
memory and access to nd-vendor causes the crash.

Effectivelly, user_data pointer is the one set by at_creg_set_cb(), and is 
freed by g_at_chat_finish_command()/at_command_destroy().

So, it seems that ofono does not manage unsolicited +CREG command.

What's your feeing?

Thanks.

Emmanuel.

-
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: Les Montalets- 2, rue de Paris, 
92196 Meudon Cedex, France
Registration Number:  302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.
___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


RE: Crash in network-registration.c/creg_notify() when receiving unsolicited +CREG: 0

2010-08-10 Thread Zhang, Zhenhua
Hi Emmanuel,

Berthier, Emmanuel wrote:
 Hi,
 
 I use ofono 0.25 and encounter a segmentation fault when
 trying to put the modem OffLine (flight mode).
 
 The AT command sent to modem is:
 
 AT+CFUN=4
 
 The modem replies with:
OK
+CREG=0
 
 Then, in creg_notify(), the user_data points to uninitialized
 (deallocated?) memory and access to “nd-vendor” causes the crash.
 

I might know where is the problem. We should unregister all notifies from 
gatchat in at_netreg_remove. Same for gprs and other drivers as well. 
Currently, we don't do that well. I will send patches soon.

 
 Effectivelly, user_data pointer is the one set by
 at_creg_set_cb(), and is freed by
 g_at_chat_finish_command()/at_command_destroy().
 
 So, it seems that ofono does not manage unsolicited +CREG command.
 
 
 
 What’s your feeing?
 
 
 
 Thanks.
 
 
 
 Emmanuel.
 
 
 
 -
 Intel Corporation SAS (French simplified joint stock company)
 Registered headquarters: Les Montalets- 2, rue de Paris, 92196
 Meudon Cedex, France Registration Number:  302 456 199 R.C.S. NANTERRE
 Capital: 4,572,000 Euros
 
 This e-mail and any attachments may contain confidential material for
 the sole use of the intended recipient(s). Any review or distribution
 by others is strictly prohibited. If you are not the intended
 recipient, please contact the sender and delete all copies.



Regards,
Zhenhua

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 1/2] huawei: poll sim state

2010-08-10 Thread Kalle Valo
On my Huawei E1552 when I plug in the modem (ie. cold start) with PIN locked
SIM, the sim state is 255 (HUAWEI_SIM_STATE_NOT_EXISTENT). As the modem
doesn't send ^SIMST notifications, poll the sim state until it's ready.

In theory it might be possible to do this better, for example follow
^BOOT notifications or something, but it's unknown what parameter we
should check for.
---
 plugins/huawei.c |   34 ++
 1 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/plugins/huawei.c b/plugins/huawei.c
index f8ada24..ba66513 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -73,8 +73,11 @@ struct huawei_data {
enum huawei_sim_state sim_state;
struct ofono_gprs *gprs;
struct ofono_gprs_context *gc;
+   guint query_sim_state;
 };
 
+static gboolean query_sim_state(gpointer user_data);
+
 static int huawei_probe(struct ofono_modem *modem)
 {
struct huawei_data *data;
@@ -114,8 +117,15 @@ static void notify_sim_state(struct ofono_modem *modem,
 {
struct huawei_data *data = ofono_modem_get_data(modem);
 
-   if (sim_state == HUAWEI_SIM_STATE_NOT_EXISTENT)
+   DBG(%d, sim_state);
+
+   if (sim_state == HUAWEI_SIM_STATE_NOT_EXISTENT) {
ofono_sim_inserted_notify(data-sim, FALSE);
+
+   /* SIM is not ready, try again a bit later */
+   data-query_sim_state =
+   g_timeout_add_seconds(2, query_sim_state, modem);
+   }
else
ofono_sim_inserted_notify(data-sim, TRUE);
 
@@ -154,6 +164,21 @@ static void sysinfo_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
notify_sim_state(modem, (enum huawei_sim_state) sim_state);
 }
 
+static gboolean query_sim_state(gpointer user_data)
+{
+   struct ofono_modem *modem = user_data;
+   struct huawei_data *data = ofono_modem_get_data(modem);
+
+   DBG();
+
+   data-query_sim_state = 0;
+
+   g_at_chat_send(data-pcui, AT^SYSINFO, sysinfo_prefix,
+   sysinfo_cb, modem, NULL);
+
+   return FALSE;
+}
+
 static void simst_notify(GAtResult *result, gpointer user_data)
 {
struct ofono_modem *modem = user_data;
@@ -187,9 +212,7 @@ static void cfun_enable(gboolean ok, GAtResult *result, 
gpointer user_data)
g_at_chat_register(data-pcui, ^SIMST:, simst_notify,
FALSE, modem, NULL);
 
-   /* query current sim state */
-   g_at_chat_send(data-pcui, AT^SYSINFO, sysinfo_prefix,
-   sysinfo_cb, modem, NULL);
+   query_sim_state(modem);
 }
 
 static GAtChat *create_port(const char *device)
@@ -319,6 +342,9 @@ static int huawei_disable(struct ofono_modem *modem)
 
DBG(%p, modem);
 
+   if (data-query_sim_state)
+   g_source_remove(data-query_sim_state);
+
if (data-modem) {
g_at_chat_cancel_all(data-modem);
g_at_chat_unregister_all(data-modem);

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 2/2] huawei: postpone post_sim until SIM is ready

2010-08-10 Thread Kalle Valo
On my Huawei E1552 with PIN locked SIM sim_state is 0 when calling
huawei_post_sim() and gprs context is not registered. This is because
^SIMST notification is received only after huawei_post_sim() is called:

Aug 10 12:38:33 tukki ofonod[6565]: plugins/huawei.c:huawei_post_sim() 0x6cdb50
[...]
Aug 10 12:38:34 tukki ofonod[6565]: Pcui: \r\n^SIMST:1\r\n\r\n^SRVST:2\r\n
Aug 10 12:38:34 tukki ofonod[6565]: plugins/huawei.c:notify_sim_state() 1

Add a test to wait for sim_state to be ready and also a call to
notify_sim_state() to call huawei_post_sim() whenever needed.
---
 plugins/huawei.c |  102 ++
 1 files changed, 56 insertions(+), 46 deletions(-)

diff --git a/plugins/huawei.c b/plugins/huawei.c
index ba66513..582cba6 100644
--- a/plugins/huawei.c
+++ b/plugins/huawei.c
@@ -74,6 +74,7 @@ struct huawei_data {
struct ofono_gprs *gprs;
struct ofono_gprs_context *gc;
guint query_sim_state;
+   gboolean post_sim;
 };
 
 static gboolean query_sim_state(gpointer user_data);
@@ -112,6 +113,58 @@ static void huawei_debug(const char *str, void *user_data)
ofono_info(%s%s, prefix, str);
 }
 
+static void huawei_post_sim(struct ofono_modem *modem)
+{
+   struct huawei_data *data = ofono_modem_get_data(modem);
+   struct ofono_netreg *netreg;
+   struct ofono_message_waiting *mw;
+
+   DBG(%p sim_state %d, modem, data-sim_state);
+
+   if (data-sim_state == HUAWEI_SIM_STATE_INVALID_OR_LOCKED) {
+   /* let's wait for ^SIMST notification so that SIM is ready */
+   data-post_sim = TRUE;
+   return;
+   }
+
+   if (data-sim_state == HUAWEI_SIM_STATE_INVALID_PS_AND_CS) {
+   ofono_phonebook_create(modem, 0, atmodem, data-pcui);
+   return;
+   }
+
+   netreg = ofono_netreg_create(modem, OFONO_VENDOR_HUAWEI, atmodem,
+   data-pcui);
+
+   ofono_sms_create(modem, OFONO_VENDOR_HUAWEI, atmodem, data-pcui);
+   ofono_cbs_create(modem, OFONO_VENDOR_QUALCOMM_MSM, atmodem,
+   data-pcui);
+   ofono_ussd_create(modem, 0, atmodem, data-pcui);
+   ofono_phonebook_create(modem, 0, atmodem, data-pcui);
+
+   if (data-sim_state == HUAWEI_SIM_STATE_VALID ||
+   data-sim_state == HUAWEI_SIM_STATE_INVALID_CS) {
+   data-gprs = ofono_gprs_create(modem, 0, atmodem, data-pcui);
+   data-gc = ofono_gprs_context_create(modem, 0, atmodem,
+   data-modem);
+
+   if (data-gprs  data-gc)
+   ofono_gprs_add_context(data-gprs, data-gc);
+   }
+
+   if ((data-sim_state == HUAWEI_SIM_STATE_VALID ||
+   data-sim_state == HUAWEI_SIM_STATE_INVALID_PS) 
+   ofono_modem_get_boolean(modem, HasVoice) == TRUE) {
+   ofono_call_forwarding_create(modem, 0, atmodem, data-pcui);
+   ofono_call_settings_create(modem, 0, atmodem, data-pcui);
+   ofono_call_barring_create(modem, 0, atmodem, data-pcui);
+   ofono_ssn_create(modem, 0, atmodem, data-pcui);
+
+   mw = ofono_message_waiting_create(modem);
+   if (mw)
+   ofono_message_waiting_register(mw);
+   }
+}
+
 static void notify_sim_state(struct ofono_modem *modem,
enum huawei_sim_state sim_state)
 {
@@ -130,6 +183,9 @@ static void notify_sim_state(struct ofono_modem *modem,
ofono_sim_inserted_notify(data-sim, TRUE);
 
data-sim_state = sim_state;
+
+   if (data-post_sim)
+   huawei_post_sim(modem);
 }
 
 static void sysinfo_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -378,52 +434,6 @@ static void huawei_pre_sim(struct ofono_modem *modem)
ofono_voicecall_create(modem, 0, atmodem, data-pcui);
 }
 
-static void huawei_post_sim(struct ofono_modem *modem)
-{
-   struct huawei_data *data = ofono_modem_get_data(modem);
-   struct ofono_netreg *netreg;
-   struct ofono_message_waiting *mw;
-
-   DBG(%p, modem);
-
-   if (data-sim_state == HUAWEI_SIM_STATE_INVALID_PS_AND_CS) {
-   ofono_phonebook_create(modem, 0, atmodem, data-pcui);
-   return;
-   }
-
-   netreg = ofono_netreg_create(modem, OFONO_VENDOR_HUAWEI, atmodem,
-   data-pcui);
-
-   ofono_sms_create(modem, OFONO_VENDOR_HUAWEI, atmodem, data-pcui);
-   ofono_cbs_create(modem, OFONO_VENDOR_QUALCOMM_MSM, atmodem,
-   data-pcui);
-   ofono_ussd_create(modem, 0, atmodem, data-pcui);
-   ofono_phonebook_create(modem, 0, atmodem, data-pcui);
-
-   if (data-sim_state == 

[PATCH 02/10] gprs: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifiers when removing gprs driver.
---
 drivers/atmodem/gprs.c |   12 +---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/atmodem/gprs.c b/drivers/atmodem/gprs.c
index bf82d06..dcf9759 100644
--- a/drivers/atmodem/gprs.c
+++ b/drivers/atmodem/gprs.c
@@ -48,6 +48,8 @@ static const char *none_prefix[] = { NULL };
 struct gprs_data {
GAtChat *chat;
unsigned int vendor;
+   guint cgev_id;
+   guint cgreg_id;
 };
 
 static void at_cgatt_cb(gboolean ok, GAtResult *result, gpointer user_data)
@@ -181,9 +183,10 @@ static void gprs_initialized(gboolean ok, GAtResult 
*result, gpointer user_data)
struct ofono_gprs *gprs = user_data;
struct gprs_data *gd = ofono_gprs_get_data(gprs);
 
-   g_at_chat_register(gd-chat, +CGEV:, cgev_notify, FALSE, gprs, NULL);
-   g_at_chat_register(gd-chat, +CGREG:, cgreg_notify,
-   FALSE, gprs, NULL);
+   gd-cgev_id = g_at_chat_register(gd-chat, +CGEV:, cgev_notify,
+   FALSE, gprs, NULL);
+   gd-cgreg_id = g_at_chat_register(gd-chat, +CGREG:, cgreg_notify,
+   FALSE, gprs, NULL);
 
ofono_gprs_register(gprs);
 }
@@ -321,6 +324,9 @@ static void at_gprs_remove(struct ofono_gprs *gprs)
 {
struct gprs_data *gd = ofono_gprs_get_data(gprs);
 
+   g_at_chat_unregister(gd-chat, gd-cgev_id);
+   g_at_chat_unregister(gd-chat, gd-cgreg_id);
+
ofono_gprs_set_data(gprs, NULL);
g_free(gd);
 }
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 04/10] cbs: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifications when removing cbs driver.
---
 drivers/atmodem/cbs.c |6 +-
 1 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/atmodem/cbs.c b/drivers/atmodem/cbs.c
index a1c4037..ef312e9 100644
--- a/drivers/atmodem/cbs.c
+++ b/drivers/atmodem/cbs.c
@@ -47,6 +47,7 @@ struct cbs_data {
GAtChat *chat;
gboolean cscb_mode_1;
unsigned int vendor;
+   guint cbm_id;
 };
 
 static void at_cbm_notify(GAtResult *result, gpointer user_data)
@@ -182,7 +183,8 @@ static void at_cbs_register(gboolean ok, GAtResult *result, 
gpointer user)
 * The default SMS driver will setup the CNMI for +CBM delivery
 * appropriately for us
 */
-   g_at_chat_register(data-chat, +CBM:, at_cbm_notify, TRUE, cbs, NULL);
+   data-cbm_id = g_at_chat_register(data-chat, +CBM:,
+   at_cbm_notify, TRUE, cbs, NULL);
 
ofono_cbs_register(cbs);
 }
@@ -252,6 +254,8 @@ static void at_cbs_remove(struct ofono_cbs *cbs)
 {
struct cbs_data *data = ofono_cbs_get_data(cbs);
 
+   g_at_chat_unregister(data-chat, data-cbm_id);
+
ofono_cbs_set_data(cbs, NULL);
 
g_free(data);
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 05/10] ussd: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Add struct ussd_data to hold gatchat and cusd_id. So that we could
unregister AT notifications in driver removing phase.
---
 drivers/atmodem/ussd.c |   33 ++---
 1 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/atmodem/ussd.c b/drivers/atmodem/ussd.c
index 555ce13..0def9b1 100644
--- a/drivers/atmodem/ussd.c
+++ b/drivers/atmodem/ussd.c
@@ -47,6 +47,11 @@ struct cusd_req {
struct ofono_ussd *ussd;
 };
 
+struct ussd_data {
+   GAtChat *chat;
+   guint cusd_id;
+};
+
 static const char *cusd_prefix[] = { +CUSD:, NULL };
 static const char *none_prefix[] = { NULL };
 
@@ -119,7 +124,7 @@ static void cusd_request_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
 static void at_ussd_request(struct ofono_ussd *ussd, const char *str,
ofono_ussd_cb_t cb, void *data)
 {
-   GAtChat *chat = ofono_ussd_get_data(ussd);
+   struct ussd_data *ud = ofono_ussd_get_data(ussd);
struct cusd_req *cbd = g_try_new0(struct cusd_req, 1);
unsigned char *converted = NULL;
int dcs;
@@ -152,7 +157,7 @@ static void at_ussd_request(struct ofono_ussd *ussd, const 
char *str,
g_free(converted);
converted = NULL;
 
-   if (g_at_chat_send(chat, buf, cusd_prefix,
+   if (g_at_chat_send(ud-chat, buf, cusd_prefix,
cusd_request_cb, cbd, g_free)  0)
return;
 
@@ -180,13 +185,13 @@ static void cusd_cancel_cb(gboolean ok, GAtResult 
*result, gpointer user_data)
 static void at_ussd_cancel(struct ofono_ussd *ussd,
ofono_ussd_cb_t cb, void *data)
 {
-   GAtChat *chat = ofono_ussd_get_data(ussd);
+   struct ussd_data *ud = ofono_ussd_get_data(ussd);
struct cb_data *cbd = cb_data_new(cb, data);
 
if (!cbd)
goto error;
 
-   if (g_at_chat_send(chat, AT+CUSD=2, none_prefix,
+   if (g_at_chat_send(ud-chat, AT+CUSD=2, none_prefix,
cusd_cancel_cb, cbd, g_free)  0)
return;
 
@@ -207,14 +212,16 @@ static void cusd_notify(GAtResult *result, gpointer 
user_data)
 static void at_ussd_register(gboolean ok, GAtResult *result, gpointer user)
 {
struct ofono_ussd *ussd = user;
-   GAtChat *chat = ofono_ussd_get_data(ussd);
+   struct ussd_data *data = ofono_ussd_get_data(ussd);
 
if (!ok) {
ofono_error(Could not enable CUSD notifications);
return;
}
 
-   g_at_chat_register(chat, +CUSD:, cusd_notify, FALSE, ussd, NULL);
+   data-cusd_id = g_at_chat_register(data-chat, +CUSD:,
+   cusd_notify, FALSE,
+   ussd, NULL);
 
ofono_ussd_register(ussd);
 }
@@ -223,8 +230,13 @@ static int at_ussd_probe(struct ofono_ussd *ussd, unsigned 
int vendor,
void *data)
 {
GAtChat *chat = data;
+   struct ussd_data *ud;
+
+   ud = g_new0(struct ussd_data, 1);
+
+   ud-chat = chat;
 
-   ofono_ussd_set_data(ussd, chat);
+   ofono_ussd_set_data(ussd, ud);
 
g_at_chat_send(chat, AT+CUSD=1, NULL, at_ussd_register, ussd, NULL);
 
@@ -233,6 +245,13 @@ static int at_ussd_probe(struct ofono_ussd *ussd, unsigned 
int vendor,
 
 static void at_ussd_remove(struct ofono_ussd *ussd)
 {
+   struct ussd_data *ud = ofono_ussd_get_data(ussd);
+
+   g_at_chat_unregister(ud-chat, ud-cusd_id);
+
+   ofono_ussd_set_data(ussd, NULL);
+
+   g_free(ud);
 }
 
 static struct ofono_ussd_driver driver = {
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 07/10] stk: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifications when removing stk driver.
---
 drivers/atmodem/stk.c |   11 +--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/atmodem/stk.c b/drivers/atmodem/stk.c
index d6c19da..de687f8 100644
--- a/drivers/atmodem/stk.c
+++ b/drivers/atmodem/stk.c
@@ -44,6 +44,8 @@
 struct stk_data {
GAtChat *chat;
unsigned int vendor;
+   guint tcmd_id;
+   guint tend_id;
 };
 
 static const char *csim_prefix[] = { +CSIM:, NULL };
@@ -294,10 +296,12 @@ static gboolean at_stk_register(gpointer user)
struct stk_data *sd = ofono_stk_get_data(stk);
 
if (sd-vendor == OFONO_VENDOR_PHONESIM) {
-   g_at_chat_register(sd-chat, *TCMD:, phonesim_tcmd_notify,
+   sd-tcmd_id = g_at_chat_register(sd-chat, *TCMD:,
+   phonesim_tcmd_notify,
FALSE, stk, NULL);
 
-   g_at_chat_register(sd-chat, *TEND, phonesim_tend_notify,
+   sd-tend_id = g_at_chat_register(sd-chat, *TEND,
+   phonesim_tend_notify,
FALSE, stk, NULL);
}
 
@@ -325,6 +329,9 @@ static void at_stk_remove(struct ofono_stk *stk)
 {
struct stk_data *sd = ofono_stk_get_data(stk);
 
+   g_at_chat_unregister(sd-chat, sd-tcmd_id);
+   g_at_chat_unregister(sd-chat, sd-tend_id);
+
ofono_stk_set_data(stk, NULL);
 
g_free(sd);
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 08/10] sms: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifiers when removing sms driver.
---
 drivers/atmodem/sms.c |   31 +--
 1 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/atmodem/sms.c b/drivers/atmodem/sms.c
index ba98c12..335f456 100644
--- a/drivers/atmodem/sms.c
+++ b/drivers/atmodem/sms.c
@@ -78,6 +78,11 @@ struct sms_data {
guint timeout_source;
GAtChat *chat;
unsigned int vendor;
+   guint cmti_id;
+   guint cmt_id;
+   guint cds_id;
+   guint cdsi_id;
+   guint cmgr_id;
 };
 
 struct cpms_request {
@@ -599,18 +604,18 @@ static void at_cmgl_done(struct ofono_sms *sms)
return;
}
 
-   g_at_chat_register(data-chat, +CMTI:, at_cmti_notify, FALSE,
-   sms, NULL);
-   g_at_chat_register(data-chat, +CMT:, at_cmt_notify, TRUE,
-   sms, NULL);
-   g_at_chat_register(data-chat, +CDS:, at_cds_notify, TRUE,
-   sms, NULL);
-   g_at_chat_register(data-chat, +CDSI:, at_cdsi_notify, FALSE,
-   sms, NULL);
+   data-cmti_id = g_at_chat_register(data-chat, +CMTI:, at_cmti_notify,
+   FALSE, sms, NULL);
+   data-cmt_id = g_at_chat_register(data-chat, +CMT:, at_cmt_notify,
+   TRUE, sms, NULL);
+   data-cds_id = g_at_chat_register(data-chat, +CDS:, at_cds_notify,
+   TRUE, sms, NULL);
+   data-cdsi_id = g_at_chat_register(data-chat, +CDSI:, at_cdsi_notify,
+   FALSE, sms, NULL);
 
/* We treat CMGR just like a notification */
-   g_at_chat_register(data-chat, +CMGR:, at_cmgr_notify, TRUE,
-   sms, NULL);
+   data-cmgr_id = g_at_chat_register(data-chat, +CMGR:, at_cmgr_notify,
+   TRUE, sms, NULL);
 }
 
 static void at_cmgl_notify(GAtResult *result, gpointer user_data)
@@ -1233,6 +1238,12 @@ static void at_sms_remove(struct ofono_sms *sms)
if (data-timeout_source  0)
g_source_remove(data-timeout_source);
 
+   g_at_chat_unregister(data-chat, data-cmti_id);
+   g_at_chat_unregister(data-chat, data-cmt_id);
+   g_at_chat_unregister(data-chat, data-cds_id);
+   g_at_chat_unregister(data-chat, data-cdsi_id);
+   g_at_chat_unregister(data-chat, data-cmgr_id);
+
g_free(data);
 }
 
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 09/10] call-meter: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifiers when removing call-meter at modem driver.
---
 drivers/atmodem/call-meter.c |   55 -
 1 files changed, 37 insertions(+), 18 deletions(-)

diff --git a/drivers/atmodem/call-meter.c b/drivers/atmodem/call-meter.c
index 38774d4..f36ff3c 100644
--- a/drivers/atmodem/call-meter.c
+++ b/drivers/atmodem/call-meter.c
@@ -45,6 +45,12 @@ static const char *cacm_prefix[] = { +CACM:, NULL };
 static const char *camm_prefix[] = { +CAMM:, NULL };
 static const char *cpuc_prefix[] = { +CPUC:, NULL };
 
+struct cm_data {
+   GAtChat *chat;
+   guint cccm_id;
+   guint ccwv_id;
+};
+
 static void caoc_cacm_camm_query_cb(gboolean ok,
GAtResult *result, gpointer user_data)
 {
@@ -113,14 +119,14 @@ static void at_caoc_query(struct ofono_call_meter *cm,
ofono_call_meter_query_cb_t cb,
void *data)
 {
-   GAtChat *chat = ofono_call_meter_get_data(cm);
+   struct cm_data *cd = ofono_call_meter_get_data(cm);
struct cb_data *cbd = cb_data_new(cb, data);
 
if (!cbd)
goto error;
 
cbd-user = +CAOC:;
-   if (g_at_chat_send(chat, AT+CAOC=0, caoc_prefix,
+   if (g_at_chat_send(cd-chat, AT+CAOC=0, caoc_prefix,
caoc_cacm_camm_query_cb, cbd, g_free)  0)
return;
 
@@ -135,14 +141,14 @@ static void at_cacm_query(struct ofono_call_meter *cm,
ofono_call_meter_query_cb_t cb,
void *data)
 {
-   GAtChat *chat = ofono_call_meter_get_data(cm);
+   struct cm_data *cd = ofono_call_meter_get_data(cm);
struct cb_data *cbd = cb_data_new(cb, data);
 
if (!cbd)
goto error;
 
cbd-user = +CACM:;
-   if (g_at_chat_send(chat, AT+CACM?, cacm_prefix,
+   if (g_at_chat_send(cd-chat, AT+CACM?, cacm_prefix,
caoc_cacm_camm_query_cb, cbd, g_free)  0)
return;
 
@@ -167,7 +173,7 @@ static void generic_set_cb(gboolean ok, GAtResult *result, 
gpointer user_data)
 static void at_cacm_set(struct ofono_call_meter *cm, const char *passwd,
ofono_call_meter_set_cb_t cb, void *data)
 {
-   GAtChat *chat = ofono_call_meter_get_data(cm);
+   struct cm_data *cd = ofono_call_meter_get_data(cm);
struct cb_data *cbd = cb_data_new(cb, data);
char buf[64];
 
@@ -176,7 +182,7 @@ static void at_cacm_set(struct ofono_call_meter *cm, const 
char *passwd,
 
snprintf(buf, sizeof(buf), AT+CACM=\%s\, passwd);
 
-   if (g_at_chat_send(chat, buf, none_prefix,
+   if (g_at_chat_send(cd-chat, buf, none_prefix,
generic_set_cb, cbd, g_free)  0)
return;
 
@@ -191,14 +197,14 @@ static void at_camm_query(struct ofono_call_meter *cm,
ofono_call_meter_query_cb_t cb,
void *data)
 {
-   GAtChat *chat = ofono_call_meter_get_data(cm);
+   struct cm_data *cd = ofono_call_meter_get_data(cm);
struct cb_data *cbd = cb_data_new(cb, data);
 
if (!cbd)
goto error;
 
cbd-user = +CAMM:;
-   if (g_at_chat_send(chat, AT+CAMM?, camm_prefix,
+   if (g_at_chat_send(cd-chat, AT+CAMM?, camm_prefix,
caoc_cacm_camm_query_cb, cbd, g_free)  0)
return;
 
@@ -213,7 +219,7 @@ static void at_camm_set(struct ofono_call_meter *cm,
int accmax, const char *passwd,
ofono_call_meter_set_cb_t cb, void *data)
 {
-   GAtChat *chat = ofono_call_meter_get_data(cm);
+   struct cm_data *cd = ofono_call_meter_get_data(cm);
struct cb_data *cbd = cb_data_new(cb, data);
char buf[64];
 
@@ -222,7 +228,7 @@ static void at_camm_set(struct ofono_call_meter *cm,
 
snprintf(buf, sizeof(buf), AT+CAMM=\%06X\,\%s\, accmax, passwd);
 
-   if (g_at_chat_send(chat, buf, none_prefix,
+   if (g_at_chat_send(cd-chat, buf, none_prefix,
generic_set_cb, cbd, g_free)  0)
return;
 
@@ -276,14 +282,14 @@ error:
 static void at_cpuc_query(struct ofono_call_meter *cm,
ofono_call_meter_puct_query_cb_t cb, void *data)
 {
-   GAtChat *chat = ofono_call_meter_get_data(cm);
+   struct cm_data *cd = ofono_call_meter_get_data(cm);
struct cb_data *cbd = cb_data_new(cb, data);
 
if (!cbd)
goto error;
 
cbd-user = +CPUC:;
-   if (g_at_chat_send(chat, AT+CPUC?, cpuc_prefix,
+   if (g_at_chat_send(cd-chat, AT+CPUC?, cpuc_prefix,
cpuc_query_cb, cbd, g_free)  0)
return;
 
@@ -298,7 +304,7 @@ static void at_cpuc_set(struct ofono_call_meter *cm, const 
char *currency,
double ppu, const char *passwd,
 

[PATCH 10/10] voicecall: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifiers when removing voicecall driver.
---
 drivers/atmodem/voicecall.c |   40 +++-
 1 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/drivers/atmodem/voicecall.c b/drivers/atmodem/voicecall.c
index fce9144..16b3069 100644
--- a/drivers/atmodem/voicecall.c
+++ b/drivers/atmodem/voicecall.c
@@ -56,6 +56,13 @@ struct voicecall_data {
unsigned int local_release;
unsigned int clcc_source;
GAtChat *chat;
+   guint ring_id;
+   guint cring_id;
+   guint clip_id;
+   guint ccwa_id;
+   guint no_carrier_id;
+   guint no_answer_id;
+   guint busy_id;
 };
 
 struct release_id_req {
@@ -814,19 +821,26 @@ static void at_voicecall_initialized(gboolean ok, 
GAtResult *result,
 
DBG(voicecall_init: registering to notifications);
 
-   g_at_chat_register(vd-chat, RING, ring_notify, FALSE, vc, NULL);
-   g_at_chat_register(vd-chat, +CRING:, cring_notify, FALSE, vc, NULL);
-   g_at_chat_register(vd-chat, +CLIP:, clip_notify, FALSE, vc, NULL);
-   g_at_chat_register(vd-chat, +CCWA:, ccwa_notify, FALSE, vc, NULL);
+   vd-ring_id = g_at_chat_register(vd-chat, RING, ring_notify,
+   FALSE, vc, NULL);
+   vd-cring_id = g_at_chat_register(vd-chat, +CRING:, cring_notify,
+   FALSE, vc, NULL);
+   vd-clip_id = g_at_chat_register(vd-chat, +CLIP:, clip_notify,
+   FALSE, vc, NULL);
+   vd-ccwa_id = g_at_chat_register(vd-chat, +CCWA:, ccwa_notify,
+   FALSE, vc, NULL);
 
/* Modems with 'better' call progress indicators should
 * probably not even bother registering to these
 */
-   g_at_chat_register(vd-chat, NO CARRIER,
-   no_carrier_notify, FALSE, vc, NULL);
-   g_at_chat_register(vd-chat, NO ANSWER,
-   no_answer_notify, FALSE, vc, NULL);
-   g_at_chat_register(vd-chat, BUSY, busy_notify, FALSE, vc, NULL);
+   vd-no_carrier_id = g_at_chat_register(vd-chat, NO CARRIER,
+   no_carrier_notify,
+   FALSE, vc, NULL);
+   vd-no_answer_id = g_at_chat_register(vd-chat, NO ANSWER,
+   no_answer_notify,
+   FALSE, vc, NULL);
+   vd-busy_id = g_at_chat_register(vd-chat, BUSY, busy_notify,
+   FALSE, vc, NULL);
 
ofono_voicecall_register(vc);
 
@@ -863,6 +877,14 @@ static void at_voicecall_remove(struct ofono_voicecall *vc)
g_slist_foreach(vd-calls, (GFunc) g_free, NULL);
g_slist_free(vd-calls);
 
+   g_at_chat_unregister(vd-chat, vd-ring_id);
+   g_at_chat_unregister(vd-chat, vd-cring_id);
+   g_at_chat_unregister(vd-chat, vd-clip_id);
+   g_at_chat_unregister(vd-chat, vd-ccwa_id);
+   g_at_chat_unregister(vd-chat, vd-no_carrier_id);
+   g_at_chat_unregister(vd-chat, vd-no_answer_id);
+   g_at_chat_unregister(vd-chat, vd-busy_id);
+
ofono_voicecall_set_data(vc, NULL);
 
g_free(vd);
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 03/10] netreg: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifications when removing network registeration driver.
---
 drivers/atmodem/network-registration.c |   49 ---
 1 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/drivers/atmodem/network-registration.c 
b/drivers/atmodem/network-registration.c
index b8ec012..8b52bbe 100644
--- a/drivers/atmodem/network-registration.c
+++ b/drivers/atmodem/network-registration.c
@@ -57,6 +57,9 @@ struct netreg_data {
int signal_max; /* max strength reported via CIND */
int tech;
unsigned int vendor;
+   guint ciev_id;
+   guint creg_id;
+   guint vendor_id;
 };
 
 struct tech_query {
@@ -945,10 +948,10 @@ static void cind_support_cb(gboolean ok, GAtResult 
*result, gpointer user_data)
 
g_at_chat_send(nd-chat, AT+CMER=3,0,0,1, NULL,
NULL, NULL, NULL);
-   g_at_chat_register(nd-chat, +CIEV:,
-   ciev_notify, FALSE, netreg, NULL);
-   g_at_chat_register(nd-chat, +CREG:,
-   creg_notify, FALSE, netreg, NULL);
+   nd-ciev_id = g_at_chat_register(nd-chat, +CIEV:, ciev_notify,
+   FALSE, netreg, NULL);
+   nd-creg_id = g_at_chat_register(nd-chat, +CREG:, creg_notify,
+   FALSE, netreg, NULL);
 
ofono_netreg_register(netreg);
return;
@@ -975,22 +978,25 @@ static void at_creg_set_cb(gboolean ok, GAtResult 
*result, gpointer user_data)
 
switch (nd-vendor) {
case OFONO_VENDOR_PHONESIM:
-   g_at_chat_register(nd-chat, +CSQ:,
-   csq_notify, FALSE, netreg, NULL);
+   nd-vendor_id = g_at_chat_register(nd-chat, +CSQ:,
+   csq_notify,
+   FALSE, netreg, NULL);
break;
case OFONO_VENDOR_CALYPSO:
g_at_chat_send(nd-chat, AT%CSQ=1, none_prefix,
NULL, NULL, NULL);
-   g_at_chat_register(nd-chat, %CSQ:, calypso_csq_notify,
-   FALSE, netreg, NULL);
+   nd-vendor_id = g_at_chat_register(nd-chat, %CSQ:,
+   calypso_csq_notify,
+   FALSE, netreg, NULL);
break;
case OFONO_VENDOR_OPTION_HSO:
g_at_chat_send(nd-chat, AT_OSSYS=1, none_prefix,
NULL, NULL, NULL);
g_at_chat_send(nd-chat, AT_OSQI=1, none_prefix,
NULL, NULL, NULL);
-   g_at_chat_register(nd-chat, _OSIGQ:, option_osigq_notify,
-   FALSE, netreg, NULL);
+   nd-vendor_id = g_at_chat_register(nd-chat, _OSIGQ:,
+   option_osigq_notify,
+   FALSE, netreg, NULL);
 
g_at_chat_send(nd-chat, AT_OSSYS?, none_prefix,
NULL, NULL, NULL);
@@ -1000,8 +1006,9 @@ static void at_creg_set_cb(gboolean ok, GAtResult 
*result, gpointer user_data)
case OFONO_VENDOR_MBM:
g_at_chat_send(nd-chat, AT*ERINFO=1, none_prefix,
NULL, NULL, NULL);
-   g_at_chat_register(nd-chat, *ERINFO:, mbm_erinfo_notify,
-   FALSE, netreg, NULL);
+   nd-vendor_id = g_at_chat_register(nd-chat, *ERINFO:,
+   mbm_erinfo_notify,
+   FALSE, netreg, NULL);
g_at_chat_send(nd-chat, AT+CIND=?, cind_prefix,
cind_support_cb, netreg, NULL);
return;
@@ -1011,12 +1018,14 @@ static void at_creg_set_cb(gboolean ok, GAtResult 
*result, gpointer user_data)
 * of technology changes, but register a handle for
 * CNTI so we get notified by any query.
 */
-   g_at_chat_register(nd-chat, $CNTI:, nw_cnti_notify,
-   FALSE, netreg, NULL);
+   nd-vendor_id = g_at_chat_register(nd-chat, $CNTI:,
+   nw_cnti_notify,
+   FALSE, netreg, NULL);
break;
case OFONO_VENDOR_HUAWEI:
-   g_at_chat_register(nd-chat, ^RSSI:, huawei_rssi_notify,
-   FALSE, netreg, NULL);
+   nd-vendor_id = g_at_chat_register(nd-chat, ^RSSI:,
+   huawei_rssi_notify,
+   FALSE, netreg, NULL);

[PATCH 06/10] ssn: Unregister AT notifiers when removing

2010-08-10 Thread Zhenhua Zhang
Unregister AT notifications when removing ssn driver.
---
 drivers/atmodem/ssn.c |   30 ++
 1 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/atmodem/ssn.c b/drivers/atmodem/ssn.c
index f219cde..ce8f1e0 100644
--- a/drivers/atmodem/ssn.c
+++ b/drivers/atmodem/ssn.c
@@ -39,6 +39,12 @@
 
 static const char *none_prefix[] = { NULL };
 
+struct ssn_data {
+   GAtChat *chat;
+   guint cssi_id;
+   guint cssu_id;
+};
+
 static void cssi_notify(GAtResult *result, gpointer user_data)
 {
struct ofono_ssn *ssn = user_data;
@@ -100,10 +106,12 @@ static void at_ssn_initialized(gboolean ok, GAtResult 
*result,
gpointer user_data)
 {
struct ofono_ssn *ssn = user_data;
-   GAtChat *chat = ofono_ssn_get_data(ssn);
+   struct ssn_data *sd = ofono_ssn_get_data(ssn);
 
-   g_at_chat_register(chat, +CSSI:, cssi_notify, FALSE, ssn, NULL);
-   g_at_chat_register(chat, +CSSU:, cssu_notify, FALSE, ssn, NULL);
+   sd-cssi_id = g_at_chat_register(sd-chat, +CSSI:, cssi_notify,
+   FALSE, ssn, NULL);
+   sd-cssu_id = g_at_chat_register(sd-chat, +CSSU:, cssu_notify,
+   FALSE, ssn, NULL);
 
ofono_ssn_register(ssn);
 }
@@ -112,8 +120,14 @@ static int at_ssn_probe(struct ofono_ssn *ssn, unsigned 
int vendor,
void *data)
 {
GAtChat *chat = data;
+   struct ssn_data *sd;
+
+   sd = g_new0(struct ssn_data, 1);
+
+   sd-chat = chat;
+
+   ofono_ssn_set_data(ssn, sd);
 
-   ofono_ssn_set_data(ssn, chat);
g_at_chat_send(chat, AT+CSSN=1,1, none_prefix,
at_ssn_initialized, ssn, NULL);
 
@@ -122,6 +136,14 @@ static int at_ssn_probe(struct ofono_ssn *ssn, unsigned 
int vendor,
 
 static void at_ssn_remove(struct ofono_ssn *ssn)
 {
+   struct ssn_data *sd = ofono_ssn_get_data(ssn);
+
+   g_at_chat_unregister(sd-chat, sd-cssi_id);
+   g_at_chat_unregister(sd-chat, sd-cssu_id);
+
+   ofono_ssn_set_data(ssn, NULL);
+
+   g_free(sd);
 }
 
 static struct ofono_ssn_driver driver = {
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 00/16] Implement DUN server for oFono

2010-08-10 Thread Zhenhua Zhang
Hi,

These patches are based my 6 patches sent on Aug 5th. It implements DUN server 
logic to manage GPRS context create/destroy per DUN client requests. On DUN 
client side, you can use 'rfcomm bind 0 xx:xx:xx:xx:xx:xx 1' and then 'gsmdial 
-n /dev/rfcomm0 -c 1 -a cid -l' to test it.

Review comments are welcome!

Regards,
Zhenhua

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 02/16] emulator: Add status watches for ofono emulator

2010-08-10 Thread Zhenhua Zhang
The status watches monitor the emulator activities. Other atoms like
gprs, netreg could register notification to watch emulator status
changes.
---
 include/emulator.h |6 +
 src/emulator.c |   60 
 src/ofono.h|   11 +
 3 files changed, 77 insertions(+), 0 deletions(-)

diff --git a/include/emulator.h b/include/emulator.h
index 1033e59..29e87b9 100644
--- a/include/emulator.h
+++ b/include/emulator.h
@@ -30,6 +30,12 @@ extern C {
 
 struct ofono_emulator;
 
+enum ofono_emulator_status {
+   OFONO_EMULATOR_STATUS_IDLE = 0,
+   OFONO_EMULATOR_STATUS_CREATE,
+   OFONO_EMULATOR_STATUS_DESTROY,
+};
+
 struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
enum ofono_atom_type type,
GIOChannel *io);
diff --git a/src/emulator.c b/src/emulator.c
index 6219bb1..f9e82a0 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -39,6 +39,8 @@ struct ofono_emulator {
enum ofono_atom_type type;
unsigned int id;
GAtServer *server;
+   enum ofono_emulator_status status;
+   struct ofono_watchlist *status_watches;
 };
 
 static unsigned int ofono_emulator_ids;
@@ -69,12 +71,31 @@ static void ofono_emulator_release_id(int id)
ofono_emulator_ids = ~(0x1  id);
 }
 
+static void notify_status_watches(struct ofono_emulator *e, void *data)
+{
+   struct ofono_watchlist_item *item;
+   ofono_emulator_status_notify_cb_t notify;
+   GSList *l;
+
+   for (l = e-status_watches-items; l; l = l-next) {
+   item = l-data;
+   notify = item-notify;
+
+   notify(e, e-status, data, item-notify_data);
+   }
+}
+
 static void emulator_remove(struct ofono_atom *atom)
 {
struct ofono_emulator *e =  __ofono_atom_get_data(atom);
 
DBG();
 
+   e-status = OFONO_EMULATOR_STATUS_DESTROY;
+   notify_status_watches(e, NULL);
+
+   __ofono_watchlist_free(e-status_watches);
+
g_at_server_shutdown(e-server);
g_at_server_unref(e-server);
e-server = NULL;
@@ -84,6 +105,37 @@ static void emulator_remove(struct ofono_atom *atom)
e = NULL;
 }
 
+unsigned int __ofono_emulator_add_status_watch(struct ofono_emulator *e,
+   ofono_emulator_status_notify_cb_t notify,
+   void *data, ofono_destroy_func destroy)
+{
+   struct ofono_watchlist_item *item;
+
+   DBG(%p, e);
+
+   if (e == NULL)
+   return 0;
+
+   if (notify == NULL)
+   return 0;
+
+   item = g_new0(struct ofono_watchlist_item, 1);
+
+   item-notify = notify;
+   item-destroy = destroy;
+   item-notify_data = data;
+
+   return __ofono_watchlist_add_item(e-status_watches, item);
+}
+
+gboolean __ofono_emulator_remove_status_watch(struct ofono_emulator *e,
+   unsigned int id)
+{
+   DBG(%p, e);
+
+   return __ofono_watchlist_remove_item(e-status_watches, id);
+}
+
 static void emulator_disconnect(gpointer user_data)
 {
struct ofono_emulator *e = user_data;
@@ -91,6 +143,10 @@ static void emulator_disconnect(gpointer user_data)
__ofono_atom_free(e-atom);
 }
 
+static void emulator_unregister(struct ofono_atom *atom)
+{
+}
+
 struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
enum ofono_atom_type type,
GIOChannel *channel)
@@ -115,7 +171,11 @@ struct ofono_emulator *ofono_emulator_create(struct 
ofono_modem *modem,
e-modem = modem;
e-type = type;
e-id = ofono_emulator_next_id();
+   e-status_watches = __ofono_watchlist_new(g_free);
+   e-status = OFONO_EMULATOR_STATUS_CREATE;
e-atom = __ofono_modem_add_atom(modem, type, emulator_remove, e);
 
+   __ofono_atom_register(e-atom, emulator_unregister);
+
return e;
 }
diff --git a/src/ofono.h b/src/ofono.h
index 8982a95..a7a9849 100644
--- a/src/ofono.h
+++ b/src/ofono.h
@@ -292,3 +292,14 @@ void __ofono_nettime_info_received(struct ofono_modem 
*modem,
struct ofono_network_time *info);
 
 #include ofono/emulator.h
+
+typedef void (*ofono_emulator_status_notify_cb_t)(struct ofono_emulator *e,
+   enum ofono_emulator_status status,
+   void *data, void *user_data);
+
+unsigned int __ofono_emulator_add_status_watch(struct ofono_emulator *e,
+   ofono_emulator_status_notify_cb_t notify,
+   void *data, ofono_destroy_func destroy);
+
+gboolean __ofono_emulator_remove_status_watch(struct ofono_emulator *e,
+   unsigned int id);
-- 
1.7.0.4


[PATCH 06/16] gprs: Make gprs_proto_to/from_string non-static

2010-08-10 Thread Zhenhua Zhang
So DUN server could share gprs_proto_to_string and
gprs_proto_from_string.
---
 include/gprs-context.h |3 +++
 src/gprs.c |5 ++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/include/gprs-context.h b/include/gprs-context.h
index f4c7321..de170b8 100644
--- a/include/gprs-context.h
+++ b/include/gprs-context.h
@@ -84,6 +84,9 @@ void *ofono_gprs_context_get_data(struct ofono_gprs_context 
*gc);
 
 struct ofono_modem *ofono_gprs_context_get_modem(struct ofono_gprs_context 
*gc);
 
+gboolean gprs_proto_from_string(const char *str, enum ofono_gprs_proto *proto);
+const char *gprs_proto_to_string(enum ofono_gprs_proto proto);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gprs.c b/src/gprs.c
index 8002cf4..677ce81 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -142,7 +142,7 @@ static enum gprs_context_type 
gprs_context_string_to_type(const char *str)
return GPRS_CONTEXT_TYPE_INVALID;
 }
 
-static const char *gprs_proto_to_string(enum ofono_gprs_proto proto)
+const char *gprs_proto_to_string(enum ofono_gprs_proto proto)
 {
switch (proto) {
case OFONO_GPRS_PROTO_IP:
@@ -154,8 +154,7 @@ static const char *gprs_proto_to_string(enum 
ofono_gprs_proto proto)
return NULL;
 }
 
-static gboolean gprs_proto_from_string(const char *str,
-   enum ofono_gprs_proto *proto)
+gboolean gprs_proto_from_string(const char *str, enum ofono_gprs_proto *proto)
 {
if (g_str_equal(str, ip)) {
*proto = OFONO_GPRS_PROTO_IP;
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 09/16] gprs: Add DUN +CGATT support in gprs atom

2010-08-10 Thread Zhenhua Zhang
DUN client may request to attach/deattach GPRS network. Use
gprs_netreg_update to set attach/deattach status.
---
 src/gprs.c |   18 ++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/src/gprs.c b/src/gprs.c
index f91d0dc..5d850df 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -39,6 +39,7 @@
 #include common.h
 #include storage.h
 #include idmap.h
+#include gatserver.h
 
 #define GPRS_FLAG_ATTACHING 0x1
 #define GPRS_FLAG_RECHECK 0x2
@@ -1453,14 +1454,31 @@ void ofono_gprs_context_deactivated(struct 
ofono_gprs_context *gc,
}
 }
 
+static void ofono_gprs_set_cgatt(struct ofono_gprs *gprs,
+   struct ofono_emulator_req *req)
+{
+   int *mode = req-data;
+
+   gprs-powered = *mode;
+
+   gprs_netreg_update(gprs);
+
+   req-cb(G_AT_SERVER_RESULT_OK, req-cb_data);
+}
+
 static void dun_status_watch(struct ofono_emulator *e,
enum ofono_emulator_status status,
void *data, void *user_data)
 {
+   struct ofono_gprs *gprs = user_data;
+
if (e == NULL)
return;
 
switch (status) {
+   case OFONO_EMULATOR_STATUS_SET_CGATT:
+   ofono_gprs_set_cgatt(gprs, data);
+   break;
default:
break;
}
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 11/16] gprs: Add DUN +CGDCONT support in gprs atom

2010-08-10 Thread Zhenhua Zhang
DUN client may request to create a new context. Call
ofono_gprs_create_context to create it.
---
 src/gprs.c |   53 +
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/src/gprs.c b/src/gprs.c
index 7e85d39..2313f52 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -59,6 +59,13 @@ enum gprs_context_type {
GPRS_CONTEXT_TYPE_INVALID,
 };
 
+struct gprs_dun_data {
+   ofono_emulator_gprs_connect_cb cb;
+   void *cb_data;
+   struct pri_context *context;
+   struct pri_context *dun;
+};
+
 struct ofono_gprs {
GSList *contexts;
ofono_bool_t attached;
@@ -84,6 +91,7 @@ struct ofono_gprs {
struct ofono_emulator *dun;
unsigned int dun_watch;
unsigned int dun_status_watch;
+   struct gprs_dun_data dun_data;
 };
 
 struct ofono_gprs_context {
@@ -1542,6 +1550,48 @@ static void ofono_gprs_set_cgatt(struct ofono_gprs *gprs,
req-cb(G_AT_SERVER_RESULT_OK, req-cb_data);
 }
 
+static void ofono_gprs_set_cgdcont(struct ofono_gprs *gprs,
+   struct ofono_emulator_gprs_context_req *req)
+{
+   struct gprs_dun_data *data = gprs-dun_data;
+   struct pri_context *context = NULL;
+   enum ofono_gprs_proto proto;
+   GSList *l;
+
+   gprs_proto_from_string(req-proto, proto);
+
+   for (l = gprs-contexts; l; l = l-next) {
+   struct pri_context *ctx = l-data;
+
+   if (ctx-type != GPRS_CONTEXT_TYPE_INTERNET)
+   continue;
+
+   if (!g_str_equal(req-apn, ctx-context.apn))
+   continue;
+
+   if (proto != ctx-context.proto)
+   continue;
+
+   context = ctx;
+   break;
+   }
+
+   if (context)
+   goto done;
+
+   context = ofono_gprs_create_context(gprs, req-apn, internet);
+   if (context == NULL) {
+   req-cb(G_AT_SERVER_RESULT_ERROR, req-cb_data);
+   return;
+   }
+
+   strcpy(context-context.apn, req-apn);
+
+done:
+   data-context = context;
+   req-cb(G_AT_SERVER_RESULT_OK, req-cb_data);
+}
+
 static void dun_status_watch(struct ofono_emulator *e,
enum ofono_emulator_status status,
void *data, void *user_data)
@@ -1555,6 +1605,9 @@ static void dun_status_watch(struct ofono_emulator *e,
case OFONO_EMULATOR_STATUS_SET_CGATT:
ofono_gprs_set_cgatt(gprs, data);
break;
+   case OFONO_EMULATOR_STATUS_SET_CGDCONT:
+   ofono_gprs_set_cgdcont(gprs, data);
+   break;
default:
break;
}
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 12/16] gprs: Add DUN server GPRS connect support

2010-08-10 Thread Zhenhua Zhang
Implement dial up networking in GPRS atom.
---
 src/gprs.c |  232 +++-
 1 files changed, 229 insertions(+), 3 deletions(-)

diff --git a/src/gprs.c b/src/gprs.c
index 2313f52..95f7ab2 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -49,6 +49,10 @@
 #define MAX_CONTEXT_NAME_LENGTH 127
 #define MAX_CONTEXTS 256
 
+#define DUN_LOCAL 192.168.1.1
+#define DUN_PEER 192.168.1.2
+#define DUN_CONNECT_TIMEOUT 20
+
 static GSList *g_drivers = NULL;
 static GSList *g_context_drivers = NULL;
 
@@ -92,6 +96,9 @@ struct ofono_gprs {
unsigned int dun_watch;
unsigned int dun_status_watch;
struct gprs_dun_data dun_data;
+   int attach_source;
+   int context_source;
+   int timeout_source;
 };
 
 struct ofono_gprs_context {
@@ -124,6 +131,7 @@ struct pri_context {
 };
 
 static void gprs_netreg_update(struct ofono_gprs *gprs);
+static gboolean dun_connect_remove(gpointer user_data);
 
 static const char *gprs_context_type_to_string(int type)
 {
@@ -453,17 +461,24 @@ static void pri_activate_callback(const struct 
ofono_error *error,
if (error-type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG(Activating context failed with error: %s,
telephony_error_to_str(error));
-   __ofono_dbus_pending_reply(gc-pending,
+
+   if (gc-pending)
+   __ofono_dbus_pending_reply(gc-pending,
__ofono_error_failed(gc-pending));
 
gprs_cid_release(ctx-gprs, ctx-context.cid);
ctx-context.cid = 0;
 
+   if (ctx-gprs-dun)
+   dun_connect_remove(ctx-gprs);
+
return;
}
 
ctx-active = TRUE;
-   __ofono_dbus_pending_reply(gc-pending,
+
+   if (gc-pending)
+   __ofono_dbus_pending_reply(gc-pending,
dbus_message_new_method_return(gc-pending));
 
/* If we don't have the interface, don't bother emitting any settings,
@@ -1488,12 +1503,35 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
gprs-cid_map = idmap_new_from_range(min, max);
 }
 
+static void ofono_gprs_remove_sources(struct ofono_gprs *gprs)
+{
+   if (gprs == NULL)
+   return;
+
+   if (gprs-timeout_source) {
+   g_source_remove(gprs-timeout_source);
+   gprs-timeout_source = 0;
+   }
+
+   if (gprs-attach_source) {
+   g_source_remove(gprs-attach_source);
+   gprs-attach_source = 0;
+   }
+
+   if (gprs-context_source) {
+   g_source_remove(gprs-context_source);
+   gprs-context_source = 0;
+   }
+}
+
 static void gprs_context_unregister(struct ofono_atom *atom)
 {
struct ofono_gprs_context *gc = __ofono_atom_get_data(atom);
 
-   if (gc-gprs)
+   if (gc-gprs) {
gc-gprs-context_driver = NULL;
+   ofono_gprs_remove_sources(gc-gprs);
+   }
 
gc-gprs = NULL;
 }
@@ -1538,6 +1576,183 @@ void ofono_gprs_context_deactivated(struct 
ofono_gprs_context *gc,
}
 }
 
+static ofono_bool_t set_primary_context_powered(struct pri_context *ctx,
+   ofono_bool_t value)
+{
+   struct ofono_gprs_context *gc = ctx-gprs-context_driver;
+
+   if (gc == NULL || gc-driver-activate_primary == NULL ||
+   gc-driver-deactivate_primary == NULL ||
+   ctx-gprs-cid_map == NULL)
+   return FALSE;
+
+   if (gc-pending)
+   return FALSE;
+
+   if (ctx-active == value)
+   return FALSE;
+
+   if (value  !ctx-gprs-attached)
+   return FALSE;
+
+   if (ctx-gprs-flags  GPRS_FLAG_ATTACHING)
+   return FALSE;
+
+   if (value) {
+   ctx-context.cid = gprs_cid_alloc(ctx-gprs);
+
+   if (ctx-context.cid == 0)
+   return FALSE;
+
+   if (ctx-context.cid !=
+   idmap_get_min(ctx-gprs-cid_map)) {
+   ofono_error(Multiple active contexts are
+not yet supported);
+
+   gprs_cid_release(ctx-gprs, ctx-context.cid);
+   ctx-context.cid = 0;
+
+   return FALSE;
+   }
+   }
+
+   if (value)
+   gc-driver-activate_primary(gc, ctx-context,
+   pri_activate_callback, ctx);
+   else
+   gc-driver-deactivate_primary(gc, ctx-context.cid,
+   pri_deactivate_callback, ctx);
+
+   return TRUE;
+}
+
+static void ofono_gprs_dun_disconnect(struct ofono_gprs *gprs,
+   struct ofono_emulator_req *req)
+{
+   struct pri_context *context = gprs-dun_data.context;
+
+   

[PATCH 15/16] emulator: Watch GPRS status changes

2010-08-10 Thread Zhenhua Zhang
Watch GPRS status update to notify DUN client, such as +CGREG
unsolicited result.
---
 src/emulator.c |   94 
 1 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/src/emulator.c b/src/emulator.c
index 8811f6c..c8f3d65 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -55,6 +55,7 @@ struct modem_settings {
int cgreg;
int cops;
int attached;
+   int gprs_status;
 };
 
 struct ofono_emulator {
@@ -68,6 +69,9 @@ struct ofono_emulator {
struct modem_settings settings;
enum ofono_emulator_status status;
struct ofono_watchlist *status_watches;
+   struct ofono_gprs *gprs;
+   unsigned int gprs_watch;
+   unsigned int gprs_status_watch;
 };
 
 static unsigned int ofono_emulator_ids;
@@ -294,12 +298,16 @@ static void cgreg_cb(GAtServerRequestType type, GAtResult 
*result,
gpointer user_data)
 {
struct ofono_emulator *e = user_data;
+   char buf[256];
 
switch (type) {
case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
break;
case G_AT_SERVER_REQUEST_TYPE_QUERY:
+   snprintf(buf, sizeof(buf), +CGREG: %d, %d, e-settings.cgreg,
+   e-settings.gprs_status);
+   ofono_emulator_send_info(e, buf, TRUE);
ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
break;
case G_AT_SERVER_REQUEST_TYPE_SET:
@@ -720,6 +728,78 @@ static void emulator_remove(struct ofono_atom *atom)
e = NULL;
 }
 
+static void emulator_gprs_update(struct ofono_emulator *e)
+{
+   GAtServer *server = e-server;
+   char buf[256];
+
+   switch (e-settings.cgreg) {
+   case 0:
+   break;
+   case 1:
+   snprintf(buf, sizeof(buf), +CGREG: %d,
+   e-settings.gprs_status);
+   g_at_server_send_unsolicited(server, buf);
+   break;
+   case 2:
+   snprintf(buf, sizeof(buf), +CGREG: %d,
+   e-settings.gprs_status);
+   g_at_server_send_unsolicited(server, buf);
+   break;
+   default:
+   break;
+   }
+}
+
+static void gprs_status_changed(int status, void *data)
+{
+   struct ofono_emulator *e = data;
+
+   DBG(%d, status);
+
+   e-settings.gprs_status = status;
+
+   emulator_gprs_update(e);
+}
+
+static void gprs_watch(struct ofono_atom *atom,
+   enum ofono_atom_watch_condition cond,
+   void *data)
+{
+   struct ofono_emulator *e = data;
+   struct ofono_gprs *gprs;
+
+   if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+   e-gprs_status_watch = 0;
+   e-gprs = NULL;
+   return;
+   }
+
+   gprs = __ofono_atom_get_data(atom);
+   e-gprs = gprs;
+   e-settings.gprs_status = ofono_gprs_get_status(gprs);
+   e-gprs_status_watch = __ofono_gprs_add_status_watch(e-gprs,
+   gprs_status_changed, e, NULL);
+
+   emulator_gprs_update(e);
+}
+
+static void add_gprs_watches(struct ofono_emulator *e)
+{
+   struct ofono_modem *modem = e-modem;
+   struct ofono_atom *gprs_atom;
+
+   e-gprs_watch = __ofono_modem_add_atom_watch(modem,
+   OFONO_ATOM_TYPE_GPRS,
+   gprs_watch, e, NULL);
+
+   gprs_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_GPRS);
+
+   if (gprs_atom  __ofono_atom_get_registered(gprs_atom))
+   gprs_watch(gprs_atom,
+   OFONO_ATOM_WATCH_CONDITION_REGISTERED, e);
+}
+
 unsigned int __ofono_emulator_add_status_watch(struct ofono_emulator *e,
ofono_emulator_status_notify_cb_t notify,
void *data, ofono_destroy_func destroy)
@@ -767,6 +847,18 @@ static void emulator_unregister(struct ofono_atom *atom)
g_at_ppp_unref(e-ppp);
e-ppp = NULL;
}
+
+   if (e-gprs_watch) {
+   if (e-gprs_status_watch) {
+   __ofono_gprs_remove_status_watch(e-gprs,
+   e-gprs_status_watch);
+   e-gprs_status_watch = 0;
+   }
+
+   __ofono_modem_remove_atom_watch(e-modem, e-gprs_watch);
+   e-gprs_watch = 0;
+   e-gprs = NULL;
+   }
 }
 
 struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
@@ -808,5 +900,7 @@ struct ofono_emulator *ofono_emulator_create(struct 
ofono_modem *modem,
g_at_server_register(e-server, +CGATT, cgatt_cb, e, NULL);
g_at_server_register(e-server, +CGDCONT, 

[PATCH 13/16] gprs: Add status watch functions

2010-08-10 Thread Zhenhua Zhang
So DUN server could watch GPRS status changes and notify client
unsolicited results like +CGREG.
---
 include/gprs.h |9 +
 src/gprs.c |   55 +++
 2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/include/gprs.h b/include/gprs.h
index a1cbcd9..c0a0e2f 100644
--- a/include/gprs.h
+++ b/include/gprs.h
@@ -36,6 +36,8 @@ typedef void (*ofono_gprs_status_cb_t)(const struct 
ofono_error *error,
 
 typedef void (*ofono_gprs_cb_t)(const struct ofono_error *error, void *data);
 
+typedef void (*ofono_gprs_status_notify_cb_t)(const int status, void *data);
+
 struct ofono_gprs_driver {
const char *name;
int (*probe)(struct ofono_gprs *gprs, unsigned int vendor,
@@ -67,6 +69,13 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
 void ofono_gprs_add_context(struct ofono_gprs *gprs,
struct ofono_gprs_context *gc);
 
+unsigned int __ofono_gprs_add_status_watch(struct ofono_gprs *gprs,
+   ofono_gprs_status_notify_cb_t cb,
+   void *data, ofono_destroy_func destroy);
+
+gboolean __ofono_gprs_remove_status_watch(struct ofono_gprs *gprs,
+   unsigned int id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gprs.c b/src/gprs.c
index 95f7ab2..b91a099 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -92,6 +92,7 @@ struct ofono_gprs {
const struct ofono_gprs_driver *driver;
void *driver_data;
struct ofono_atom *atom;
+   struct ofono_watchlist *status_watches;
struct ofono_emulator *dun;
unsigned int dun_watch;
unsigned int dun_status_watch;
@@ -1467,6 +1468,51 @@ static GDBusSignalTable manager_signals[] = {
{ }
 };
 
+unsigned int __ofono_gprs_add_status_watch(struct ofono_gprs *gprs,
+   ofono_gprs_status_notify_cb_t notify,
+   void *data, ofono_destroy_func destroy)
+{
+   struct ofono_watchlist_item *item;
+
+   DBG(%p, gprs);
+
+   if (gprs == NULL)
+   return 0;
+
+   if (notify == NULL)
+   return 0;
+
+   item = g_new0(struct ofono_watchlist_item, 1);
+
+   item-notify = notify;
+   item-destroy = destroy;
+   item-notify_data = data;
+
+   return __ofono_watchlist_add_item(gprs-status_watches, item);
+}
+
+gboolean __ofono_gprs_remove_status_watch(struct ofono_gprs *gprs,
+   unsigned int id)
+{
+   DBG(%p, gprs);
+
+   return __ofono_watchlist_remove_item(gprs-status_watches, id);
+}
+
+static void notify_status_watches(struct ofono_gprs *gprs)
+{
+   struct ofono_watchlist_item *item;
+   GSList *l;
+   ofono_gprs_status_notify_cb_t notify;
+
+   for (l = gprs-status_watches-items; l; l = l-next) {
+   item = l-data;
+   notify = item-notify;
+
+   notify(gprs-status, item-notify_data);
+   }
+}
+
 void ofono_gprs_detached_notify(struct ofono_gprs *gprs)
 {
if (gprs-driver_attached == FALSE)
@@ -1476,6 +1522,8 @@ void ofono_gprs_detached_notify(struct ofono_gprs *gprs)
 
gprs_attached_update(gprs);
 
+   notify_status_watches(gprs);
+
/* TODO: The network forced a detach, we should wait for some time
 * and try to re-attach
 */
@@ -1489,6 +1537,8 @@ void ofono_gprs_status_notify(struct ofono_gprs *gprs, 
int status)
 
gprs-status = status;
gprs_attached_update(gprs);
+
+   notify_status_watches(gprs);
 }
 
 void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
@@ -1972,6 +2022,9 @@ static void gprs_unregister(struct ofono_atom *atom)
const char *path = __ofono_atom_get_path(atom);
GSList *l;
 
+   __ofono_watchlist_free(gprs-status_watches);
+   gprs-status_watches = NULL;
+
if (gprs-settings) {
storage_close(gprs-imsi, SETTINGS_STORE,
gprs-settings, TRUE);
@@ -2289,6 +2342,8 @@ void ofono_gprs_register(struct ofono_gprs *gprs)
ofono_modem_add_interface(modem,
OFONO_DATA_CONNECTION_MANAGER_INTERFACE);
 
+   gprs-status_watches = __ofono_watchlist_new(g_free);
+
sim_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_SIM);
 
if (sim_atom) {
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 14/16] gprs: Add gprs_get_status

2010-08-10 Thread Zhenhua Zhang
So that DUN server could get latest GPRS status.
---
 include/gprs.h |2 ++
 src/gprs.c |8 
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/include/gprs.h b/include/gprs.h
index c0a0e2f..ca23c45 100644
--- a/include/gprs.h
+++ b/include/gprs.h
@@ -76,6 +76,8 @@ unsigned int __ofono_gprs_add_status_watch(struct ofono_gprs 
*gprs,
 gboolean __ofono_gprs_remove_status_watch(struct ofono_gprs *gprs,
unsigned int id);
 
+int ofono_gprs_get_status(struct ofono_gprs *gprs);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gprs.c b/src/gprs.c
index b91a099..b3fad91 100644
--- a/src/gprs.c
+++ b/src/gprs.c
@@ -1995,6 +1995,14 @@ struct ofono_modem *ofono_gprs_context_get_modem(struct 
ofono_gprs_context *gc)
return __ofono_atom_get_modem(gc-atom);
 }
 
+int ofono_gprs_get_status(struct ofono_gprs *gprs)
+{
+   if (gprs == NULL)
+   return -1;
+
+   return gprs-status;
+}
+
 int ofono_gprs_driver_register(const struct ofono_gprs_driver *d)
 {
DBG(driver: %p, name: %s, d, d-name);
-- 
1.7.0.4

___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono


[PATCH 16/16] emulator: Watch netreg status changes

2010-08-10 Thread Zhenhua Zhang
Watch netreg status update to notify DUN client, such as +CREG
unsolicited result.
---
 src/emulator.c |  106 
 1 files changed, 106 insertions(+), 0 deletions(-)

diff --git a/src/emulator.c b/src/emulator.c
index c8f3d65..56edab6 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -56,6 +56,9 @@ struct modem_settings {
int cops;
int attached;
int gprs_status;
+   int netreg_status;
+   int netreg_lac;
+   int netreg_ci;
 };
 
 struct ofono_emulator {
@@ -72,6 +75,9 @@ struct ofono_emulator {
struct ofono_gprs *gprs;
unsigned int gprs_watch;
unsigned int gprs_status_watch;
+   struct ofono_netreg *netreg;
+   unsigned int netreg_watch;
+   unsigned int netreg_status_watch;
 };
 
 static unsigned int ofono_emulator_ids;
@@ -254,12 +260,19 @@ static void creg_cb(GAtServerRequestType type, GAtResult 
*result,
gpointer user_data)
 {
struct ofono_emulator *e = user_data;
+   char buf[256];
 
switch (type) {
case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
break;
case G_AT_SERVER_REQUEST_TYPE_QUERY:
+   snprintf(buf, sizeof(buf), +CREG: %d, %x, %x, %x,
+   e-settings.creg,
+   e-settings.netreg_status,
+   e-settings.netreg_lac,
+   e-settings.netreg_ci);
+   ofono_emulator_send_info(e, buf, TRUE);
ofono_emulator_send_final(e, G_AT_SERVER_RESULT_OK);
break;
case G_AT_SERVER_REQUEST_TYPE_SET:
@@ -800,6 +813,86 @@ static void add_gprs_watches(struct ofono_emulator *e)
OFONO_ATOM_WATCH_CONDITION_REGISTERED, e);
 }
 
+static void emulator_netreg_update(struct ofono_emulator *e)
+{
+   GAtServer *server = e-server;
+   char buf[256];
+
+   switch (e-settings.creg) {
+   case 0:
+   break;
+   case 1:
+   snprintf(buf, sizeof(buf), +CREG: %d,
+   e-settings.netreg_status);
+   g_at_server_send_unsolicited(server, buf);
+   break;
+   case 2:
+   snprintf(buf, sizeof(buf), +CREG: %d, %x, %x,
+   e-settings.netreg_status,
+   e-settings.netreg_lac,
+   e-settings.netreg_ci);
+   g_at_server_send_unsolicited(server, buf);
+   break;
+   default:
+   break;
+   }
+}
+
+static void netreg_status_changed(int status, int lac, int ci, int tech,
+   const char *mcc, const char *mnc,
+   void *data)
+{
+   struct ofono_emulator *e = data;
+
+   DBG(%d %d %d, status, lac, ci);
+
+   e-settings.netreg_status = status;
+   e-settings.netreg_lac = lac;
+   e-settings.netreg_ci = ci;
+
+   emulator_netreg_update(e);
+}
+
+static void netreg_watch(struct ofono_atom *atom,
+   enum ofono_atom_watch_condition cond,
+   void *data)
+{
+   struct ofono_emulator *e = data;
+   struct ofono_netreg *netreg;
+
+   if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+   e-netreg_status_watch = 0;
+   e-netreg = NULL;
+   return;
+   }
+
+   netreg = __ofono_atom_get_data(atom);
+   e-netreg = netreg;
+   e-settings.netreg_status = ofono_netreg_get_status(netreg);
+   e-settings.netreg_lac = ofono_netreg_get_location(netreg);
+   e-settings.netreg_ci = ofono_netreg_get_cellid(netreg);
+   e-netreg_status_watch = __ofono_netreg_add_status_watch(e-netreg,
+   netreg_status_changed, e, NULL);
+
+   emulator_netreg_update(e);
+}
+
+static void add_netreg_watches(struct ofono_emulator *e)
+{
+   struct ofono_modem *modem = e-modem;
+   struct ofono_atom *netreg_atom;
+
+   e-netreg_watch = __ofono_modem_add_atom_watch(modem,
+   OFONO_ATOM_TYPE_NETREG,
+   netreg_watch, e, NULL);
+
+   netreg_atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_NETREG);
+
+   if (netreg_atom  __ofono_atom_get_registered(netreg_atom))
+   netreg_watch(netreg_atom,
+   OFONO_ATOM_WATCH_CONDITION_REGISTERED, e);
+}
+
 unsigned int __ofono_emulator_add_status_watch(struct ofono_emulator *e,
ofono_emulator_status_notify_cb_t notify,
void *data, ofono_destroy_func 

Re: [PATCH v3 2/2] huawei: add gprs context

2010-08-10 Thread Inaky Perez-Gonzalez
On Fri, 2010-08-06 at 10:26 +0300, Kalle Valo wrote: 
 Inaky Perez-Gonzalez in...@linux.intel.com writes:
 
  Hi Kale
 
 Hola,
 
  On Thu, 2010-08-05 at 08:54 +0300, Kalle Valo wrote: 
 
  This is my setup:
  
  ; from linux/Documentation/CodingStyle
  (defun c-lineup-arglist-tabs-only (ignored)
Line up argument lists by tabs, not spaces
(let* ((anchor (c-langelem-pos c-syntactic-element))
  (column (c-langelem-2nd-pos c-syntactic-element))
  (offset (- (1+ column) anchor))
  (steps (floor offset c-basic-offset)))
  (* (max steps 1)
 c-basic-offset)))
 
  Thanks! Phew ... this is a handful of lisp! I don't understand anything
  that is not basic anymore :)
 
 It sure is. I just copied it from Linux CodingStyle document and it
 seems to work somehow.
 
  -- I gave it a whiz and one thing I saw was that
 
  struct tx_queue_entry *__ofono_sms_txq_submit(struct ofono_sms *sms,
  GSList *list,
  unsigned int flags, unsigned 
  msg_id,
  ofono_sms_msg_stch_cb_t stch_cb,
  void *data, ofono_destroy_func 
  destroy)
 
  is being formatted as:
 
  struct tx_queue_entry *__ofono_sms_txq_submit(struct ofono_sms *sms,
  GSList *list,
  unsigned int flags, unsigned msg_id,
  ofono_sms_msg_stch_cb_t stch_cb,
  void *data, ofono_destroy_func destroy)
 
  ie: one c-basic-offset less than it should -- I really can't figure out 
  where to poke.
 
 That's my problem as well. Currently I just manually add one more tab to
 each line with M-i. If you find a way to fix this, please let me know.

I think I found it, seems to cut it; replace:

(steps (floor offset c-basic-offset)))

with

 (steps (floor (+ offset (- c-basic-offset 1)) c-basic-offset)))

Lisp nuts me out, but it is doing the:

steps = floor(offset/c-basic-offset);

with

steps = floor((offset + c-basic-offset - 1) / c-basic-offset);

thus making sure there is always one more tab except when the offset is
right on a tab boundary that we keep the same.

So far, so good -- probably it fails in some case, because this is
totally trial and error as unscientific as it can :)


___
ofono mailing list
ofono@ofono.org
http://lists.ofono.org/listinfo/ofono