Skip to contentSkip to conversation

bluetooth: add CIND and CIEV support for HFP AG

PATCH Superseded Frédéric Danis 1 participant 5 messages Feb 18, 2011

v1 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

cover bluetooth: add CIND and CIEV support for HFP AG

Add signal strength APIs in netreg atom
Add CIND and CIEV support in emulator atom for service, roaming and signal indicators

Frédéric Danis (4):
emulator: add network info support for HFP
netreg: add get signal strength API
netreg: add support for signal strength get and watch APIs
emulator: add network signal support for HFP

 include/netreg.h |    1 +
 src/emulator.c   |  162 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/network.c    |   61 ++++++++++++++++++++
 src/ofono.h      |   10 +++
 4 files changed, 234 insertions(+), 0 deletions(-)
#1 lore raw

PATCH 1/4 emulator: add network info support for HFP

Add CIND and CIEV support related to network info

---
 src/emulator.c |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 129 insertions(+), 0 deletions(-)
src/emulator.c +129 -0
index 101b33d..d8cd32f 100644
@@ -28,12 +28,18 @@
 #include <glib.h>
 
 #include "ofono.h"
+#include "common.h"
 #include "gatserver.h"
 
 struct ofono_emulator {
 	struct ofono_atom *atom;
 	enum ofono_emulator_type type;
 	GAtServer *server;
+	struct ofono_netreg *netreg;
+	unsigned int netreg_watch;
+	unsigned int status_watch;
+	gboolean net_registered;
+	gboolean roaming;
 };
 
 static void emulator_debug(const char *str, void *data)
@@ -41,6 +47,99 @@ static void emulator_debug(const char *str, void *data)
 	ofono_info("%s: %s\n", (char *)data, str);
 }
 
