* [PATCH 1/1] Create network registration driver for hfpmodem
@ 2009-11-03 17:04 Gustavo F. Padovan
2009-11-04 17:54 ` Denis Kenzior
0 siblings, 1 reply; 9+ messages in thread
From: Gustavo F. Padovan @ 2009-11-03 17:04 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 11605 bytes --]
This driver handles phone informations about registration status, signal
strength and roaming status listening +CIEV commands. It also gets the
Network Operator name with +COPS commands.
---
Makefile.am | 3 +-
drivers/hfpmodem/hfpmodem.c | 2 +
drivers/hfpmodem/hfpmodem.h | 3 +
drivers/hfpmodem/network-registration.c | 365 +++++++++++++++++++++++++++++++
plugins/hfp.c | 1 +
5 files changed, 373 insertions(+), 1 deletions(-)
create mode 100644 drivers/hfpmodem/network-registration.c
diff --git a/Makefile.am b/Makefile.am
index 8e56568..c3e06b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,7 +126,8 @@ builtin_modules += hfpmodem
builtin_sources += drivers/atmodem/atutil.h \
drivers/hfpmodem/hfpmodem.h \
drivers/hfpmodem/hfpmodem.c \
- drivers/hfpmodem/voicecall.c
+ drivers/hfpmodem/voicecall.c \
+ drivers/hfpmodem/network-registration.c
builtin_modules += mbmmodem
builtin_sources += drivers/atmodem/atutil.h \
diff --git a/drivers/hfpmodem/hfpmodem.c b/drivers/hfpmodem/hfpmodem.c
index 03b5ea0..58ae03d 100644
--- a/drivers/hfpmodem/hfpmodem.c
+++ b/drivers/hfpmodem/hfpmodem.c
@@ -42,6 +42,7 @@
static int hfpmodem_init(void)
{
hfp_voicecall_init();
+ hfp_netreg_init();
return 0;
}
@@ -49,6 +50,7 @@ static int hfpmodem_init(void)
static void hfpmodem_exit(void)
{
hfp_voicecall_exit();
+ hfp_netreg_exit();
}
OFONO_PLUGIN_DEFINE(hfpmodem, "Hands-Free Profile Driver", VERSION,
diff --git a/drivers/hfpmodem/hfpmodem.h b/drivers/hfpmodem/hfpmodem.h
index c4e2a34..02f5a4b 100644
--- a/drivers/hfpmodem/hfpmodem.h
+++ b/drivers/hfpmodem/hfpmodem.h
@@ -61,6 +61,9 @@ struct hfp_data {
unsigned int cind_val[HFP_INDICATOR_LAST];
};
+extern void hfp_netreg_init();
+extern void hfp_netreg_exit();
+
extern void hfp_voicecall_init();
extern void hfp_voicecall_exit();
diff --git a/drivers/hfpmodem/network-registration.c b/drivers/hfpmodem/network-registration.c
new file mode 100644
index 0000000..6cfaf57
--- /dev/null
+++ b/drivers/hfpmodem/network-registration.c
@@ -0,0 +1,365 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009 ProFUSION embedded systems. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/netreg.h>
+
+#include "gatchat.h"
+#include "gatresult.h"
+#include "common.h"
+
+#include "hfpmodem.h"
+
+#define HFP_MAX_OPERATOR_NAME_LENGTH 16
+
+static const char *cops_prefix[] = { "+COPS:", NULL };
+static const char *cind_prefix[] = { "+CIND:", NULL };
+
+struct netreg_data {
+ GAtChat *chat;
+ unsigned char cind_pos[HFP_INDICATOR_LAST];
+ int cind_val[HFP_INDICATOR_LAST];
+};
+
+static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ ofono_netreg_operator_cb_t cb = cbd->cb;
+ struct ofono_network_operator op;
+ GAtResultIter iter;
+ int format;
+ const char *name;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, NULL, cbd->data);
+ goto out;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+COPS:"))
+ return;
+
+ g_at_result_iter_skip_next(&iter);
+
+ ok = g_at_result_iter_next_number(&iter, &format);
+
+ if (ok == FALSE || format != 0)
+ return;
+
+ if (g_at_result_iter_next_string(&iter, &name) == FALSE)
+ return;
+
+ strncpy(op.name, name, HFP_MAX_OPERATOR_NAME_LENGTH);
+ op.name[HFP_MAX_OPERATOR_NAME_LENGTH] = '\0';
+
+ op.mcc[0] = '\0';
+ op.mnc[0] = '\0';
+
+ cb(&error, &op, cbd->data);
+
+out:
+ g_free(cbd);
+
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
+
+ g_free(cbd);
+}
+
+static void ciev_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ GAtResultIter iter;
+ int index, value, status;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIEV:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &index))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &value))
+ return;
+
+ if (index == nd->cind_pos[HFP_INDICATOR_SERVICE]) {
+ nd->cind_val[HFP_INDICATOR_SERVICE] = value;
+ if (value)
+ status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+ else
+ status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
+
+ ofono_netreg_status_notify(netreg, status, -1, -1, -1);
+ } else if (index == nd->cind_pos[HFP_INDICATOR_ROAM]) {
+ nd->cind_val[HFP_INDICATOR_ROAM] = value;
+ if (value)
+ status = NETWORK_REGISTRATION_STATUS_ROAMING;
+
+ ofono_netreg_status_notify(netreg, status, -1, -1, -1);
+ } else if (index == nd->cind_pos[HFP_INDICATOR_SIGNAL]) {
+ nd->cind_val[HFP_INDICATOR_SIGNAL] = value;
+ ofono_netreg_strength_notify(netreg, value * 20);
+ }
+
+ return;
+}
+
+static void signal_strength_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_strength_cb_t cb = cbd->cb;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ GAtResultIter iter;
+ int index, strength;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, -1, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIND:")) {
+ CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
+ return;
+ }
+
+ index = 1;
+
+ while (g_at_result_iter_next_number(&iter, &strength)) {
+ if (index == nd->cind_pos[HFP_INDICATOR_SIGNAL]) {
+ nd->cind_val[HFP_INDICATOR_SIGNAL] = strength;
+ break;
+ }
+
+ index++;
+ }
+
+ ofono_debug("signal_strength_cb: %d", strength);
+
+ cb(&error, strength * 20, cbd->data);
+}
+
+static void registration_status_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_status_cb_t cb = cbd->cb;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ GAtResultIter iter;
+ int index, value, status;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, -1, -1, -1, -1, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIND:")) {
+ CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
+ return;
+ }
+
+ index = 1;
+
+ while (g_at_result_iter_next_number(&iter, &value)) {
+
+ if (index == nd->cind_pos[HFP_INDICATOR_SERVICE])
+ nd->cind_val[HFP_INDICATOR_SERVICE] = value;
+
+ if (index == nd->cind_pos[HFP_INDICATOR_ROAM])
+ nd->cind_val[HFP_INDICATOR_ROAM] = value;
+
+ index++;
+ }
+
+ if (nd->cind_val[HFP_INDICATOR_SERVICE])
+ status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+ else
+ status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
+
+ if (nd->cind_val[HFP_INDICATOR_ROAM])
+ status = NETWORK_REGISTRATION_STATUS_ROAMING;
+
+ cb(&error, status, -1, -1, -1, cbd->data);
+}
+
+static void hfp_registration_status(struct ofono_netreg *netreg,
+ ofono_netreg_status_cb_t cb,
+ void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ gboolean ok;
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ ok = g_at_chat_send(nd->chat, "AT+CIND?", cind_prefix,
+ registration_status_cb, cbd, g_free);
+ if (ok)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, data);
+}
+
+static void hfp_current_operator(struct ofono_netreg *netreg,
+ ofono_netreg_operator_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ gboolean ok;
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ ok = g_at_chat_send(nd->chat, "AT+COPS=3,0", NULL,
+ NULL, cbd, NULL);
+
+ if (ok)
+ ok = g_at_chat_send(nd->chat, "AT+COPS?", cops_prefix,
+ cops_cb, cbd, NULL);
+
+ if (ok)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, NULL, data);
+}
+
+static void hfp_signal_strength(struct ofono_netreg *netreg,
+ ofono_netreg_strength_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ if (g_at_chat_send(nd->chat, "AT+CIND?", cind_prefix,
+ signal_strength_cb, cbd, g_free) > 0)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, -1, data);
+}
+
+static gboolean hfp_netreg_register(gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+
+ ofono_netreg_register(netreg);
+
+ return FALSE;
+}
+
+static int hfp_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
+ void *user_data)
+{
+ struct hfp_data *data = user_data;
+ struct netreg_data *nd;
+
+ nd = g_new0(struct netreg_data, 1);
+ nd->chat = data->chat;
+ memcpy(nd->cind_pos, data->cind_pos, HFP_INDICATOR_LAST);
+ memcpy(nd->cind_val, data->cind_val, HFP_INDICATOR_LAST);
+
+ ofono_netreg_set_data(netreg, nd);
+
+ g_at_chat_register(nd->chat, "+CIEV:", ciev_notify, FALSE,
+ netreg, NULL);
+
+ g_idle_add(hfp_netreg_register, netreg);
+
+ return 0;
+}
+
+static void hfp_netreg_remove(struct ofono_netreg *netreg)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+
+ g_free(nd);
+}
+
+static struct ofono_netreg_driver driver = {
+ .name = "hfpmodem",
+ .probe = hfp_netreg_probe,
+ .remove = hfp_netreg_remove,
+ .registration_status = hfp_registration_status,
+ .current_operator = hfp_current_operator,
+ .strength = hfp_signal_strength,
+};
+
+void hfp_netreg_init()
+{
+ ofono_netreg_driver_register(&driver);
+}
+
+void hfp_netreg_exit()
+{
+ ofono_netreg_driver_unregister(&driver);
+}
diff --git a/plugins/hfp.c b/plugins/hfp.c
index 5e94a05..be812cd 100644
--- a/plugins/hfp.c
+++ b/plugins/hfp.c
@@ -311,6 +311,7 @@ static void hfp_pre_sim(struct ofono_modem *modem)
DBG("%p", modem);
ofono_voicecall_create(modem, 0, "hfpmodem", data);
+ ofono_netreg_create(modem, 0, "hfpmodem", data);
}
static void hfp_post_sim(struct ofono_modem *modem)
--
1.6.4.4
^ permalink raw reply related [flat|nested] 9+ messages in thread[parent not found: <0463F45F3606F4428ED35AC8C709F92E089B9CBAB7@pdsmsx502.ccr.corp.intel.com>]
* Re: [PATCH 1/1] Create network registration driver for hfpmodem
[not found] <0463F45F3606F4428ED35AC8C709F92E089B9CBAB7@pdsmsx502.ccr.corp.intel.com>
@ 2009-11-03 17:46 ` Zhenhua Zhang
2009-11-03 16:53 ` Gustavo F. Padovan
0 siblings, 1 reply; 9+ messages in thread
From: Zhenhua Zhang @ 2009-11-03 17:46 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 3347 bytes --]
Hi Padovan,
Gustavo F. Padovan wrote:
> This driver handles phone informations about registration status, signal
> strength and roaming status listening +CIEV commands. It also gets the
> Network Operator name with +COPS commands.
> ---
> Makefile.am | 3 +-
> drivers/hfpmodem/hfpmodem.c | 2 +
> drivers/hfpmodem/hfpmodem.h | 3 +
> drivers/hfpmodem/network-registration.c | 365 +++++++++++++++++++++++++++++++
> plugins/hfp.c | 1 +
> 5 files changed, 373 insertions(+), 1 deletions(-)
> create mode 100644 drivers/hfpmodem/network-registration.c
On compiling your code I got:
CC drivers/hfpmodem/network-registration.o
cc1: warnings being treated as errors
drivers/hfpmodem/network-registration.c: In function ‘cops_cb’:
drivers/hfpmodem/network-registration.c:101: error: label ‘error’
defined but not used
drivers/hfpmodem/network-registration.c:58: error: unused variable ‘nd’
make[1]: *** [drivers/hfpmodem/network-registration.o] Error 1
make: *** [all] Error 2
So I have below patch to remove 'nd' and refine labels in cops_cb.
Please review it.
I would suggest to replace 'out' label by return. We really don't need
two labels that is confusing. Atmodem netreg has the same problem.
---
drivers/hfpmodem/network-registration.c | 19 +++++--------------
1 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/drivers/hfpmodem/network-registration.c
b/drivers/hfpmodem/network-registration.c
index 6cfaf57..e163b79 100644
--- a/drivers/hfpmodem/network-registration.c
+++ b/drivers/hfpmodem/network-registration.c
@@ -55,7 +55,6 @@ struct netreg_data {
static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
{
struct cb_data *cbd = user_data;
- struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
ofono_netreg_operator_cb_t cb = cbd->cb;
struct ofono_network_operator op;
GAtResultIter iter;
@@ -67,23 +66,23 @@ static void cops_cb(gboolean ok, GAtResult *result,
gpointer user_data)
if (!ok) {
cb(&error, NULL, cbd->data);
- goto out;
+ return;
}
g_at_result_iter_init(&iter, result);
if (!g_at_result_iter_next(&iter, "+COPS:"))
- return;
+ goto error;
g_at_result_iter_skip_next(&iter);
ok = g_at_result_iter_next_number(&iter, &format);
if (ok == FALSE || format != 0)
- return;
+ goto error;
if (g_at_result_iter_next_string(&iter, &name) == FALSE)
- return;
+ goto error;
strncpy(op.name, name, HFP_MAX_OPERATOR_NAME_LENGTH);
op.name[HFP_MAX_OPERATOR_NAME_LENGTH] = '\0';
@@ -93,15 +92,10 @@ static void cops_cb(gboolean ok, GAtResult *result,
gpointer user_data)
cb(&error, &op, cbd->data);
-out:
- g_free(cbd);
-
return;
error:
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
-
- g_free(cbd);
}
static void ciev_notify(GAtResult *result, gpointer user_data)
@@ -274,15 +268,12 @@ static void hfp_current_operator(struct
ofono_netreg *netreg,
if (ok)
ok = g_at_chat_send(nd->chat, "AT+COPS?", cops_prefix,
- cops_cb, cbd, NULL);
+ cops_cb, cbd, g_free);
if (ok)
return;
error:
- if (cbd)
- g_free(cbd);
-
CALLBACK_WITH_FAILURE(cb, NULL, data);
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 1/1] Create network registration driver for hfpmodem
2009-11-03 17:46 ` Zhenhua Zhang
@ 2009-11-03 16:53 ` Gustavo F. Padovan
0 siblings, 0 replies; 9+ messages in thread
From: Gustavo F. Padovan @ 2009-11-03 16:53 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1735 bytes --]
Hi Zhenhua,
On Tue, Nov 3, 2009 at 3:46 PM, Zhenhua Zhang <zhenhua.zhang@intel.com> wrote:
> Hi Padovan,
>
> Gustavo F. Padovan wrote:
>> This driver handles phone informations about registration status, signal
>> strength and roaming status listening +CIEV commands. It also gets the
>> Network Operator name with +COPS commands.
>> ---
>> Makefile.am | 3 +-
>> drivers/hfpmodem/hfpmodem.c | 2 +
>> drivers/hfpmodem/hfpmodem.h | 3 +
>> drivers/hfpmodem/network-registration.c | 365 +++++++++++++++++++++++++++++++
>> plugins/hfp.c | 1 +
>> 5 files changed, 373 insertions(+), 1 deletions(-)
>> create mode 100644 drivers/hfpmodem/network-registration.c
>
> On compiling your code I got:
>
> CC drivers/hfpmodem/network-registration.o
> cc1: warnings being treated as errors
> drivers/hfpmodem/network-registration.c: In function ‘cops_cb’:
> drivers/hfpmodem/network-registration.c:101: error: label ‘error’
> defined but not used
> drivers/hfpmodem/network-registration.c:58: error: unused variable ‘nd’
> make[1]: *** [drivers/hfpmodem/network-registration.o] Error 1
> make: *** [all] Error 2
Sorry, I forgot the --enable-maintainer-mode. :(
>
> So I have below patch to remove 'nd' and refine labels in cops_cb.
> Please review it.
>
> I would suggest to replace 'out' label by return. We really don't need
> two labels that is confusing. Atmodem netreg has the same problem.
I agree with you, thanks for the patch and the review.
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/1] Create network registration driver for hfpmodem
@ 2009-11-03 17:44 Gustavo F. Padovan
0 siblings, 0 replies; 9+ messages in thread
From: Gustavo F. Padovan @ 2009-11-03 17:44 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 11478 bytes --]
This driver handles phone informations about registration status, signal
strength and roaming status listening +CIEV commands. It also gets the
Network Operator name with +COPS commands.
---
Makefile.am | 3 +-
drivers/hfpmodem/hfpmodem.c | 2 +
drivers/hfpmodem/hfpmodem.h | 3 +
drivers/hfpmodem/network-registration.c | 356 +++++++++++++++++++++++++++++++
plugins/hfp.c | 1 +
5 files changed, 364 insertions(+), 1 deletions(-)
create mode 100644 drivers/hfpmodem/network-registration.c
diff --git a/Makefile.am b/Makefile.am
index 8e56568..c3e06b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,7 +126,8 @@ builtin_modules += hfpmodem
builtin_sources += drivers/atmodem/atutil.h \
drivers/hfpmodem/hfpmodem.h \
drivers/hfpmodem/hfpmodem.c \
- drivers/hfpmodem/voicecall.c
+ drivers/hfpmodem/voicecall.c \
+ drivers/hfpmodem/network-registration.c
builtin_modules += mbmmodem
builtin_sources += drivers/atmodem/atutil.h \
diff --git a/drivers/hfpmodem/hfpmodem.c b/drivers/hfpmodem/hfpmodem.c
index 03b5ea0..58ae03d 100644
--- a/drivers/hfpmodem/hfpmodem.c
+++ b/drivers/hfpmodem/hfpmodem.c
@@ -42,6 +42,7 @@
static int hfpmodem_init(void)
{
hfp_voicecall_init();
+ hfp_netreg_init();
return 0;
}
@@ -49,6 +50,7 @@ static int hfpmodem_init(void)
static void hfpmodem_exit(void)
{
hfp_voicecall_exit();
+ hfp_netreg_exit();
}
OFONO_PLUGIN_DEFINE(hfpmodem, "Hands-Free Profile Driver", VERSION,
diff --git a/drivers/hfpmodem/hfpmodem.h b/drivers/hfpmodem/hfpmodem.h
index c4e2a34..02f5a4b 100644
--- a/drivers/hfpmodem/hfpmodem.h
+++ b/drivers/hfpmodem/hfpmodem.h
@@ -61,6 +61,9 @@ struct hfp_data {
unsigned int cind_val[HFP_INDICATOR_LAST];
};
+extern void hfp_netreg_init();
+extern void hfp_netreg_exit();
+
extern void hfp_voicecall_init();
extern void hfp_voicecall_exit();
diff --git a/drivers/hfpmodem/network-registration.c b/drivers/hfpmodem/network-registration.c
new file mode 100644
index 0000000..e163b79
--- /dev/null
+++ b/drivers/hfpmodem/network-registration.c
@@ -0,0 +1,356 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009 ProFUSION embedded systems. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/netreg.h>
+
+#include "gatchat.h"
+#include "gatresult.h"
+#include "common.h"
+
+#include "hfpmodem.h"
+
+#define HFP_MAX_OPERATOR_NAME_LENGTH 16
+
+static const char *cops_prefix[] = { "+COPS:", NULL };
+static const char *cind_prefix[] = { "+CIND:", NULL };
+
+struct netreg_data {
+ GAtChat *chat;
+ unsigned char cind_pos[HFP_INDICATOR_LAST];
+ int cind_val[HFP_INDICATOR_LAST];
+};
+
+static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_operator_cb_t cb = cbd->cb;
+ struct ofono_network_operator op;
+ GAtResultIter iter;
+ int format;
+ const char *name;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, NULL, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+COPS:"))
+ goto error;
+
+ g_at_result_iter_skip_next(&iter);
+
+ ok = g_at_result_iter_next_number(&iter, &format);
+
+ if (ok == FALSE || format != 0)
+ goto error;
+
+ if (g_at_result_iter_next_string(&iter, &name) == FALSE)
+ goto error;
+
+ strncpy(op.name, name, HFP_MAX_OPERATOR_NAME_LENGTH);
+ op.name[HFP_MAX_OPERATOR_NAME_LENGTH] = '\0';
+
+ op.mcc[0] = '\0';
+ op.mnc[0] = '\0';
+
+ cb(&error, &op, cbd->data);
+
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
+}
+
+static void ciev_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ GAtResultIter iter;
+ int index, value, status;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIEV:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &index))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &value))
+ return;
+
+ if (index == nd->cind_pos[HFP_INDICATOR_SERVICE]) {
+ nd->cind_val[HFP_INDICATOR_SERVICE] = value;
+ if (value)
+ status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+ else
+ status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
+
+ ofono_netreg_status_notify(netreg, status, -1, -1, -1);
+ } else if (index == nd->cind_pos[HFP_INDICATOR_ROAM]) {
+ nd->cind_val[HFP_INDICATOR_ROAM] = value;
+ if (value)
+ status = NETWORK_REGISTRATION_STATUS_ROAMING;
+
+ ofono_netreg_status_notify(netreg, status, -1, -1, -1);
+ } else if (index == nd->cind_pos[HFP_INDICATOR_SIGNAL]) {
+ nd->cind_val[HFP_INDICATOR_SIGNAL] = value;
+ ofono_netreg_strength_notify(netreg, value * 20);
+ }
+
+ return;
+}
+
+static void signal_strength_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_strength_cb_t cb = cbd->cb;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ GAtResultIter iter;
+ int index, strength;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, -1, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIND:")) {
+ CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
+ return;
+ }
+
+ index = 1;
+
+ while (g_at_result_iter_next_number(&iter, &strength)) {
+ if (index == nd->cind_pos[HFP_INDICATOR_SIGNAL]) {
+ nd->cind_val[HFP_INDICATOR_SIGNAL] = strength;
+ break;
+ }
+
+ index++;
+ }
+
+ ofono_debug("signal_strength_cb: %d", strength);
+
+ cb(&error, strength * 20, cbd->data);
+}
+
+static void registration_status_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_status_cb_t cb = cbd->cb;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ GAtResultIter iter;
+ int index, value, status;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, -1, -1, -1, -1, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIND:")) {
+ CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
+ return;
+ }
+
+ index = 1;
+
+ while (g_at_result_iter_next_number(&iter, &value)) {
+
+ if (index == nd->cind_pos[HFP_INDICATOR_SERVICE])
+ nd->cind_val[HFP_INDICATOR_SERVICE] = value;
+
+ if (index == nd->cind_pos[HFP_INDICATOR_ROAM])
+ nd->cind_val[HFP_INDICATOR_ROAM] = value;
+
+ index++;
+ }
+
+ if (nd->cind_val[HFP_INDICATOR_SERVICE])
+ status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+ else
+ status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
+
+ if (nd->cind_val[HFP_INDICATOR_ROAM])
+ status = NETWORK_REGISTRATION_STATUS_ROAMING;
+
+ cb(&error, status, -1, -1, -1, cbd->data);
+}
+
+static void hfp_registration_status(struct ofono_netreg *netreg,
+ ofono_netreg_status_cb_t cb,
+ void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ gboolean ok;
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ ok = g_at_chat_send(nd->chat, "AT+CIND?", cind_prefix,
+ registration_status_cb, cbd, g_free);
+ if (ok)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, data);
+}
+
+static void hfp_current_operator(struct ofono_netreg *netreg,
+ ofono_netreg_operator_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ gboolean ok;
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ ok = g_at_chat_send(nd->chat, "AT+COPS=3,0", NULL,
+ NULL, cbd, NULL);
+
+ if (ok)
+ ok = g_at_chat_send(nd->chat, "AT+COPS?", cops_prefix,
+ cops_cb, cbd, g_free);
+
+ if (ok)
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, data);
+}
+
+static void hfp_signal_strength(struct ofono_netreg *netreg,
+ ofono_netreg_strength_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ if (g_at_chat_send(nd->chat, "AT+CIND?", cind_prefix,
+ signal_strength_cb, cbd, g_free) > 0)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, -1, data);
+}
+
+static gboolean hfp_netreg_register(gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+
+ ofono_netreg_register(netreg);
+
+ return FALSE;
+}
+
+static int hfp_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
+ void *user_data)
+{
+ struct hfp_data *data = user_data;
+ struct netreg_data *nd;
+
+ nd = g_new0(struct netreg_data, 1);
+ nd->chat = data->chat;
+ memcpy(nd->cind_pos, data->cind_pos, HFP_INDICATOR_LAST);
+ memcpy(nd->cind_val, data->cind_val, HFP_INDICATOR_LAST);
+
+ ofono_netreg_set_data(netreg, nd);
+
+ g_at_chat_register(nd->chat, "+CIEV:", ciev_notify, FALSE,
+ netreg, NULL);
+
+ g_idle_add(hfp_netreg_register, netreg);
+
+ return 0;
+}
+
+static void hfp_netreg_remove(struct ofono_netreg *netreg)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+
+ g_free(nd);
+}
+
+static struct ofono_netreg_driver driver = {
+ .name = "hfpmodem",
+ .probe = hfp_netreg_probe,
+ .remove = hfp_netreg_remove,
+ .registration_status = hfp_registration_status,
+ .current_operator = hfp_current_operator,
+ .strength = hfp_signal_strength,
+};
+
+void hfp_netreg_init()
+{
+ ofono_netreg_driver_register(&driver);
+}
+
+void hfp_netreg_exit()
+{
+ ofono_netreg_driver_unregister(&driver);
+}
diff --git a/plugins/hfp.c b/plugins/hfp.c
index 5e94a05..be812cd 100644
--- a/plugins/hfp.c
+++ b/plugins/hfp.c
@@ -311,6 +311,7 @@ static void hfp_pre_sim(struct ofono_modem *modem)
DBG("%p", modem);
ofono_voicecall_create(modem, 0, "hfpmodem", data);
+ ofono_netreg_create(modem, 0, "hfpmodem", data);
}
static void hfp_post_sim(struct ofono_modem *modem)
--
1.6.4.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 1/1] Create network registration driver for hfpmodem
@ 2009-10-30 22:55 Gustavo F. Padovan
0 siblings, 0 replies; 9+ messages in thread
From: Gustavo F. Padovan @ 2009-10-30 22:55 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 11605 bytes --]
This driver handles phone informations about registration status, signal
strength and roaming status listening +CIEV commands. It also gets the
Network Operator name with +COPS commands.
---
Makefile.am | 3 +-
drivers/hfpmodem/hfpmodem.c | 2 +
drivers/hfpmodem/hfpmodem.h | 3 +
drivers/hfpmodem/network-registration.c | 365 +++++++++++++++++++++++++++++++
plugins/hfp.c | 1 +
5 files changed, 373 insertions(+), 1 deletions(-)
create mode 100644 drivers/hfpmodem/network-registration.c
diff --git a/Makefile.am b/Makefile.am
index 8e56568..c3e06b4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,7 +126,8 @@ builtin_modules += hfpmodem
builtin_sources += drivers/atmodem/atutil.h \
drivers/hfpmodem/hfpmodem.h \
drivers/hfpmodem/hfpmodem.c \
- drivers/hfpmodem/voicecall.c
+ drivers/hfpmodem/voicecall.c \
+ drivers/hfpmodem/network-registration.c
builtin_modules += mbmmodem
builtin_sources += drivers/atmodem/atutil.h \
diff --git a/drivers/hfpmodem/hfpmodem.c b/drivers/hfpmodem/hfpmodem.c
index 03b5ea0..58ae03d 100644
--- a/drivers/hfpmodem/hfpmodem.c
+++ b/drivers/hfpmodem/hfpmodem.c
@@ -42,6 +42,7 @@
static int hfpmodem_init(void)
{
hfp_voicecall_init();
+ hfp_netreg_init();
return 0;
}
@@ -49,6 +50,7 @@ static int hfpmodem_init(void)
static void hfpmodem_exit(void)
{
hfp_voicecall_exit();
+ hfp_netreg_exit();
}
OFONO_PLUGIN_DEFINE(hfpmodem, "Hands-Free Profile Driver", VERSION,
diff --git a/drivers/hfpmodem/hfpmodem.h b/drivers/hfpmodem/hfpmodem.h
index c4e2a34..02f5a4b 100644
--- a/drivers/hfpmodem/hfpmodem.h
+++ b/drivers/hfpmodem/hfpmodem.h
@@ -61,6 +61,9 @@ struct hfp_data {
unsigned int cind_val[HFP_INDICATOR_LAST];
};
+extern void hfp_netreg_init();
+extern void hfp_netreg_exit();
+
extern void hfp_voicecall_init();
extern void hfp_voicecall_exit();
diff --git a/drivers/hfpmodem/network-registration.c b/drivers/hfpmodem/network-registration.c
new file mode 100644
index 0000000..6cfaf57
--- /dev/null
+++ b/drivers/hfpmodem/network-registration.c
@@ -0,0 +1,365 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009 ProFUSION embedded systems. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/netreg.h>
+
+#include "gatchat.h"
+#include "gatresult.h"
+#include "common.h"
+
+#include "hfpmodem.h"
+
+#define HFP_MAX_OPERATOR_NAME_LENGTH 16
+
+static const char *cops_prefix[] = { "+COPS:", NULL };
+static const char *cind_prefix[] = { "+CIND:", NULL };
+
+struct netreg_data {
+ GAtChat *chat;
+ unsigned char cind_pos[HFP_INDICATOR_LAST];
+ int cind_val[HFP_INDICATOR_LAST];
+};
+
+static void cops_cb(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ ofono_netreg_operator_cb_t cb = cbd->cb;
+ struct ofono_network_operator op;
+ GAtResultIter iter;
+ int format;
+ const char *name;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, NULL, cbd->data);
+ goto out;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+COPS:"))
+ return;
+
+ g_at_result_iter_skip_next(&iter);
+
+ ok = g_at_result_iter_next_number(&iter, &format);
+
+ if (ok == FALSE || format != 0)
+ return;
+
+ if (g_at_result_iter_next_string(&iter, &name) == FALSE)
+ return;
+
+ strncpy(op.name, name, HFP_MAX_OPERATOR_NAME_LENGTH);
+ op.name[HFP_MAX_OPERATOR_NAME_LENGTH] = '\0';
+
+ op.mcc[0] = '\0';
+ op.mnc[0] = '\0';
+
+ cb(&error, &op, cbd->data);
+
+out:
+ g_free(cbd);
+
+ return;
+
+error:
+ CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
+
+ g_free(cbd);
+}
+
+static void ciev_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ GAtResultIter iter;
+ int index, value, status;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIEV:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &index))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &value))
+ return;
+
+ if (index == nd->cind_pos[HFP_INDICATOR_SERVICE]) {
+ nd->cind_val[HFP_INDICATOR_SERVICE] = value;
+ if (value)
+ status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+ else
+ status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
+
+ ofono_netreg_status_notify(netreg, status, -1, -1, -1);
+ } else if (index == nd->cind_pos[HFP_INDICATOR_ROAM]) {
+ nd->cind_val[HFP_INDICATOR_ROAM] = value;
+ if (value)
+ status = NETWORK_REGISTRATION_STATUS_ROAMING;
+
+ ofono_netreg_status_notify(netreg, status, -1, -1, -1);
+ } else if (index == nd->cind_pos[HFP_INDICATOR_SIGNAL]) {
+ nd->cind_val[HFP_INDICATOR_SIGNAL] = value;
+ ofono_netreg_strength_notify(netreg, value * 20);
+ }
+
+ return;
+}
+
+static void signal_strength_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_strength_cb_t cb = cbd->cb;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ GAtResultIter iter;
+ int index, strength;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, -1, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIND:")) {
+ CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
+ return;
+ }
+
+ index = 1;
+
+ while (g_at_result_iter_next_number(&iter, &strength)) {
+ if (index == nd->cind_pos[HFP_INDICATOR_SIGNAL]) {
+ nd->cind_val[HFP_INDICATOR_SIGNAL] = strength;
+ break;
+ }
+
+ index++;
+ }
+
+ ofono_debug("signal_strength_cb: %d", strength);
+
+ cb(&error, strength * 20, cbd->data);
+}
+
+static void registration_status_cb(gboolean ok, GAtResult *result,
+ gpointer user_data)
+{
+ struct cb_data *cbd = user_data;
+ ofono_netreg_status_cb_t cb = cbd->cb;
+ struct netreg_data *nd = ofono_netreg_get_data(cbd->user);
+ GAtResultIter iter;
+ int index, value, status;
+ struct ofono_error error;
+
+ decode_at_error(&error, g_at_result_final_response(result));
+
+ if (!ok) {
+ cb(&error, -1, -1, -1, -1, cbd->data);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIND:")) {
+ CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, cbd->data);
+ return;
+ }
+
+ index = 1;
+
+ while (g_at_result_iter_next_number(&iter, &value)) {
+
+ if (index == nd->cind_pos[HFP_INDICATOR_SERVICE])
+ nd->cind_val[HFP_INDICATOR_SERVICE] = value;
+
+ if (index == nd->cind_pos[HFP_INDICATOR_ROAM])
+ nd->cind_val[HFP_INDICATOR_ROAM] = value;
+
+ index++;
+ }
+
+ if (nd->cind_val[HFP_INDICATOR_SERVICE])
+ status = NETWORK_REGISTRATION_STATUS_REGISTERED;
+ else
+ status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
+
+ if (nd->cind_val[HFP_INDICATOR_ROAM])
+ status = NETWORK_REGISTRATION_STATUS_ROAMING;
+
+ cb(&error, status, -1, -1, -1, cbd->data);
+}
+
+static void hfp_registration_status(struct ofono_netreg *netreg,
+ ofono_netreg_status_cb_t cb,
+ void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ gboolean ok;
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ ok = g_at_chat_send(nd->chat, "AT+CIND?", cind_prefix,
+ registration_status_cb, cbd, g_free);
+ if (ok)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, -1, -1, -1, -1, data);
+}
+
+static void hfp_current_operator(struct ofono_netreg *netreg,
+ ofono_netreg_operator_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+ gboolean ok;
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ ok = g_at_chat_send(nd->chat, "AT+COPS=3,0", NULL,
+ NULL, cbd, NULL);
+
+ if (ok)
+ ok = g_at_chat_send(nd->chat, "AT+COPS?", cops_prefix,
+ cops_cb, cbd, NULL);
+
+ if (ok)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, NULL, data);
+}
+
+static void hfp_signal_strength(struct ofono_netreg *netreg,
+ ofono_netreg_strength_cb_t cb, void *data)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ struct cb_data *cbd = cb_data_new(cb, data);
+
+ if (!cbd)
+ goto error;
+
+ cbd->user = netreg;
+
+ if (g_at_chat_send(nd->chat, "AT+CIND?", cind_prefix,
+ signal_strength_cb, cbd, g_free) > 0)
+ return;
+
+error:
+ if (cbd)
+ g_free(cbd);
+
+ CALLBACK_WITH_FAILURE(cb, -1, data);
+}
+
+static gboolean hfp_netreg_register(gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+
+ ofono_netreg_register(netreg);
+
+ return FALSE;
+}
+
+static int hfp_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
+ void *user_data)
+{
+ struct hfp_data *data = user_data;
+ struct netreg_data *nd;
+
+ nd = g_new0(struct netreg_data, 1);
+ nd->chat = data->chat;
+ memcpy(nd->cind_pos, data->cind_pos, HFP_INDICATOR_LAST);
+ memcpy(nd->cind_val, data->cind_val, HFP_INDICATOR_LAST);
+
+ ofono_netreg_set_data(netreg, nd);
+
+ g_at_chat_register(nd->chat, "+CIEV:", ciev_notify, FALSE,
+ netreg, NULL);
+
+ g_idle_add(hfp_netreg_register, netreg);
+
+ return 0;
+}
+
+static void hfp_netreg_remove(struct ofono_netreg *netreg)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+
+ g_free(nd);
+}
+
+static struct ofono_netreg_driver driver = {
+ .name = "hfpmodem",
+ .probe = hfp_netreg_probe,
+ .remove = hfp_netreg_remove,
+ .registration_status = hfp_registration_status,
+ .current_operator = hfp_current_operator,
+ .strength = hfp_signal_strength,
+};
+
+void hfp_netreg_init()
+{
+ ofono_netreg_driver_register(&driver);
+}
+
+void hfp_netreg_exit()
+{
+ ofono_netreg_driver_unregister(&driver);
+}
diff --git a/plugins/hfp.c b/plugins/hfp.c
index 5e94a05..be812cd 100644
--- a/plugins/hfp.c
+++ b/plugins/hfp.c
@@ -311,6 +311,7 @@ static void hfp_pre_sim(struct ofono_modem *modem)
DBG("%p", modem);
ofono_voicecall_create(modem, 0, "hfpmodem", data);
+ ofono_netreg_create(modem, 0, "hfpmodem", data);
}
static void hfp_post_sim(struct ofono_modem *modem)
--
1.6.4.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH 0/1] netreg driver for HFP
@ 2009-10-23 21:36 Gustavo F. Padovan
2009-10-23 21:36 ` [PATCH 1/1] Create network registration driver for hfpmodem Gustavo F. Padovan
0 siblings, 1 reply; 9+ messages in thread
From: Gustavo F. Padovan @ 2009-10-23 21:36 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 178 bytes --]
Hi,
The following patch creates the netreg driver for hfpmodem. Please review it,
probably I missed something since it's my first patch to oFono.
Gustavo F. Padovan
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/1] Create network registration driver for hfpmodem
2009-10-23 21:36 [PATCH 0/1] netreg driver for HFP Gustavo F. Padovan
@ 2009-10-23 21:36 ` Gustavo F. Padovan
2009-10-26 9:01 ` Naveen Verma
0 siblings, 1 reply; 9+ messages in thread
From: Gustavo F. Padovan @ 2009-10-23 21:36 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 7192 bytes --]
This driver handles phone informations about registration status, signal
strength and roaming status listening +CIEV commands.
It also gets the Network Operator name with +COPS commands.
---
Makefile.am | 3 +-
drivers/hfpmodem/hfpmodem.c | 2 +
drivers/hfpmodem/hfpmodem.h | 3 +
drivers/hfpmodem/network-registration.c | 172 +++++++++++++++++++++++++++++++
plugins/hfp.c | 1 +
5 files changed, 180 insertions(+), 1 deletions(-)
create mode 100644 drivers/hfpmodem/network-registration.c
diff --git a/Makefile.am b/Makefile.am
index 561eeb0..332e10b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -123,7 +123,8 @@ builtin_modules += hfpmodem
builtin_sources += drivers/atmodem/atutil.h \
drivers/hfpmodem/hfpmodem.h \
drivers/hfpmodem/hfpmodem.c \
- drivers/hfpmodem/voicecall.c
+ drivers/hfpmodem/voicecall.c \
+ drivers/hfpmodem/network-registration.c
builtin_modules += modemconf
builtin_sources += plugins/modemconf.c
diff --git a/drivers/hfpmodem/hfpmodem.c b/drivers/hfpmodem/hfpmodem.c
index 03b5ea0..58ae03d 100644
--- a/drivers/hfpmodem/hfpmodem.c
+++ b/drivers/hfpmodem/hfpmodem.c
@@ -42,6 +42,7 @@
static int hfpmodem_init(void)
{
hfp_voicecall_init();
+ hfp_netreg_init();
return 0;
}
@@ -49,6 +50,7 @@ static int hfpmodem_init(void)
static void hfpmodem_exit(void)
{
hfp_voicecall_exit();
+ hfp_netreg_exit();
}
OFONO_PLUGIN_DEFINE(hfpmodem, "Hands-Free Profile Driver", VERSION,
diff --git a/drivers/hfpmodem/hfpmodem.h b/drivers/hfpmodem/hfpmodem.h
index 6c6ab6f..3b30d83 100644
--- a/drivers/hfpmodem/hfpmodem.h
+++ b/drivers/hfpmodem/hfpmodem.h
@@ -61,6 +61,9 @@ struct hfp_data {
gint cind_val[HFP_INDICATOR_LAST];
};
+extern void hfp_netreg_init();
+extern void hfp_netreg_exit();
+
extern void hfp_voicecall_init();
extern void hfp_voicecall_exit();
diff --git a/drivers/hfpmodem/network-registration.c b/drivers/hfpmodem/network-registration.c
new file mode 100644
index 0000000..c23d07e
--- /dev/null
+++ b/drivers/hfpmodem/network-registration.c
@@ -0,0 +1,172 @@
+/*
+ *
+ * oFono - Open Source Telephony
+ *
+ * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
+ * Copyright (C) 2009 ProFUSION embedded systems. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <ofono/log.h>
+#include <ofono/modem.h>
+#include <ofono/netreg.h>
+
+#include "gatchat.h"
+#include "gatresult.h"
+
+#include "hfpmodem.h"
+
+#define OFONO_MAX_HFP_OPERATOR_NAME_LENGTH 16
+
+static const char *cops_prefix[] = { "+COPS:", NULL };
+
+struct netreg_data {
+ GAtChat *chat;
+ unsigned char cind_pos[HFP_INDICATOR_LAST];
+ int cind_val[HFP_INDICATOR_LAST];
+ char operator[16];
+};
+
+static void cops_name_notify(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ GAtResultIter iter;
+ int format;
+ const char *name;
+
+ if (!ok) {
+ ofono_error("Unable to get name of the registered Network");
+ ofono_netreg_remove(netreg);
+ return;
+ }
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+COPS:"))
+ return;
+
+ g_at_result_iter_skip_next(&iter);
+
+ ok = g_at_result_iter_next_number(&iter, &format);
+
+ if (ok == FALSE || format != 0)
+ return;
+
+ if (g_at_result_iter_next_string(&iter, &name) == FALSE)
+ return;
+
+ strncpy(nd->operator, name, OFONO_MAX_HFP_OPERATOR_NAME_LENGTH);
+ nd->operator[OFONO_MAX_HFP_OPERATOR_NAME_LENGTH] = '\0';
+}
+
+static void cops_notify(gboolean ok, GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+
+ if (!ok) {
+ ofono_error("Unable to get name of the registered Network");
+ ofono_netreg_remove(netreg);
+ return;
+ }
+
+ g_at_chat_send(nd->chat, "AT+COPS?", cops_prefix,
+ cops_name_notify, netreg, NULL);
+}
+
+static void ciev_notify(GAtResult *result, gpointer user_data)
+{
+ struct ofono_netreg *netreg = user_data;
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+ GAtResultIter iter;
+ int index, value;
+
+ g_at_result_iter_init(&iter, result);
+
+ if (!g_at_result_iter_next(&iter, "+CIEV:"))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &index))
+ return;
+
+ if (!g_at_result_iter_next_number(&iter, &value))
+ return;
+
+ if (index == nd->cind_pos[HFP_INDICATOR_SERVICE])
+ nd->cind_val[HFP_INDICATOR_SERVICE] = value;
+ else if (index == nd->cind_pos[HFP_INDICATOR_ROAM])
+ nd->cind_val[HFP_INDICATOR_ROAM] = value;
+ else if (index == nd->cind_pos[HFP_INDICATOR_SIGNAL])
+ nd->cind_val[HFP_INDICATOR_SIGNAL] = value;
+
+ return;
+}
+
+static int hfp_netreg_probe(struct ofono_netreg *netreg, unsigned int vendor,
+ void *user_data)
+{
+ struct hfp_data *data = user_data;
+ struct netreg_data *nd;
+
+ nd = g_new0(struct netreg_data, 1);
+ nd->chat = data->chat;
+ memcpy(nd->cind_pos, data->cind_pos, HFP_INDICATOR_LAST);
+ memcpy(nd->cind_val, data->cind_val, HFP_INDICATOR_LAST);
+
+ ofono_netreg_set_data(netreg, nd);
+
+ g_at_chat_send(nd->chat, "AT+COPS=3,0", NULL,
+ cops_notify, netreg, NULL);
+ g_at_chat_register(nd->chat, "+CIEV:", ciev_notify, FALSE,
+ netreg, NULL);
+
+ return 0;
+}
+
+static void hfp_netreg_remove(struct ofono_netreg *netreg)
+{
+ struct netreg_data *nd = ofono_netreg_get_data(netreg);
+
+ g_free(nd);
+}
+
+static struct ofono_netreg_driver driver = {
+ .name = "hfpmodem",
+ .probe = hfp_netreg_probe,
+ .remove = hfp_netreg_remove,
+};
+
+void hfp_netreg_init()
+{
+ ofono_netreg_driver_register(&driver);
+}
+
+void hfp_netreg_exit()
+{
+ ofono_netreg_driver_unregister(&driver);
+}
diff --git a/plugins/hfp.c b/plugins/hfp.c
index 5e94a05..be812cd 100644
--- a/plugins/hfp.c
+++ b/plugins/hfp.c
@@ -311,6 +311,7 @@ static void hfp_pre_sim(struct ofono_modem *modem)
DBG("%p", modem);
ofono_voicecall_create(modem, 0, "hfpmodem", data);
+ ofono_netreg_create(modem, 0, "hfpmodem", data);
}
static void hfp_post_sim(struct ofono_modem *modem)
--
1.6.4.4
^ permalink raw reply related [flat|nested] 9+ messages in thread* Re: [PATCH 1/1] Create network registration driver for hfpmodem
2009-10-23 21:36 ` [PATCH 1/1] Create network registration driver for hfpmodem Gustavo F. Padovan
@ 2009-10-26 9:01 ` Naveen Verma
2009-10-26 14:27 ` Gustavo F. Padovan
0 siblings, 1 reply; 9+ messages in thread
From: Naveen Verma @ 2009-10-26 9:01 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 1714 bytes --]
> @@ -0,0 +1,172 @@
> +/*
> + *
> + * oFono - Open Source Telephony
> + *
> + * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
> + * Copyright (C) 2009 ProFUSION embedded systems. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
> USA
> + *
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#define _GNU_SOURCE
> +#include <string.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include <glib.h>
> +
> +#include <ofono/log.h>
> +#include <ofono/modem.h>
> +#include <ofono/netreg.h>
> +
> +#include "gatchat.h"
> +#include "gatresult.h"
> +
> +#include "hfpmodem.h"
> +
> +#define OFONO_MAX_HFP_OPERATOR_NAME_LENGTH 16
> +
> +static const char *cops_prefix[] = { "+COPS:", NULL };
> +
> +struct netreg_data {
> + GAtChat *chat;
> + unsigned char cind_pos[HFP_INDICATOR_LAST];
> + int cind_val[HFP_INDICATOR_LAST];
> + char operator[16];
>
-- Should we use above #define for operator name length?
-Br
Naveen
[-- Attachment #2: attachment.html --]
[-- Type: text/html, Size: 2061 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH 1/1] Create network registration driver for hfpmodem
2009-10-26 9:01 ` Naveen Verma
@ 2009-10-26 14:27 ` Gustavo F. Padovan
0 siblings, 0 replies; 9+ messages in thread
From: Gustavo F. Padovan @ 2009-10-26 14:27 UTC (permalink / raw)
To: ofono
[-- Attachment #1: Type: text/plain, Size: 2125 bytes --]
On Mon, Oct 26, 2009 at 7:01 AM, Naveen Verma <ernaveenverma@gmail.com> wrote:
>
>
>>
>> @@ -0,0 +1,172 @@
>> +/*
>> + *
>> + * oFono - Open Source Telephony
>> + *
>> + * Copyright (C) 2008-2009 Intel Corporation. All rights reserved.
>> + * Copyright (C) 2009 ProFUSION embedded systems. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
>> USA
>> + *
>> + */
>> +
>> +#ifdef HAVE_CONFIG_H
>> +#include <config.h>
>> +#endif
>> +
>> +#define _GNU_SOURCE
>> +#include <string.h>
>> +#include <stdlib.h>
>> +#include <stdio.h>
>> +
>> +#include <glib.h>
>> +
>> +#include <ofono/log.h>
>> +#include <ofono/modem.h>
>> +#include <ofono/netreg.h>
>> +
>> +#include "gatchat.h"
>> +#include "gatresult.h"
>> +
>> +#include "hfpmodem.h"
>> +
>> +#define OFONO_MAX_HFP_OPERATOR_NAME_LENGTH 16
>> +
>> +static const char *cops_prefix[] = { "+COPS:", NULL };
>> +
>> +struct netreg_data {
>> + GAtChat *chat;
>> + unsigned char cind_pos[HFP_INDICATOR_LAST];
>> + int cind_val[HFP_INDICATOR_LAST];
>> + char operator[16];
>
> -- Should we use above #define for operator name length?
Yes, I missed that. Thanks.
> -Br
> Naveen
>
>
>
> _______________________________________________
> ofono mailing list
> ofono(a)ofono.org
> http://lists.ofono.org/listinfo/ofono
>
>
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2009-11-04 17:54 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-03 17:04 [PATCH 1/1] Create network registration driver for hfpmodem Gustavo F. Padovan
2009-11-04 17:54 ` Denis Kenzior
[not found] <0463F45F3606F4428ED35AC8C709F92E089B9CBAB7@pdsmsx502.ccr.corp.intel.com>
2009-11-03 17:46 ` Zhenhua Zhang
2009-11-03 16:53 ` Gustavo F. Padovan
-- strict thread matches above, loose matches on Subject: below --
2009-11-03 17:44 Gustavo F. Padovan
2009-10-30 22:55 Gustavo F. Padovan
2009-10-23 21:36 [PATCH 0/1] netreg driver for HFP Gustavo F. Padovan
2009-10-23 21:36 ` [PATCH 1/1] Create network registration driver for hfpmodem Gustavo F. Padovan
2009-10-26 9:01 ` Naveen Verma
2009-10-26 14:27 ` Gustavo F. Padovan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.