[PATCH v0 0/9] External HFP: Add SCO
by Claudio Takahasi
This patch series adds Bluetooth SCO socket declaration and the initial
code to manage HF audio connections.
Some Bluetooth functions and structs are being declared locally, Bluetooth
headers dependency will be removed in the future.
Claudio Takahasi (9):
bluez5: Add SCO socket declarations
bluez5: Add bt_bacpy()
hfp_hf_bluez5: Add SCO listen socket
bluez5: Add bt_ba2str()
bluez5: Add bt_getsockpeers()
bluez5: Add RFCOMM socket address declaration
hfp_hf_bluez5: Add rejecting SCO connection
hfp_hf_bluez5: Reject SCO if source doesn't match
hfp_hf_bluez5: Fix missing fd close
plugins/bluez5.c | 38 ++++++++++++
plugins/bluez5.h | 42 +++++++++++++
plugins/hfp_hf_bluez5.c | 162 +++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 232 insertions(+), 10 deletions(-)
--
1.7.11.7
7 years, 12 months
[PATCH v0 1/3] bluez5: Add SCO socket declarations
by Claudio Takahasi
Adds local copy of SCO Bluetooth sockets declarations, since the
objective to avoid including BlueZ library headers.
---
plugins/bluez5.c | 3 +++
plugins/bluez5.h | 28 ++++++++++++++++++++++++++++
plugins/hfp_hf_bluez5.c | 2 ++
3 files changed, 33 insertions(+)
diff --git a/plugins/bluez5.c b/plugins/bluez5.c
index 8d8b565..d471454 100644
--- a/plugins/bluez5.c
+++ b/plugins/bluez5.c
@@ -24,6 +24,9 @@
#endif
#include <errno.h>
+#include <stdint.h>
+#include <sys/socket.h>
+
#include <glib.h>
#define OFONO_API_SUBJECT_TO_CHANGE
diff --git a/plugins/bluez5.h b/plugins/bluez5.h
index 3aa8ffe..fd0704e 100644
--- a/plugins/bluez5.h
+++ b/plugins/bluez5.h
@@ -28,6 +28,34 @@
#define HFP_HS_UUID "0000111e-0000-1000-8000-00805f9b34fb"
#define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb"
+#ifndef AF_BLUETOOTH
+#define AF_BLUETOOTH 31
+#define PF_BLUETOOTH AF_BLUETOOTH
+#endif
+
+#define BTPROTO_SCO 2
+
+#define SOL_SCO 17
+
+#ifndef SOL_BLUETOOTH
+#define SOL_BLUETOOTH 274
+#endif
+
+#define BT_DEFER_SETUP 7
+
+/* BD Address */
+typedef struct {
+ uint8_t b[6];
+} __attribute__((packed)) bdaddr_t;
+
+#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
+
+/* SCO socket address */
+struct sockaddr_sco {
+ sa_family_t sco_family;
+ bdaddr_t sco_bdaddr;
+};
+
int bluetooth_register_profile(DBusConnection *conn, const char *uuid,
const char *name, const char *object);
diff --git a/plugins/hfp_hf_bluez5.c b/plugins/hfp_hf_bluez5.c
index f6ceb76..0e496ee 100644
--- a/plugins/hfp_hf_bluez5.c
+++ b/plugins/hfp_hf_bluez5.c
@@ -24,9 +24,11 @@
#endif
#include <errno.h>
+#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <sys/socket.h>
#include <glib.h>
--
1.7.11.7
7 years, 12 months
SIMCOM support
by Viallard Anthony
Hello ofono guys,
I've got a embedded device with SIM5216E modem. Based on the previous
work done by my colleague Jean-Christian de Rivaz (you can see previous
talk on this mailing list about this modem "Some experiments with the
SIMCOM SIM5216E modem on a ARM926 board"), the simcom AT doc, my
MacGyver kit and my resourcefulness, i do a patch for ofono to support
this modem (and maybe others models).
I attach the patch to this email.
While making this patch, I wondered about that :
* After entering a pin code, ofono goes too fast and checks too
early the sim pin status with "CPIN?". The ME responds "CME Error : 14
(SIM busy)" and ofono stops here. Ofono doesn't send more CPIN? or
intercept the "+CPIN: READY" that the modem send after a while when SIM
is back online. So, I use the same workaround that for ZTE : sending
severals AT+CPIN? commands during 20 seconds until having "+CPIN:
READY". It works well but as my modem sends the "+CPIN: READY" from its
own, I think I can use another mechanism more "standard" in ofono, isn't
it ?
* I want to save power when i doesn't need the modem. So, i guess it
is the purpose of the "org.ofono.Modem.SetProperty" dbus method and the
setting "Powered". When I set "Powered" to "False", I see ofono calls
the "disable" callback of "struct ofono_modem_driver", so I think its
here I must write the famous CFUN command(s) to put modem down. In the
AT doc for SIMCOM, I have severals CFUN values for, i think, disable
purpose :
0 – minimum functionality
4 – disable phone both transmit and receive RF circuits
7 – Offline Mode
For now, i do a CFUN=4 but maybe i need to do more and add CFUN=7 ? Or
maybe use CFUN=0 ?
Can the "disable" callback be called by ofono in other case and so, i
must only do a CFUN=4 ?
* I would like to do a reset of the modem at start and at end of
ofono life (with AT+CFUN=6 or AT+CRESET). The purpose is having a modem
always in init state for ofono and the others programs. Do you think its
a good idea ?
Best regards,
Anthony Viallard.
8 years
[PATCH] hfp_hf_bluez5: Add SLC establishment procedure
by Vinicius Costa Gomes
When receiving a NewConnection call from BlueZ, initiates the Service
Level Connection using the received file descriptor. The HFP modem
sub-components (devinfo, voicecall, netreg, handsfree and callvolume)
are created at this point.
---
Now that we don't change how hfp_slc_info is allocated, this is the last
patch in the "HFP Service Level Connection establishment" series.
plugins/hfp_hf_bluez5.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 169 insertions(+), 6 deletions(-)
diff --git a/plugins/hfp_hf_bluez5.c b/plugins/hfp_hf_bluez5.c
index d4f158e..f6ceb76 100644
--- a/plugins/hfp_hf_bluez5.c
+++ b/plugins/hfp_hf_bluez5.c
@@ -24,17 +24,27 @@
#endif
#include <errno.h>
+#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
#include <glib.h>
#include <gdbus.h>
+#include <gatchat.h>
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/modem.h>
#include <ofono/dbus.h>
#include <ofono/plugin.h>
#include <ofono/log.h>
+#include <ofono/devinfo.h>
+#include <ofono/netreg.h>
+#include <ofono/voicecall.h>
+#include <ofono/call-volume.h>
+#include <ofono/handsfree.h>
+
+#include <drivers/hfpmodem/slc.h>
#include "bluez5.h"
@@ -44,12 +54,115 @@
#define HFP_EXT_PROFILE_PATH "/bluetooth/profile/hfp_hf"
+struct hfp {
+ struct hfp_slc_info info;
+ DBusMessage *msg;
+};
+
static GHashTable *modem_hash = NULL;
static GHashTable *devices_proxies = NULL;
static GDBusClient *bluez = NULL;
+static void hfp_debug(const char *str, void *user_data)
+{
+ const char *prefix = user_data;
+
+ ofono_info("%s%s", prefix, str);
+}
+
+static void slc_established(gpointer userdata)
+{
+ struct ofono_modem *modem = userdata;
+ struct hfp *hfp = ofono_modem_get_data(modem);
+ DBusMessage *msg;
+
+ ofono_modem_set_powered(modem, TRUE);
+
+ msg = dbus_message_new_method_return(hfp->msg);
+ g_dbus_send_message(ofono_dbus_get_connection(), msg);
+ dbus_message_unref(hfp->msg);
+ hfp->msg = NULL;
+
+ ofono_info("Service level connection established");
+}
+
+static void slc_failed(gpointer userdata)
+{
+ struct ofono_modem *modem = userdata;
+ struct hfp *hfp = ofono_modem_get_data(modem);
+ struct hfp_slc_info *info = &hfp->info;
+ DBusMessage *msg;
+
+ msg = g_dbus_create_error(hfp->msg, BLUEZ_ERROR_INTERFACE
+ ".Failed",
+ "HFP Handshake failed");
+
+ g_dbus_send_message(ofono_dbus_get_connection(), msg);
+ dbus_message_unref(hfp->msg);
+ hfp->msg = NULL;
+
+ ofono_error("Service level connection failed");
+ ofono_modem_set_powered(modem, FALSE);
+
+ g_at_chat_unref(info->chat);
+ info->chat = NULL;
+}
+
+static void hfp_disconnected_cb(gpointer user_data)
+{
+ struct ofono_modem *modem = user_data;
+ struct hfp *hfp = ofono_modem_get_data(modem);
+ struct hfp_slc_info *info = &hfp->info;
+
+ DBG("HFP disconnected");
+
+ ofono_modem_set_powered(modem, FALSE);
+
+ g_at_chat_unref(info->chat);
+ info->chat = NULL;
+}
+
+static int service_level_connection(struct ofono_modem *modem,
+ int fd, guint16 version)
+{
+ struct hfp *hfp = ofono_modem_get_data(modem);
+ struct hfp_slc_info *info = &hfp->info;
+ GIOChannel *io;
+ GAtSyntax *syntax;
+ GAtChat *chat;
+
+ io = g_io_channel_unix_new(fd);
+ if (io == NULL) {
+ ofono_error("Service level connection failed: %s (%d)",
+ strerror(errno), errno);
+ return -EIO;
+ }
+
+ syntax = g_at_syntax_new_gsm_permissive();
+ chat = g_at_chat_new(io, syntax);
+ g_at_syntax_unref(syntax);
+
+ g_io_channel_set_close_on_unref(io, TRUE);
+ g_io_channel_unref(io);
+
+ if (chat == NULL)
+ return -ENOMEM;
+
+ g_at_chat_set_disconnect_function(chat, hfp_disconnected_cb, modem);
+
+ if (getenv("OFONO_AT_DEBUG"))
+ g_at_chat_set_debug(chat, hfp_debug, "");
+
+ hfp_slc_info_init(info, version);
+ info->chat = chat;
+
+ hfp_slc_establish(info, slc_established, slc_failed, modem);
+
+ return -EINPROGRESS;
+}
+
static struct ofono_modem *modem_register(const char *device,
- const char *alias)
+ const char *device_address, const char *alias)
{
struct ofono_modem *modem;
char *path;
@@ -67,6 +180,8 @@ static struct ofono_modem *modem_register(const char *device,
if (modem == NULL)
return NULL;
+ ofono_modem_set_string(modem, "Address", device_address);
+
ofono_modem_set_name(modem, alias);
ofono_modem_register(modem);
@@ -77,14 +192,32 @@ static struct ofono_modem *modem_register(const char *device,
static int hfp_probe(struct ofono_modem *modem)
{
+ struct hfp *hfp;
+
DBG("modem: %p", modem);
+ hfp = g_new0(struct hfp, 1);
+
+ ofono_modem_set_data(modem, hfp);
+
return 0;
}
static void hfp_remove(struct ofono_modem *modem)
{
+ struct hfp *hfp = ofono_modem_get_data(modem);
+ struct hfp_slc_info *info = &hfp->info;
+
DBG("modem: %p", modem);
+
+ if (hfp->msg)
+ dbus_message_unref(hfp->msg);
+
+ g_at_chat_unref(info->chat);
+
+ g_free(hfp);
+
+ ofono_modem_set_data(modem, NULL);
}
/* power up hardware */
@@ -104,7 +237,16 @@ static int hfp_disable(struct ofono_modem *modem)
static void hfp_pre_sim(struct ofono_modem *modem)
{
+ struct hfp *hfp = ofono_modem_get_data(modem);
+ char *address = (char *) ofono_modem_get_string(modem, "Address");
+
DBG("%p", modem);
+
+ ofono_devinfo_create(modem, 0, "hfpmodem", address);
+ ofono_voicecall_create(modem, 0, "hfpmodem", &hfp->info);
+ ofono_netreg_create(modem, 0, "hfpmodem", &hfp->info);
+ ofono_handsfree_create(modem, 0, "hfpmodem", &hfp->info);
+ ofono_call_volume_create(modem, 0, "hfpmodem", &hfp->info);
}
static void hfp_post_sim(struct ofono_modem *modem)
@@ -126,12 +268,13 @@ static struct ofono_modem_driver hfp_driver = {
static DBusMessage *profile_new_connection(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
+ struct hfp *hfp;
struct ofono_modem *modem;
DBusMessageIter iter;
GDBusProxy *proxy;
DBusMessageIter entry;
- const char *device, *alias;
- int fd;
+ const char *device, *alias, *address;
+ int fd, err;
DBG("Profile handler NewConnection");
@@ -153,6 +296,11 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
dbus_message_iter_get_basic(&iter, &alias);
+ if (g_dbus_proxy_get_property(proxy, "Address", &iter) == FALSE)
+ goto invalid;
+
+ dbus_message_iter_get_basic(&iter, &address);
+
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_UNIX_FD)
goto invalid;
@@ -161,7 +309,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
if (fd < 0)
goto invalid;
- modem = modem_register(device, alias);
+ modem = modem_register(device, address, alias);
if (modem == NULL) {
close(fd);
return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
@@ -169,6 +317,15 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
"Could not register HFP modem");
}
+ err = service_level_connection(modem, fd, HFP_VERSION_LATEST);
+ if (err < 0 && err != -EINPROGRESS)
+ return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
+ ".Rejected",
+ "Not enough resources");
+
+ hfp = ofono_modem_get_data(modem);
+ hfp->msg = dbus_message_ref(msg);
+
return NULL;
invalid:
@@ -252,7 +409,7 @@ static gboolean has_hfp_ag_uuid(DBusMessageIter *array)
static void proxy_added(GDBusProxy *proxy, void *user_data)
{
- const char *interface, *path, *alias;
+ const char *interface, *path, *alias, *address;
DBusMessageIter iter;
interface = g_dbus_proxy_get_interface(proxy);
@@ -276,7 +433,13 @@ static void proxy_added(GDBusProxy *proxy, void *user_data)
dbus_message_iter_get_basic(&iter, &alias);
- modem_register(path, alias);
+
+ if (g_dbus_proxy_get_property(proxy, "Address", &iter) == FALSE)
+ return;
+
+ dbus_message_iter_get_basic(&iter, &address);
+
+ modem_register(path, address, alias);
}
static void proxy_removed(GDBusProxy *proxy, void *user_data)
--
1.8.1.1
8 years
[PATCH 00/10] HFP Service Level Connection establishment
by Vinicius Costa Gomes
Hi,
This series include the modem registration when a BlueZ device appears
with support for HFP AG.
Also, a modem is registered when NewConnection() comes and we don't
have a modem associated yet.
For the SLC establishment, only the file descriptor from NewConnection()
is used.
Cheers,
Vinicius Costa Gomes (10):
hfp_hf_bluez5: Initial GDBusClient for BlueZ
hfp_hf_bluez5: Add GDBusProxy for Bluetooth devices
hfp_hf_bluez5: Register modem for HFP AG capable devices
hfp_hf_bluez5: Keep track of changes of devices Aliases
hfp_hf_bluez5: Handle NewConnection from BlueZ
hfpmodem: Add dynamic hfp_slc_info allocation
hfpmodem: Implement hfp_slc_info_free
hfp_hf_bluez4: Use hfp_slc_info_free()
phonesim: Use hfp_slc_info_free()
hfp_hf_bluez5: Add SLC establishment procedure
drivers/hfpmodem/slc.c | 16 +-
drivers/hfpmodem/slc.h | 3 +-
plugins/bluez5.h | 6 +-
plugins/hfp_hf_bluez4.c | 41 +++--
plugins/hfp_hf_bluez5.c | 421 ++++++++++++++++++++++++++++++++++++++++++++++--
plugins/phonesim.c | 10 +-
6 files changed, 460 insertions(+), 37 deletions(-)
--
1.8.1.1
8 years
[PATCH v0 0/8] HFP HF: Service Level/Codec negotiation
by Claudio Takahasi
Second group of patches related to HFP external profile.
The following patches contain the HFP 1.6 codec negotiation.
Remaining HFP HF patches:
git://git.infradead.org/users/cktakahasi/ofono.git HF-20130117
Claudio Takahasi (3):
hfp_hf: Add NewConnection arguments parsing
hfp_hf: Register the HFP modem
hfp_hf: Add service level negotiation
Vinicius Costa Gomes (5):
hfpmodem: Add version defines for HFP 1.6
hfpmodem: Add support for sending the supported codecs
hfpmodem: Add support for storing the supported codecs
hfpmodem: Send the AT+BAC command with the supported codecs
hfp_hf: Add support for codec negotiation
Makefile.am | 3 +-
drivers/hfpmodem/slc.c | 54 ++++++-
drivers/hfpmodem/slc.h | 13 +-
plugins/bluez5.c | 81 ++++++++++
plugins/bluez5.h | 3 +
plugins/hfp_hf_bluez4.c | 5 +-
plugins/hfp_hf_bluez5.c | 408 +++++++++++++++++++++++++++++++++++++++++++++++-
plugins/media.c | 63 ++++++++
plugins/media.h | 29 ++++
plugins/phonesim.c | 12 +-
10 files changed, 658 insertions(+), 13 deletions(-)
create mode 100644 plugins/media.c
create mode 100644 plugins/media.h
--
1.7.11.7
8 years
[PATCH v1 0/3] HFP driver improvements
by Mikel Astiz
From: Mikel Astiz <mikel.astiz(a)bmw-carit.de>
v1 fixes the comment added in patch v0 2/3, otherwise the rest stays the same.
>From original cover-letter:
While testing the HFP modem driver with several phones, I found out an issue with the Nokia 500, as described in patch v0 3/3.
The first two patches address a somehow unrelated issue regarding how call states should be reported.
Mikel Astiz (3):
hfpmodem: Refactor voicecall notify with foreach
hfpmodem: Avoid transitional voicecall states
hfpmodem: Fix release-and-swap without +CIEV
drivers/hfpmodem/voicecall.c | 72 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 66 insertions(+), 6 deletions(-)
--
1.7.11.7
8 years
[PATCH v0 0/3] HFP driver improvements
by Mikel Astiz
From: Mikel Astiz <mikel.astiz(a)bmw-carit.de>
While testing the HFP modem driver with several phones, I found out an issue with the Nokia 500, as described in patch v0 3/3.
The first two patches address a somehow unrelated issue regarding how call states should be reported.
Mikel Astiz (3):
hfpmodem: Refactor voicecall notify with foreach
hfpmodem: Avoid transitional voicecall states
hfpmodem: Fix release-and-swap without +CIEV
drivers/hfpmodem/voicecall.c | 70 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 64 insertions(+), 6 deletions(-)
--
1.7.11.7
8 years
fix for +CMER parser of AT driver (fixes registration)
by M. Dietrich
Hi All,
i recently noticed that the at driver did not reach the state "registered".
marcel pointer me to the message
+CMER not supported by this modem. If this is an error please submit
patches to support this hardware
and i started digging. problem was parsing of the response
+CMER: (0,3),(0,2),0,(0-1),0
that expresses the allowed options of CMER. neither (a list of) single integer
"(0,3)" (in opposite to range "(0-1)") nor missing brackets "0" were supported
by ofono so i added this (see patch).
i'm not sure if missing brackets are allowed or espress something different,
maybe a AT-guru can tell. for now "(0)" behaves like "0".
i assume that also other response-parsing flows in ofono have that problem
so either a generic aproach should be implemented or other places be reviewed.
marcel already pointer out that a generic aproach may be unnecessarily complex
where i agree if it comes to strings and nested brackets but for plain integer
cases it would be quite useful to get this done in one place for all. if
interested i could implement such stuff into gatchat/gatresult.c which then can
be used for the integer-only cases. what do you think?
regards,
michael
--
M. Dietrich
8 years