+static void net_status_changed(int status, int lac, int ci, int tech,
+					const char *mcc, const char *mnc,
+					void *data)
+{
+	struct ofono_emulator *em = data;
+	gboolean old_registered = em->net_registered;
+	gboolean old_roaming = em->roaming;
+	char buf[20];
+
+	DBG("%d", status);
+
+	switch (status) {
+	case NETWORK_REGISTRATION_STATUS_REGISTERED:
+		em->net_registered = 1;
+		em->roaming = 0;
+		break;
+	case NETWORK_REGISTRATION_STATUS_ROAMING:
+		em->net_registered = 1;
+		em->roaming = 1;
+		break;
+	default:
+		em->net_registered = 0;
+		em->roaming = 0;
+		break;
+	}
+
+	if (em->net_registered != old_registered) {
+		sprintf(buf, "+CIEV: 1,%d", em->net_registered);
+		g_at_server_send_info(em->server, buf, TRUE);
+	}
+
+	if (em->roaming != old_roaming) {
+		sprintf(buf, "+CIEV: 6,%d", em->roaming);
+		g_at_server_send_info(em->server, buf, TRUE);
+	}
+}
+
+static void netreg_watch(struct ofono_atom *atom,
+				enum ofono_atom_watch_condition cond,
+				void *data)
+{
+	struct ofono_emulator *em = data;
+	int status;
+
+	DBG("%p %sregistered", atom, cond ? "un" : "");
+
+	if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
+		em->status_watch = 0;
+		net_status_changed(NETWORK_REGISTRATION_STATUS_NOT_REGISTERED,
+					0, 0, 0, NULL, NULL, em);
+
+		em->netreg = NULL;
+
+		return;
+	}
+
+	em->netreg = __ofono_atom_get_data(atom);
+
+	status = ofono_netreg_get_status(em->netreg);
+	net_status_changed(status, 0, 0, 0, NULL, NULL, em);
+
+	em->status_watch = __ofono_netreg_add_status_watch(em->netreg,
+					net_status_changed, em, NULL);
+}
+
+static void cind_cb(GAtServer *server, GAtServerRequestType type,
+			GAtResult *result, gpointer user_data)
+{
+	struct ofono_emulator *em = user_data;
+	char buf[30];
+
+	switch (type) {
+	case G_AT_SERVER_REQUEST_TYPE_QUERY:
+		sprintf(buf, "+CIND: %d,0,0,0,0,%d,0", em->net_registered,
+					em->roaming);
+		g_at_server_send_info(em->server, buf, FALSE);
+		g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+		break;
+
+	case G_AT_SERVER_REQUEST_TYPE_SUPPORT:
+		g_at_server_send_info(server, "+CIND: (\"service\",(0,1)),"
+				"(\"call\",(0,1)),(\"callsetup\",(0-3)),"
+				"(\"callheld\",(0-2)),(\"signal\",(0-5)),"
+				"(\"roam\",(0,1)),(\"battchg\",(0-5))", FALSE);
+		g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+		break;
+
+	default:
+		g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+		break;
+	}
+}
+
 static void emulator_disconnect(gpointer user_data)
 {
 	struct ofono_emulator *em = user_data;
@@ -53,9 +152,19 @@ static void emulator_disconnect(gpointer user_data)
 static void emulator_unregister(struct ofono_atom *atom)
 {
 	struct ofono_emulator *em = __ofono_atom_get_data(atom);
+	struct ofono_modem *modem;
 
 	DBG("%p", em);
 
+	if (em->netreg) {
+		if (em->status_watch)
+			__ofono_netreg_remove_status_watch(em->netreg,
+							em->status_watch);
+
+		modem = __ofono_atom_get_modem(em->atom);
+		__ofono_modem_remove_atom_watch(modem, em->netreg_watch);
+	}
+
 	g_at_server_unref(em->server);
 	em->server = NULL;
 }
@@ -63,6 +172,8 @@ static void emulator_unregister(struct ofono_atom *atom)
 void ofono_emulator_register(struct ofono_emulator *em, int fd)
 {
 	GIOChannel *io;
+	struct ofono_modem *modem;
+	struct ofono_atom *netreg_atom;
 
 	DBG("%p, %d", em, fd);
 
@@ -81,6 +192,24 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
 	g_at_server_set_disconnect_function(em->server,
 						emulator_disconnect, em);
 
+	if (em->type == OFONO_EMULATOR_TYPE_HFP) {
+		g_at_server_register(em->server, "+CIND", cind_cb, em, NULL);
+
+		modem = __ofono_atom_get_modem(em->atom);
+
+		em->netreg_watch = __ofono_modem_add_atom_watch(modem,
+						OFONO_ATOM_TYPE_NETREG,
+						netreg_watch, em, 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,
+					em);
+	}
+
 	__ofono_atom_register(em->atom, emulator_unregister);
 }
 
Signature · 1 line
1.7.1
#2 lore raw

PATCH 2/4 netreg: add get signal strength API

In reply to Frédéric Danis
---
 include/netreg.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
include/netreg.h +1 -0
index 26a3442..871fe6d 100644
@@ -111,6 +111,7 @@ void *ofono_netreg_get_data(struct ofono_netreg *netreg);
 int ofono_netreg_get_location(struct ofono_netreg *netreg);
 int ofono_netreg_get_cellid(struct ofono_netreg *netreg);
 int ofono_netreg_get_status(struct ofono_netreg *netreg);
+int ofono_netreg_get_strength(struct ofono_netreg *netreg);
 int ofono_netreg_get_technology(struct ofono_netreg *netreg);
 const char *ofono_netreg_get_mcc(struct ofono_netreg *netreg);
 const char *ofono_netreg_get_mnc(struct ofono_netreg *netreg);
Signature · 1 line
1.7.1
#3 lore raw

PATCH 3/4 netreg: add support for signal strength get and watch APIs

In reply to Frédéric Danis
---
 src/network.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ofono.h   |   10 +++++++++
 2 files changed, 71 insertions(+), 0 deletions(-)
src/network.c +61 -0
index c059906..4a0e984 100644
@@ -79,6 +79,7 @@ struct ofono_netreg {
 	GKeyFile *settings;
 	char *imsi;
 	struct ofono_watchlist *status_watches;
+	struct ofono_watchlist *strength_watches;
 	const struct ofono_netreg_driver *driver;
 	void *driver_data;
 	struct ofono_atom *atom;
@@ -1159,6 +1160,51 @@ static void notify_status_watches(struct ofono_netreg *netreg)
 	}
 }
 
