ERROR:Reject SCO: Agent not registered.
by Abhishek Dharmapurikar
Hi,
I was trying to setup HFP uing ofono. I have the following setup
Rasperry Pi B+ ( ARM1176JZF-S)
Bluez 5.32
Pulseaudio 6.0
ofono 1.16
Used the following steps
http://padovan.org/blog/2010/02/handsfree-profile-into-bluez-and-ofono/
start pulseaudio, bluetoothd and ofonod
Connect to phone using bluetoothctl
./enable-modem
./dial-number
loopback
I was able to pair my nexus 4 device and use the script ./dial-number which
actually sets a call up. But the audio of the call doesn't route to the
default sink. I see the following error in ofonod
*Reject SCO: Agent not registered*
Which could be the reason for the audio problem.
Things that I have already tried.
Patched http://cgit.freedesktop.org/~jprvita/pulseaudio/ file
bluetooth-headsets-media-api.
Recompiled the raspbian kernel with
*CONFIG_BT_SCOCONFIG_BT_HCIUSB_SCO*
enabled
Added
*Enable = Source,Sink,Headset,Gateway,Control,MediaDisable = Socket*
to /etc/bluetooth/audio.conf.
Things that could be wrong
When I do a pactl list cards, i see the bluetooth card at #0 with two
profiles.
* Profiles: a2dp_source: High Fidelity Capture (A2DP
Source) (sinks: 0, sources: 1, priority: 10, available: yes)
headset_audio_gateway: Headset Audio Gateway (HSP/HFP) (sinks: 1, sources:
1, priority: 20, available: no) off: Off (sinks: 0, sources:
0, priority: 0, available: yes) Active Profile: a2dp_source*
But when I try making the headset_audio_gateway the default profile. I get
*$ sudo pactl set-card-profile 0 headset_audio_gatewayFailure: Input/Output
error*
Also read this in the pulseaudio notes
http://www.freedesktop.org/wiki/Software/PulseAudio/Notes/6.0/
"When building PulseAudio, it's possible to choose between "native" and
"ofono" BlueZ 5 headset backends."
How do I specify that I wish to use the ofono headset backend? Is that the
problem?
5 years, 1 month
[PATCH 1/2 v4] emulator: add codec negotiation support
by Simon Fels
---
include/emulator.h | 5 ++
src/emulator.c | 259 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 264 insertions(+)
diff --git a/include/emulator.h b/include/emulator.h
index 15dc61c..4b2bc98 100644
--- a/include/emulator.h
+++ b/include/emulator.h
@@ -112,6 +112,11 @@ void ofono_emulator_set_hf_indicator_active(struct ofono_emulator *em,
void ofono_emulator_set_handsfree_card(struct ofono_emulator *em,
struct ofono_handsfree_card *card);
+typedef void (*ofono_emulator_codec_negotiation_cb)(int err, void *data);
+
+int ofono_emulator_start_codec_negotiation(struct ofono_emulator *em,
+ ofono_emulator_codec_negotiation_cb cb, void *data);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/emulator.c b/src/emulator.c
index 626dec3..4c81a39 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -27,6 +27,7 @@
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
+#include <errno.h>
#include <glib.h>
@@ -39,6 +40,15 @@
#define RING_TIMEOUT 3
+#define CVSD_OFFSET 0
+#define MSBC_OFFSET 1
+#define CODECS_COUNT (MSBC_OFFSET + 1)
+
+struct hfp_codec_info {
+ unsigned char type;
+ ofono_bool_t supported;
+};
+
struct ofono_emulator {
struct ofono_atom *atom;
enum ofono_emulator_type type;
@@ -50,6 +60,13 @@ struct ofono_emulator {
guint callsetup_source;
int pns_id;
struct ofono_handsfree_card *card;
+ struct hfp_codec_info r_codecs[CODECS_COUNT];
+ unsigned char selected_codec;
+ unsigned char negotiated_codec;
+ unsigned char proposed_codec;
+ ofono_emulator_codec_negotiation_cb codec_negotiation_cb;
+ void *codec_negotiation_data;
+ ofono_bool_t bac_received;
bool slc : 1;
unsigned int events_mode : 2;
bool events_ind : 1;
@@ -938,6 +955,176 @@ fail:
}
}
+static void finish_codec_negotiation(struct ofono_emulator *em,
+ int err)
+{
+ if (em->codec_negotiation_cb == NULL)
+ return;
+
+ em->codec_negotiation_cb(err, em->codec_negotiation_data);
+
+ em->codec_negotiation_cb = NULL;
+ em->codec_negotiation_data = NULL;
+}
+
+static void bac_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtResultIter iter;
+ int val;
+
+ DBG("");
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_SET:
+ g_at_result_iter_init(&iter, result);
+ g_at_result_iter_next(&iter, "");
+
+ /*
+ * CVSD codec is mandatory and must come first.
+ * See HFP v1.6 4.34.1
+ */
+ if (g_at_result_iter_next_number(&iter, &val) == FALSE ||
+ val != HFP_CODEC_CVSD)
+ goto fail;
+
+ em->bac_received = TRUE;
+
+ em->negotiated_codec = 0;
+ em->r_codecs[CVSD_OFFSET].supported = TRUE;
+
+ while (g_at_result_iter_next_number(&iter, &val)) {
+ switch (val) {
+ case HFP_CODEC_MSBC:
+ em->r_codecs[MSBC_OFFSET].supported = TRUE;
+ break;
+ default:
+ DBG("Unsupported HFP codec %d", val);
+ break;
+ }
+ }
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+
+ /*
+ * If we're currently in the process of selecting a codec
+ * we have to restart that now
+ */
+ if (em->proposed_codec) {
+ em->proposed_codec = 0;
+ ofono_emulator_start_codec_negotiation(em, NULL, NULL);
+ }
+
+ break;
+
+ default:
+fail:
+ DBG("Process AT+BAC failed");
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+
+ finish_codec_negotiation(em, -EIO);
+
+ break;
+ }
+}
+
+static void connect_sco(struct ofono_emulator *em)
+{
+ int err;
+
+ DBG("");
+
+ if (em->card == NULL) {
+ finish_codec_negotiation(em, -EINVAL);
+ return;
+ }
+
+ err = ofono_handsfree_card_connect_sco(em->card);
+ if (err == 0) {
+ finish_codec_negotiation(em, 0);
+ return;
+ }
+
+ /* If we have another codec we can try then lets do that */
+ if (em->negotiated_codec != HFP_CODEC_CVSD) {
+ em->selected_codec = HFP_CODEC_CVSD;
+ ofono_emulator_start_codec_negotiation(em,
+ em->codec_negotiation_cb,
+ em->codec_negotiation_data);
+ return;
+ }
+
+ finish_codec_negotiation(em, -EIO);
+}
+
+static void bcs_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtResultIter iter;
+ int val;
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_SET:
+ g_at_result_iter_init(&iter, result);
+ g_at_result_iter_next(&iter, "");
+
+ if (!g_at_result_iter_next_number(&iter, &val))
+ break;
+
+ if (em->proposed_codec != val) {
+ em->proposed_codec = 0;
+ break;
+ }
+
+ em->proposed_codec = 0;
+ em->negotiated_codec = val;
+
+ DBG("negotiated codec %d", val);
+
+ if (em->card != NULL)
+ ofono_handsfree_card_set_codec(em->card,
+ em->negotiated_codec);
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+
+ connect_sco(em);
+
+ return;
+ default:
+ break;
+ }
+
+ finish_codec_negotiation(em, -EIO);
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void bcc_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+
+ if (!em->negotiated_codec) {
+ ofono_emulator_start_codec_negotiation(em, NULL, NULL);
+ return;
+ }
+
+ connect_sco(em);
+
+ return;
+ default:
+ break;
+ }
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+}
+
static void emulator_add_indicator(struct ofono_emulator *em, const char* name,
int min, int max, int dflt,
gboolean mandatory)
@@ -1047,6 +1234,9 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
g_at_server_register(em->server, "+BIA", bia_cb, em, NULL);
g_at_server_register(em->server, "+BIND", bind_cb, em, NULL);
g_at_server_register(em->server, "+BIEV", biev_cb, em, NULL);
+ g_at_server_register(em->server, "+BAC", bac_cb, em, NULL);
+ g_at_server_register(em->server, "+BCC", bcc_cb, em, NULL);
+ g_at_server_register(em->server, "+BCS", bcs_cb, em, NULL);
}
__ofono_atom_register(em->atom, emulator_unregister);
@@ -1101,6 +1291,7 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_CONTROL;
em->l_features |= HFP_AG_FEATURE_EXTENDED_RES_CODE;
em->l_features |= HFP_AG_FEATURE_HF_INDICATORS;
+ em->l_features |= HFP_AG_FEATURE_CODEC_NEGOTIATION;
em->events_mode = 3; /* default mode is forwarding events */
em->cmee_mode = 0; /* CME ERROR disabled by default */
@@ -1476,3 +1667,71 @@ void ofono_emulator_set_handsfree_card(struct ofono_emulator *em,
em->card = card;
}
+
+static unsigned char select_codec(struct ofono_emulator *em)
+{
+ if (ofono_handsfree_audio_has_wideband() &&
+ em->r_codecs[MSBC_OFFSET].supported)
+ return HFP_CODEC_MSBC;
+
+ /* CVSD is mandatory for both sides */
+ return HFP_CODEC_CVSD;
+}
+
+int ofono_emulator_start_codec_negotiation(struct ofono_emulator *em,
+ ofono_emulator_codec_negotiation_cb cb, void *data)
+{
+ char buf[64];
+ unsigned char codec;
+
+ if (em == NULL)
+ return -EINVAL;
+
+ if (cb != NULL && em->codec_negotiation_cb != NULL)
+ return -EALREADY;
+
+ if (em->proposed_codec > 0)
+ return -EALREADY;
+
+ if (!em->bac_received || em->negotiated_codec > 0) {
+ /*
+ * Report we're done even if we don't have done any
+ * negotiation as the other side may have to clean up.
+ */
+ cb(0, data);
+
+ /*
+ * If we didn't received any +BAC during the SLC setup the
+ * remote side doesn't support codec negotiation and we can
+ * directly connect our card. Otherwise if we got +BAC and
+ * already have a negotiated codec we can proceed here
+ * without doing any negotiation again.
+ */
+ ofono_handsfree_card_connect_sco(em->card);
+
+ return 0;
+ }
+
+ if (em->selected_codec > 0) {
+ codec = em->selected_codec;
+ em->selected_codec = 0;
+ goto done;
+ }
+
+ codec = select_codec(em);
+ if (!codec) {
+ DBG("Failed to select HFP codec");
+ return -EINVAL;
+ }
+
+done:
+ em->proposed_codec = codec;
+
+ em->codec_negotiation_cb = cb;
+ em->codec_negotiation_data = data;
+
+ snprintf(buf, 64, "+BCS: %d", em->proposed_codec);
+ g_at_server_send_unsolicited(em->server, buf);
+
+ return 0;
+}
--
2.5.0
5 years, 4 months
[PATCH 1/2 v3] emulator: add codec negotiation support
by Simon Fels
---
include/emulator.h | 6 ++
src/emulator.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 254 insertions(+)
diff --git a/include/emulator.h b/include/emulator.h
index 15dc61c..36153ef 100644
--- a/include/emulator.h
+++ b/include/emulator.h
@@ -112,6 +112,12 @@ void ofono_emulator_set_hf_indicator_active(struct ofono_emulator *em,
void ofono_emulator_set_handsfree_card(struct ofono_emulator *em,
struct ofono_handsfree_card *card);
+typedef void (*ofono_emulator_codec_negotiation_cb)(int err, void *data);
+
+int ofono_emulator_start_codec_negotiation(struct ofono_emulator *em,
+ unsigned char codec,
+ ofono_emulator_codec_negotiation_cb cb, void *data);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/emulator.c b/src/emulator.c
index 626dec3..e16312e 100644
--- a/src/emulator.c
+++ b/src/emulator.c
@@ -27,6 +27,7 @@
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
+#include <errno.h>
#include <glib.h>
@@ -39,6 +40,15 @@
#define RING_TIMEOUT 3
+#define CVSD_OFFSET 0
+#define MSBC_OFFSET 1
+#define CODECS_COUNT (MSBC_OFFSET + 1)
+
+struct hfp_codec_info {
+ unsigned char type;
+ ofono_bool_t supported;
+};
+
struct ofono_emulator {
struct ofono_atom *atom;
enum ofono_emulator_type type;
@@ -50,6 +60,13 @@ struct ofono_emulator {
guint callsetup_source;
int pns_id;
struct ofono_handsfree_card *card;
+ struct hfp_codec_info r_codecs[CODECS_COUNT];
+ unsigned char negotiated_codec;
+ unsigned char proposed_codec;
+ guint delay_sco;
+ ofono_emulator_codec_negotiation_cb codec_negotiation_cb;
+ void *codec_negotiation_data;
+ ofono_bool_t bac_received;
bool slc : 1;
unsigned int events_mode : 2;
bool events_ind : 1;
@@ -938,6 +955,168 @@ fail:
}
}
+static void bac_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtResultIter iter;
+ int val;
+
+ DBG("");
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_SET:
+ g_at_result_iter_init(&iter, result);
+ g_at_result_iter_next(&iter, "");
+
+ /*
+ * CVSD codec is mandatory and must come first.
+ * See HFP v1.6 4.34.1
+ */
+ if (g_at_result_iter_next_number(&iter, &val) == FALSE ||
+ val != HFP_CODEC_CVSD)
+ goto fail;
+
+ em->bac_received = TRUE;
+
+ em->negotiated_codec = 0;
+ em->r_codecs[CVSD_OFFSET].supported = TRUE;
+
+ while (g_at_result_iter_next_number(&iter, &val)) {
+ switch (val) {
+ case HFP_CODEC_MSBC:
+ em->r_codecs[MSBC_OFFSET].supported = TRUE;
+ break;
+ default:
+ DBG("Unsupported HFP codec %d", val);
+ break;
+ }
+ }
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+
+ /*
+ * If we're currently in the process of selecting a codec
+ * we have to restart that now
+ */
+ if (em->proposed_codec)
+ ofono_emulator_start_codec_negotiation(em, 0, NULL, NULL);
+
+ break;
+
+ default:
+fail:
+ DBG("Process AT+BAC failed");
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+ break;
+ }
+}
+
+static void finish_codec_negotiation(struct ofono_emulator *em,
+ int err)
+{
+ if (em->codec_negotiation_cb == NULL)
+ return;
+
+ em->codec_negotiation_cb(err, em->codec_negotiation_data);
+
+ em->codec_negotiation_cb = NULL;
+ em->codec_negotiation_data = NULL;
+}
+
+static void connect_sco(struct ofono_emulator *em)
+{
+ int err;
+
+ DBG("");
+
+ em->delay_sco = 0;
+
+ err = ofono_handsfree_card_connect_sco(em->card);
+ if (err == 0) {
+ finish_codec_negotiation(em, 0);
+ return;
+ }
+
+ /* If we have another codec we can try then lets do that */
+ if (em->negotiated_codec != HFP_CODEC_CVSD) {
+ ofono_emulator_start_codec_negotiation(em, HFP_CODEC_CVSD,
+ em->codec_negotiation_cb,
+ em->codec_negotiation_data);
+ return;
+ }
+
+ finish_codec_negotiation(em, -EIO);
+}
+
+static void bcs_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+ GAtResultIter iter;
+ int val;
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_SET:
+ g_at_result_iter_init(&iter, result);
+ g_at_result_iter_next(&iter, "");
+
+ if (!g_at_result_iter_next_number(&iter, &val))
+ break;
+
+ if (em->proposed_codec != val) {
+ em->proposed_codec = 0;
+ break;
+ }
+
+ em->proposed_codec = 0;
+ em->negotiated_codec = val;
+
+ DBG("negotiated codec %d", val);
+
+ if (em->card != NULL)
+ ofono_handsfree_card_set_codec(em->card,
+ em->negotiated_codec);
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+
+ connect_sco(em);
+
+ return;
+ default:
+ break;
+ }
+
+ finish_codec_negotiation(em, -EIO);
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+}
+
+static void bcc_cb(GAtServer *server, GAtServerRequestType type,
+ GAtResult *result, gpointer user_data)
+{
+ struct ofono_emulator *em = user_data;
+
+ switch (type) {
+ case G_AT_SERVER_REQUEST_TYPE_COMMAND_ONLY:
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_OK);
+
+ if (!em->negotiated_codec) {
+ ofono_emulator_start_codec_negotiation(em, 0, NULL, NULL);
+ return;
+ }
+
+ connect_sco(em);
+
+ return;
+ default:
+ break;
+ }
+
+ g_at_server_send_final(server, G_AT_SERVER_RESULT_ERROR);
+}
+
static void emulator_add_indicator(struct ofono_emulator *em, const char* name,
int min, int max, int dflt,
gboolean mandatory)
@@ -1047,6 +1226,9 @@ void ofono_emulator_register(struct ofono_emulator *em, int fd)
g_at_server_register(em->server, "+BIA", bia_cb, em, NULL);
g_at_server_register(em->server, "+BIND", bind_cb, em, NULL);
g_at_server_register(em->server, "+BIEV", biev_cb, em, NULL);
+ g_at_server_register(em->server, "+BAC", bac_cb, em, NULL);
+ g_at_server_register(em->server, "+BCC", bcc_cb, em, NULL);
+ g_at_server_register(em->server, "+BCS", bcs_cb, em, NULL);
}
__ofono_atom_register(em->atom, emulator_unregister);
@@ -1101,6 +1283,7 @@ struct ofono_emulator *ofono_emulator_create(struct ofono_modem *modem,
em->l_features |= HFP_AG_FEATURE_ENHANCED_CALL_CONTROL;
em->l_features |= HFP_AG_FEATURE_EXTENDED_RES_CODE;
em->l_features |= HFP_AG_FEATURE_HF_INDICATORS;
+ em->l_features |= HFP_AG_FEATURE_CODEC_NEGOTIATION;
em->events_mode = 3; /* default mode is forwarding events */
em->cmee_mode = 0; /* CME ERROR disabled by default */
@@ -1476,3 +1659,68 @@ void ofono_emulator_set_handsfree_card(struct ofono_emulator *em,
em->card = card;
}
+
+static unsigned char select_codec(struct ofono_emulator *em)
+{
+ if (ofono_handsfree_audio_has_wideband() &&
+ em->r_codecs[MSBC_OFFSET].supported)
+ return HFP_CODEC_MSBC;
+
+ /* CVSD is mandatory for both sides */
+ return HFP_CODEC_CVSD;
+}
+
+int ofono_emulator_start_codec_negotiation(struct ofono_emulator *em,
+ unsigned char codec,
+ ofono_emulator_codec_negotiation_cb cb, void *data)
+{
+ char buf[64];
+ unsigned char selected_codec;
+
+ if (em == NULL)
+ return -EINVAL;
+
+ if (cb != NULL && em->codec_negotiation_cb != NULL)
+ return -EALREADY;
+
+ if (!em->bac_received || em->negotiated_codec > 0) {
+ /*
+ * Report we're done even if we don't have done any
+ * negotiation as the other side may have to clean up.
+ */
+ cb(0, data);
+
+ /*
+ * If we didn't received any +BAC during the SLC setup the
+ * remote side doesn't support codec negotiation and we can
+ * directly connect our card. Otherwise if we got +BAC and
+ * already have a negotiated codec we can proceed here
+ * without doing any negotiation again.
+ */
+ ofono_handsfree_card_connect_sco(em->card);
+
+ return 0;
+ }
+
+ if (codec > 0) {
+ selected_codec = codec;
+ goto done;
+ }
+
+ selected_codec = select_codec(em);
+ if (!selected_codec) {
+ DBG("Failed to selected HFP codec");
+ return -EINVAL;
+ }
+
+done:
+ em->proposed_codec = selected_codec;
+
+ em->codec_negotiation_cb = cb;
+ em->codec_negotiation_data = data;
+
+ snprintf(buf, 64, "+BCS: %d", selected_codec);
+ g_at_server_send_unsolicited(em->server, buf);
+
+ return 0;
+}
--
2.5.0
5 years, 4 months
[PATCH 00/10] Re-factoring of gril and rilmodem
by Alfonso Sanchez-Beato
The attached patches include:
* Moving parcel processing code to the rilmodem driver
* Unit tests for parcel processing
* Removing of assertions
The unit tests illustrate one of the reasons for creating separate
modules for building/parsing parcels.
Alfonso Sanchez-Beato (10):
gril: Move parcel processing to rilmodem
gril: Adapt to movement of parcel processing
rilmodem: Adapt to movement of parcel processing
ril: Adapt to movement of parcel processing
gril: Remove asserts
rilmodem: Remove asserts
ril: Remove asserts
unit: Add unit tests for ril parcel processing
build: Add rilmodem unit tests
gitignore: Ignore rilmodem unit tests
.gitignore | 3 +
Makefile.am | 43 +-
drivers/rilmodem/call-barring.c | 4 +-
drivers/rilmodem/call-forwarding.c | 6 +-
drivers/rilmodem/call-settings.c | 4 +-
drivers/rilmodem/call-volume.c | 4 +-
drivers/rilmodem/devinfo.c | 2 +-
drivers/rilmodem/gprs-context.c | 9 +-
drivers/rilmodem/gprs.c | 6 +-
drivers/rilmodem/network-registration.c | 6 +-
drivers/rilmodem/radio-settings.c | 4 +-
{gril => drivers/rilmodem}/ril_constants.h | 0
gril/grilreply.c => drivers/rilmodem/rilreply.c | 5 +-
gril/grilreply.h => drivers/rilmodem/rilreply.h | 1 +
.../grilrequest.c => drivers/rilmodem/rilrequest.c | 3 +-
.../grilrequest.h => drivers/rilmodem/rilrequest.h | 1 +
gril/grilunsol.c => drivers/rilmodem/rilunsol.c | 3 +-
gril/grilunsol.h => drivers/rilmodem/rilunsol.h | 1 +
drivers/rilmodem/rilutil.c | 623 ++++++
drivers/rilmodem/rilutil.h | 14 +
drivers/rilmodem/sim.c | 6 +-
drivers/rilmodem/sms.c | 6 +-
drivers/rilmodem/ussd.c | 4 +-
drivers/rilmodem/voicecall.c | 6 +-
gril/gril.c | 47 +-
gril/gril.h | 1 -
gril/grilio.c | 3 +-
gril/grilio.h | 2 +
gril/grilutil.c | 628 ------
gril/grilutil.h | 15 -
plugins/ril.c | 16 +-
unit/test-rilreply.c | 2141 ++++++++++++++++++++
unit/test-rilrequest.c | 1737 ++++++++++++++++
unit/test-rilunsol.c | 698 +++++++
34 files changed, 5331 insertions(+), 721 deletions(-)
rename {gril => drivers/rilmodem}/ril_constants.h (100%)
rename gril/grilreply.c => drivers/rilmodem/rilreply.c (99%)
rename gril/grilreply.h => drivers/rilmodem/rilreply.h (99%)
rename gril/grilrequest.c => drivers/rilmodem/rilrequest.c (99%)
rename gril/grilrequest.h => drivers/rilmodem/rilrequest.h (99%)
rename gril/grilunsol.c => drivers/rilmodem/rilunsol.c (99%)
rename gril/grilunsol.h => drivers/rilmodem/rilunsol.h (98%)
create mode 100644 unit/test-rilreply.c
create mode 100644 unit/test-rilrequest.c
create mode 100644 unit/test-rilunsol.c
--
2.1.4
5 years, 4 months
[PATCH 1/3 v2] hfp_ag_bluez5: Add initial handsfree audio driver
by Simon Fels
---
plugins/hfp_ag_bluez5.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 52 insertions(+), 3 deletions(-)
diff --git a/plugins/hfp_ag_bluez5.c b/plugins/hfp_ag_bluez5.c
index ef8a048..3aca792 100644
--- a/plugins/hfp_ag_bluez5.c
+++ b/plugins/hfp_ag_bluez5.c
@@ -49,11 +49,47 @@
#define HFP_AG_EXT_PROFILE_PATH "/bluetooth/profile/hfp_ag"
#define BT_ADDR_SIZE 18
+#define HFP_AG_DRIVER "hfp-ag-driver"
+
static guint modemwatch_id;
static GList *modems;
static GHashTable *sim_hash = NULL;
static GHashTable *connection_hash;
+static int hfp_card_probe(struct ofono_handsfree_card *card,
+ unsigned int vendor, void *data)
+{
+ DBG("");
+
+ return 0;
+}
+
+static void hfp_card_remove(struct ofono_handsfree_card *card)
+{
+ DBG("");
+}
+
+static void hfp_card_connect(struct ofono_handsfree_card *card,
+ ofono_handsfree_card_connect_cb_t cb,
+ void *data)
+{
+ DBG("");
+ ofono_handsfree_card_connect_sco(card);
+}
+
+static void hfp_sco_connected_hint(struct ofono_handsfree_card *card)
+{
+ DBG("");
+}
+
+static struct ofono_handsfree_card_driver hfp_ag_driver = {
+ .name = HFP_AG_DRIVER,
+ .probe = hfp_card_probe,
+ .remove = hfp_card_remove,
+ .connect = hfp_card_connect,
+ .sco_connected_hint = hfp_sco_connected_hint,
+};
+
static void connection_destroy(gpointer data)
{
int fd = GPOINTER_TO_INT(data);
@@ -104,12 +140,15 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
goto invalid;
dbus_message_iter_get_basic(&entry, &fd);
- dbus_message_iter_next(&entry);
if (fd < 0)
goto invalid;
- DBG("%s", device);
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_ARRAY) {
+ close(fd);
+ goto invalid;
+ }
/* Pick the first voicecall capable modem */
if (modems == NULL) {
@@ -167,7 +206,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
card = ofono_handsfree_card_create(0,
OFONO_HANDSFREE_CARD_TYPE_GATEWAY,
- NULL, NULL);
+ HFP_AG_DRIVER, em);
ofono_handsfree_card_set_local(card, local);
ofono_handsfree_card_set_remote(card, remote);
@@ -369,6 +408,7 @@ static void call_modemwatch(struct ofono_modem *modem, void *user)
static int hfp_ag_init(void)
{
DBusConnection *conn = ofono_dbus_get_connection();
+ int err;
if (DBUS_TYPE_UNIX_FD < 0)
return -EBADF;
@@ -383,6 +423,13 @@ static int hfp_ag_init(void)
return -EIO;
}
+ err = ofono_handsfree_card_driver_register(&hfp_ag_driver);
+ if (err < 0) {
+ g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
+ BLUEZ_PROFILE_INTERFACE);
+ return err;
+ }
+
sim_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
modemwatch_id = __ofono_modemwatch_add(modem_watch, NULL, NULL);
@@ -404,6 +451,8 @@ static void hfp_ag_exit(void)
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE);
+ ofono_handsfree_card_driver_unregister(&hfp_ag_driver);
+
g_hash_table_destroy(connection_hash);
g_list_free(modems);
--
2.5.0
5 years, 4 months
[PATCH] rildev: Do not create modems if no env var set
by Alfonso Sanchez-Beato
Do not create rilmodem instances if the environment variable
OFONO_RIL_DEVICE is not set.
---
plugins/rildev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/rildev.c b/plugins/rildev.c
index 461324d..f4cea6f 100644
--- a/plugins/rildev.c
+++ b/plugins/rildev.c
@@ -93,7 +93,7 @@ static int detect_init(void)
ril_type = getenv("OFONO_RIL_DEVICE");
if (ril_type == NULL)
- ril_type = "ril";
+ return 0;
/* Check for multi-SIM support */
multi_sim = getenv("OFONO_RIL_NUM_SIM_SLOTS");
--
2.1.4
5 years, 4 months
[PATCH 0/9] Rilmodem driver
by Alfonso Sanchez-Beato
This patch series implements the rilmodem driver, which uses Android's
radio interface layer (RIL, part of the Android HAL) to interact with
the modem.
The driver is almost feature-complete with some exceptions, being CBS
and SAT the most prominent.
Besides the driver, the patches include the following plugins:
* ril.c: Plugin for Android modems
* infineon.c: Plugin for infineon modems, which are a variant of the ril
modem
* rildev: plugin that creates ril-type modems using environment
variables
Finally, the patches contain some minor modifications of the core code
to export a couple of enumerations used by the driver.
The driver is used by Ubuntu for Phones and Sailfish and is quite stable
at the moment.
Alfonso Sanchez-Beato (5):
include: Add definitions for phone number types
infineon: Definitions for infineon modem
infineon: Plugin for infineon modems
rildev: plugin that creates ril-type modems
build: Add rilmodem to the build
Tony Espy (4):
src: make bearer/operator enums public
gril: Library to communicate with rild
rilmodem: driver for Android modems
ril: Plugin for Android modems
Makefile.am | 44 +-
configure.ac | 5 +
drivers/infineonmodem/infineon_constants.h | 77 ++
drivers/rilmodem/call-barring.c | 245 +++++
drivers/rilmodem/call-forwarding.c | 327 +++++++
drivers/rilmodem/call-settings.c | 286 ++++++
drivers/rilmodem/call-volume.c | 182 ++++
drivers/rilmodem/devinfo.c | 218 +++++
drivers/rilmodem/gprs-context.c | 585 +++++++++++
drivers/rilmodem/gprs.c | 487 ++++++++++
drivers/rilmodem/gprs.h | 46 +
drivers/rilmodem/network-registration.c | 566 +++++++++++
drivers/rilmodem/phonebook.c | 1055 ++++++++++++++++++++
drivers/rilmodem/radio-settings.c | 300 ++++++
drivers/rilmodem/radio-settings.h | 47 +
drivers/rilmodem/rilmodem.c | 78 ++
drivers/rilmodem/rilmodem.h | 71 ++
drivers/rilmodem/rilutil.c | 194 ++++
drivers/rilmodem/rilutil.h | 165 ++++
drivers/rilmodem/sim.c | 1200 +++++++++++++++++++++++
drivers/rilmodem/sms.c | 315 ++++++
drivers/rilmodem/ussd.c | 264 +++++
drivers/rilmodem/vendor.h | 32 +
drivers/rilmodem/voicecall.c | 824 ++++++++++++++++
drivers/rilmodem/voicecall.h | 71 ++
gril/gfunc.h | 42 +
gril/gril.c | 1295 +++++++++++++++++++++++++
gril/gril.h | 172 ++++
gril/grilio.c | 399 ++++++++
gril/grilio.h | 69 ++
gril/grilreply.c | 1450 ++++++++++++++++++++++++++++
gril/grilreply.h | 185 ++++
gril/grilrequest.c | 1161 ++++++++++++++++++++++
gril/grilrequest.h | 293 ++++++
gril/grilunsol.c | 638 ++++++++++++
gril/grilunsol.h | 99 ++
gril/grilutil.c | 830 ++++++++++++++++
gril/grilutil.h | 63 ++
gril/parcel.c | 293 ++++++
gril/parcel.h | 53 +
gril/ril_constants.h | 429 ++++++++
include/types.h | 6 +
plugins/infineon.c | 77 ++
plugins/ril.c | 461 +++++++++
plugins/ril.h | 30 +
plugins/rildev.c | 133 +++
src/common.h | 20 +
src/gprs.c | 12 -
src/network.c | 8 -
49 files changed, 15881 insertions(+), 21 deletions(-)
create mode 100644 drivers/infineonmodem/infineon_constants.h
create mode 100644 drivers/rilmodem/call-barring.c
create mode 100644 drivers/rilmodem/call-forwarding.c
create mode 100644 drivers/rilmodem/call-settings.c
create mode 100644 drivers/rilmodem/call-volume.c
create mode 100644 drivers/rilmodem/devinfo.c
create mode 100644 drivers/rilmodem/gprs-context.c
create mode 100644 drivers/rilmodem/gprs.c
create mode 100644 drivers/rilmodem/gprs.h
create mode 100644 drivers/rilmodem/network-registration.c
create mode 100644 drivers/rilmodem/phonebook.c
create mode 100644 drivers/rilmodem/radio-settings.c
create mode 100644 drivers/rilmodem/radio-settings.h
create mode 100644 drivers/rilmodem/rilmodem.c
create mode 100644 drivers/rilmodem/rilmodem.h
create mode 100644 drivers/rilmodem/rilutil.c
create mode 100644 drivers/rilmodem/rilutil.h
create mode 100644 drivers/rilmodem/sim.c
create mode 100644 drivers/rilmodem/sms.c
create mode 100644 drivers/rilmodem/ussd.c
create mode 100644 drivers/rilmodem/vendor.h
create mode 100644 drivers/rilmodem/voicecall.c
create mode 100644 drivers/rilmodem/voicecall.h
create mode 100644 gril/gfunc.h
create mode 100644 gril/gril.c
create mode 100644 gril/gril.h
create mode 100644 gril/grilio.c
create mode 100644 gril/grilio.h
create mode 100644 gril/grilreply.c
create mode 100644 gril/grilreply.h
create mode 100644 gril/grilrequest.c
create mode 100644 gril/grilrequest.h
create mode 100644 gril/grilunsol.c
create mode 100644 gril/grilunsol.h
create mode 100644 gril/grilutil.c
create mode 100644 gril/grilutil.h
create mode 100644 gril/parcel.c
create mode 100644 gril/parcel.h
create mode 100644 gril/ril_constants.h
create mode 100644 plugins/infineon.c
create mode 100644 plugins/ril.c
create mode 100644 plugins/ril.h
create mode 100644 plugins/rildev.c
--
2.1.4
5 years, 4 months
[PATCH 1/2] hfp_ag_bluez5: Add initial handsfree audio driver
by Simon Fels
---
plugins/hfp_ag_bluez5.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 101 insertions(+), 4 deletions(-)
diff --git a/plugins/hfp_ag_bluez5.c b/plugins/hfp_ag_bluez5.c
index ef8a048..a80875f 100644
--- a/plugins/hfp_ag_bluez5.c
+++ b/plugins/hfp_ag_bluez5.c
@@ -49,11 +49,42 @@
#define HFP_AG_EXT_PROFILE_PATH "/bluetooth/profile/hfp_ag"
#define BT_ADDR_SIZE 18
+#define HFP16_AG_DRIVER "hfp16-ag-driver"
+
static guint modemwatch_id;
static GList *modems;
static GHashTable *sim_hash = NULL;
static GHashTable *connection_hash;
+static int hfp16_card_probe(struct ofono_handsfree_card *card,
+ unsigned int vendor, void *data)
+{
+ return 0;
+}
+
+static void hfp16_card_remove(struct ofono_handsfree_card *card)
+{
+}
+
+static void hfp16_card_connect(struct ofono_handsfree_card *card,
+ ofono_handsfree_card_connect_cb_t cb,
+ void *data)
+{
+ ofono_handsfree_card_connect_sco(card);
+}
+
+static void hfp16_sco_connected_hint(struct ofono_handsfree_card *card)
+{
+}
+
+static struct ofono_handsfree_card_driver hfp16_ag_driver = {
+ .name = HFP16_AG_DRIVER,
+ .probe = hfp16_card_probe,
+ .remove = hfp16_card_remove,
+ .connect = hfp16_card_connect,
+ .sco_connected_hint = hfp16_sco_connected_hint,
+};
+
static void connection_destroy(gpointer data)
{
int fd = GPOINTER_TO_INT(data);
@@ -74,11 +105,51 @@ static gboolean io_hup_cb(GIOChannel *io, GIOCondition cond, gpointer data)
return FALSE;
}
+static int get_version(DBusMessageIter *iter, uint16_t *version)
+{
+ DBusMessageIter dict, entry, valiter;
+ const char *key;
+ uint16_t value;
+
+ /* Points to dict */
+ dbus_message_iter_recurse(iter, &dict);
+
+ /* For each entry in this dict */
+ while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
+ /* I want to access the entry's contents */
+ dbus_message_iter_recurse(&dict, &entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ /* If the current key isn't "Version", keep looking */
+ dbus_message_iter_get_basic(&entry, &key);
+ if (!g_str_equal("Version", key)) {
+ dbus_message_iter_next(&dict);
+ continue;
+ }
+
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(&entry, &valiter);
+ dbus_message_iter_get_basic(&valiter, &value);
+
+ if (version)
+ *version = value;
+
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
static DBusMessage *profile_new_connection(DBusConnection *conn,
DBusMessage *msg, void *data)
{
DBusMessageIter entry;
- const char *device;
+ const char *device, *driver;
GIOChannel *io;
int fd, fd_dup;
struct sockaddr_rc saddr;
@@ -87,6 +158,7 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
struct ofono_modem *modem;
char local[BT_ADDR_SIZE], remote[BT_ADDR_SIZE];
struct ofono_handsfree_card *card;
+ uint16_t version = HFP_VERSION_1_5;
int err;
DBG("Profile handler NewConnection");
@@ -104,12 +176,22 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
goto invalid;
dbus_message_iter_get_basic(&entry, &fd);
- dbus_message_iter_next(&entry);
if (fd < 0)
goto invalid;
- DBG("%s", device);
+ dbus_message_iter_next(&entry);
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_ARRAY) {
+ close(fd);
+ goto invalid;
+ }
+
+ if (get_version(&entry, &version) < 0) {
+ close(fd);
+ goto invalid;
+ }
+
+ DBG("version: %hd", version);
/* Pick the first voicecall capable modem */
if (modems == NULL) {
@@ -165,9 +247,14 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
g_strdup(device), g_free);
g_io_channel_unref(io);
+ driver = NULL;
+
+ if (version >= HFP_VERSION_1_6)
+ driver = HFP16_AG_DRIVER;
+
card = ofono_handsfree_card_create(0,
OFONO_HANDSFREE_CARD_TYPE_GATEWAY,
- NULL, NULL);
+ driver, NULL);
ofono_handsfree_card_set_local(card, local);
ofono_handsfree_card_set_remote(card, remote);
@@ -369,6 +456,7 @@ static void call_modemwatch(struct ofono_modem *modem, void *user)
static int hfp_ag_init(void)
{
DBusConnection *conn = ofono_dbus_get_connection();
+ int err;
if (DBUS_TYPE_UNIX_FD < 0)
return -EBADF;
@@ -383,6 +471,13 @@ static int hfp_ag_init(void)
return -EIO;
}
+ err = ofono_handsfree_card_driver_register(&hfp16_ag_driver);
+ if (err < 0) {
+ g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
+ BLUEZ_PROFILE_INTERFACE);
+ return err;
+ }
+
sim_hash = g_hash_table_new(g_direct_hash, g_direct_equal);
modemwatch_id = __ofono_modemwatch_add(modem_watch, NULL, NULL);
@@ -404,6 +499,8 @@ static void hfp_ag_exit(void)
g_dbus_unregister_interface(conn, HFP_AG_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE);
+ ofono_handsfree_card_driver_unregister(&hfp16_ag_driver);
+
g_hash_table_destroy(connection_hash);
g_list_free(modems);
--
2.5.0
5 years, 4 months
HandsfreeAudioCard registration for HFP AG plugin
by Simon Fels
Hey everybody,
after some more detailed discussion with Denis yesterday on IRC I've
reworked the previously sent patches a bit and included two patches
Denis worked on before but never submitted yet. With this the audio
card is only registered if we have a service level connection
successfully established.
What is missing currently is codec negotiation between AG and HF but
I already started to implement this and will send further patches
with support for this soon.
regards,
Simon
5 years, 4 months
[PATCH 1/2 v2] handsfree-audio: add type for our audio cards
by Simon Fels
When registering audio cards for the handsfree and gateway roles we
need a way for our users to differentiate between both to decide which
of them they start using for their purpose.
---
doc/handsfree-audio-api.txt | 4 ++++
include/handsfree-audio.h | 10 ++++++++--
plugins/hfp_hf_bluez5.c | 4 +++-
src/handsfree-audio.c | 24 ++++++++++++++++++++++--
4 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/doc/handsfree-audio-api.txt b/doc/handsfree-audio-api.txt
index 89b5aab..d82035c 100644
--- a/doc/handsfree-audio-api.txt
+++ b/doc/handsfree-audio-api.txt
@@ -89,6 +89,10 @@ Properties string RemoteAddress [readonly]
Bluetooth address of the local adapter.
+ string Type [readonly]
+
+ Type of the card. Valid values are "gateway" or
+ "handsfree".
Handsfree Audio Agent hierarchy [experimental]
===============================
diff --git a/include/handsfree-audio.h b/include/handsfree-audio.h
index bfb8480..0e37dae 100644
--- a/include/handsfree-audio.h
+++ b/include/handsfree-audio.h
@@ -30,6 +30,11 @@ extern "C" {
struct ofono_handsfree_card;
+enum ofono_handsfree_card_type {
+ OFONO_HANDSFREE_CARD_TYPE_HANDSFREE,
+ OFONO_HANDSFREE_CARD_TYPE_GATEWAY,
+};
+
typedef void (*ofono_handsfree_card_connect_cb_t)(
const struct ofono_error *error, void *data);
@@ -45,8 +50,9 @@ struct ofono_handsfree_card_driver {
};
struct ofono_handsfree_card *ofono_handsfree_card_create(unsigned int vendor,
- const char *driver,
- void *data);
+ enum ofono_handsfree_card_type type,
+ const char *driver,
+ void *data);
int ofono_handsfree_card_register(struct ofono_handsfree_card *card);
void ofono_handsfree_card_remove(struct ofono_handsfree_card *card);
ofono_bool_t ofono_handsfree_card_set_codec(struct ofono_handsfree_card *card,
diff --git a/plugins/hfp_hf_bluez5.c b/plugins/hfp_hf_bluez5.c
index 713c789..6ae98b3 100644
--- a/plugins/hfp_hf_bluez5.c
+++ b/plugins/hfp_hf_bluez5.c
@@ -589,7 +589,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn,
if (version >= HFP_VERSION_1_6)
driver = HFP16_HF_DRIVER;
- hfp->card = ofono_handsfree_card_create(0, driver, hfp);
+ hfp->card = ofono_handsfree_card_create(0,
+ OFONO_HANDSFREE_CARD_TYPE_HANDSFREE,
+ driver, hfp);
ofono_handsfree_card_set_data(hfp->card, hfp);
ofono_handsfree_card_set_local(hfp->card, local);
diff --git a/src/handsfree-audio.c b/src/handsfree-audio.c
index c990cc3..8db99e1 100644
--- a/src/handsfree-audio.c
+++ b/src/handsfree-audio.c
@@ -45,6 +45,7 @@
#define HFP_AUDIO_CARD_INTERFACE OFONO_SERVICE ".HandsfreeAudioCard"
struct ofono_handsfree_card {
+ enum ofono_handsfree_card_type type;
char *remote;
char *local;
char *path;
@@ -69,6 +70,17 @@ static ofono_bool_t has_wideband = FALSE;
static int defer_setup = 1;
static ofono_bool_t transparent_sco = FALSE;
+static const char *card_type_to_string(enum ofono_handsfree_card_type type)
+{
+ switch (type) {
+ case OFONO_HANDSFREE_CARD_TYPE_HANDSFREE:
+ return "handsfree";
+ case OFONO_HANDSFREE_CARD_TYPE_GATEWAY:
+ return "gateway";
+ }
+ return "";
+}
+
static uint16_t codec2setting(uint8_t codec)
{
switch (codec) {
@@ -255,6 +267,12 @@ static int sco_init(void)
static void card_append_properties(struct ofono_handsfree_card *card,
DBusMessageIter *dict)
{
+ const char *type;
+
+ type = card_type_to_string(card->type);
+ ofono_dbus_dict_append(dict, "Type",
+ DBUS_TYPE_STRING, &type);
+
ofono_dbus_dict_append(dict, "RemoteAddress",
DBUS_TYPE_STRING, &card->remote);
@@ -395,14 +413,16 @@ static const GDBusSignalTable card_signals[] = {
};
struct ofono_handsfree_card *ofono_handsfree_card_create(unsigned int vendor,
- const char *driver,
- void *data)
+ enum ofono_handsfree_card_type type,
+ const char *driver,
+ void *data)
{
struct ofono_handsfree_card *card;
GSList *l;
card = g_new0(struct ofono_handsfree_card, 1);
+ card->type = type;
card->selected_codec = HFP_CODEC_CVSD;
card_list = g_slist_prepend(card_list, card);
--
2.5.0
5 years, 4 months