+unsigned int __ofono_netreg_add_strength_watch(struct ofono_netreg *netreg,
+				ofono_netreg_strength_notify_cb_t notify,
+				void *data, ofono_destroy_func destroy)
+{
+	struct ofono_watchlist_item *item;
+
+	DBG("%p", netreg);
+
+	if (netreg == 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(netreg->strength_watches, item);
+}
+
+gboolean __ofono_netreg_remove_strength_watch(struct ofono_netreg *netreg,
+						unsigned int id)
+{
+	DBG("%p", netreg);
+
+	return __ofono_watchlist_remove_item(netreg->strength_watches, id);
+}
+
+static void notify_strength_watches(struct ofono_netreg *netreg)
+{
+	struct ofono_watchlist_item *item;
+	GSList *l;
+	ofono_netreg_strength_notify_cb_t notify;
+
+	for (l = netreg->strength_watches->items; l; l = l->next) {
+		item = l->data;
+		notify = item->notify;
+
+		notify(netreg->signal_strength, item->notify_data);
+	}
+}
+
 static void reset_available(struct network_operator_data *old,
 				const struct ofono_network_operator *new)
 {
@@ -1400,6 +1446,8 @@ void ofono_netreg_strength_notify(struct ofono_netreg *netreg, int strength)
 					OFONO_NETWORK_REGISTRATION_INTERFACE,
 					"Strength", DBUS_TYPE_BYTE,
 					&strength);
+
+		notify_strength_watches(netreg);
 	}
 }
 
@@ -1599,6 +1647,14 @@ int ofono_netreg_get_status(struct ofono_netreg *netreg)
 	return netreg->status;
 }
 
+int ofono_netreg_get_strength(struct ofono_netreg *netreg)
+{
+	if (netreg == NULL)
+		return -1;
+
+	return netreg->signal_strength;
+}
+
 int ofono_netreg_get_technology(struct ofono_netreg *netreg)
 {
 	if (netreg == NULL)
@@ -1659,6 +1715,9 @@ static void netreg_unregister(struct ofono_atom *atom)
 	__ofono_watchlist_free(netreg->status_watches);
 	netreg->status_watches = NULL;
 
+	__ofono_watchlist_free(netreg->strength_watches);
+	netreg->strength_watches = NULL;
+
 	for (l = netreg->operator_list; l; l = l->next) {
 		struct network_operator_data *opd = l->data;
 
@@ -1857,6 +1916,8 @@ void ofono_netreg_register(struct ofono_netreg *netreg)
 
 	netreg->status_watches = __ofono_watchlist_new(g_free);
 
+	netreg->strength_watches = __ofono_watchlist_new(g_free);
+
 	ofono_modem_add_interface(modem, OFONO_NETWORK_REGISTRATION_INTERFACE);
 
 	if (netreg->driver->registration_status != NULL)
src/ofono.h +10 -0
index 14dcd18..f82f447 100644
@@ -404,6 +404,16 @@ unsigned int __ofono_netreg_add_status_watch(struct ofono_netreg *netreg,
 gboolean __ofono_netreg_remove_status_watch(struct ofono_netreg *netreg,
 						unsigned int id);
 
+typedef void (*ofono_netreg_strength_notify_cb_t)(int signal_strength,
+							void *data);
+
+unsigned int __ofono_netreg_add_strength_watch(struct ofono_netreg *netreg,
+				ofono_netreg_strength_notify_cb_t cb,
+				void *data, ofono_destroy_func destroy);
+
+gboolean __ofono_netreg_remove_strength_watch(struct ofono_netreg *netreg,
+						unsigned int id);
+
 void __ofono_netreg_set_base_station_name(struct ofono_netreg *netreg,
 						const char *name);
 
Signature · 1 line
1.7.1
#4 lore raw

PATCH 4/4 emulator: add network signal support for HFP

In reply to Frédéric Danis
---
 src/emulator.c |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)
src/emulator.c +35 -2
index d8cd32f..6835f96 100644
@@ -38,8 +38,10 @@ struct ofono_emulator {
 	struct ofono_netreg *netreg;
 	unsigned int netreg_watch;
 	unsigned int status_watch;
+	unsigned int strength_watch;
 	gboolean net_registered;
 	gboolean roaming;
+	int strength;
 };
 
 static void emulator_debug(const char *str, void *data)
@@ -84,12 +86,29 @@ static void net_status_changed(int status, int lac, int ci, int tech,
 	}
 }
 
+static void net_strength_changed(int signal_strength, void *data)
+{
+	struct ofono_emulator *em = data;
+	int old_strength = em->strength;
+	char buf[20];
+
+	DBG("%d", signal_strength);
+
+	em->strength = (signal_strength + 20) / 21;
+
+	if (em->strength != old_strength) {
+		sprintf(buf, "+CIEV: 5,%d", em->strength);
+		g_at_server_send_info(em->server, buf, TRUE);
+	}
+}
+
 static void netreg_watch(struct ofono_atom *atom,
 				enum ofono_atom_watch_condition cond,
 				void *data)
 {
 	struct ofono_emulator *em = data;
 	int status;
+	int strength;
 
 	DBG("%p %sregistered", atom, cond ? "un" : "");
 
@@ -98,6 +117,9 @@ static void netreg_watch(struct ofono_atom *atom,
 		net_status_changed(NETWORK_REGISTRATION_STATUS_NOT_REGISTERED,
 					0, 0, 0, NULL, NULL, em);
 
+		em->strength_watch = 0;
+		net_strength_changed(0, em);
+
 		em->netreg = NULL;
 
 		return;
@@ -110,6 +132,13 @@ static void netreg_watch(struct ofono_atom *atom,
 
 	em->status_watch = __ofono_netreg_add_status_watch(em->netreg,
 					net_status_changed, em, NULL);
+
+	strength = ofono_netreg_get_strength(em->netreg);
+	net_strength_changed(strength, em);
+
+	em->strength_watch = __ofono_netreg_add_strength_watch(em->netreg,
+					net_strength_changed, em, NULL);
+
 }
 
 static void cind_cb(GAtServer *server, GAtServerRequestType type,
@@ -120,8 +149,8 @@ static void cind_cb(GAtServer *server, GAtServerRequestType type,
 
 	switch (type) {
 	case G_AT_SERVER_REQUEST_TYPE_QUERY:
-		sprintf(buf, "+CIND: %d,0,0,0,0,%d,0", em->net_registered,
-					em->roaming);
+		sprintf(buf, "+CIND: %d,0,0,0,%d,%d,0", em->net_registered,
+					em->strength, em->roaming);
 		g_at_server_send_info(em->server, buf, FALSE);
 		g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
 		break;
@@ -161,6 +190,10 @@ static void emulator_unregister(struct ofono_atom *atom)
 			__ofono_netreg_remove_status_watch(em->netreg,
 							em->status_watch);
 
+		if (em->strength_watch)
+			__ofono_netreg_remove_strength_watch(em->netreg,
+							em->strength_watch);
+
 		modem = __ofono_atom_get_modem(em->atom);
 		__ofono_modem_remove_atom_watch(modem, em->netreg_watch);
 	}
Signature · 1 line
1.7.1