aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/lib/bluetooth/hal-bt.c
diff options
context:
space:
mode:
authorJonathan Aillet <jonathan.aillet@iot.bzh>2018-08-24 20:17:12 +0200
committerJonathan Aillet <jonathan.aillet@iot.bzh>2018-10-08 15:56:09 +0200
commit92eb34c496de489f288c0eb59c9d84d6cf31decd (patch)
treec2b4a69c98ad8cb3017ecb824e7e2955586a572d /plugins/lib/bluetooth/hal-bt.c
parentdeb99447f014426cf2aed8263932b38d412bd376 (diff)
Add bluetooth hal plugin
Add first version of a hal plugin that will handle hal that wants bluetooth as an audio device. Change-Id: I4f5628ef9688c417b1b443fc3c4948cb23c17214 Signed-off-by: Jonathan Aillet <jonathan.aillet@iot.bzh>
Diffstat (limited to 'plugins/lib/bluetooth/hal-bt.c')
-rw-r--r--plugins/lib/bluetooth/hal-bt.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/plugins/lib/bluetooth/hal-bt.c b/plugins/lib/bluetooth/hal-bt.c
new file mode 100644
index 0000000..32fbbf7
--- /dev/null
+++ b/plugins/lib/bluetooth/hal-bt.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2018 "IoT.bzh"
+ * Author Jonathan Aillet <jonathan.aillet@iot.bzh>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <wrap-json.h>
+
+#include <ctl-plugin.h>
+
+#include "hal-bt.h"
+#include "hal-bt-cb.h"
+#include "hal-bt-data.h"
+
+// Local (static) Hal manager data structure
+static struct HalBtPluginData localHalBtPluginData;
+
+CTLP_CAPI_REGISTER(HAL_BT_PLUGIN_NAME)
+
+// Call at initialisation time
+CTLP_ONLOAD(plugin, callbacks)
+{
+ AFB_ApiNotice(plugin->api, "Hal-Bt Plugin Register: uid='%s' 'info='%s'", plugin->uid, plugin->info);
+
+ memset(&localHalBtPluginData, '\0', sizeof(localHalBtPluginData));
+
+ AFB_RequireApi(plugin->api, BT_MANAGER_API, 1);
+
+ /* TDB JAI :
+ - Register 'init' plugin function (HAL_BT_PLUGIN_NAME#init) as onload action here (to avoid adding it in json)
+ - Register 'event' plugin function (HAL_BT_PLUGIN_NAME#event) as action for BT_MANAGER_API#BT_MANAGER_DEVICE_UPDATE_EVENT event here (to avoid adding it in json)
+ */
+
+ return 0;
+}
+
+// Call at onload time
+CTLP_CAPI(init, source, argsJ, queryJ)
+{
+ unsigned int err;
+
+ struct json_object *toSendJ, *returnedJ, *returnedBtList = NULL;
+
+ AFB_ApiNotice(source->api, "Initializing HAL-BT plugin");
+
+ // Loading hal BT plugin specific verbs
+ if(afb_dynapi_add_verb(source->api,
+ HAL_BT_GET_STREAMING_STATUS_VERB,
+ "Get Bluetooth streaming status",
+ HalBtGetStreamingStatus,
+ (void *) &localHalBtPluginData,
+ NULL,
+ 0)) {
+ AFB_ApiError(source->api, "%s: error while creating verb for bluetooth plugin : '%s'", __func__, HAL_BT_GET_STREAMING_STATUS_VERB);
+ return -1;
+ }
+
+ if(afb_dynapi_add_verb(source->api,
+ HAL_BT_SET_STREAMING_STATUS_VERB,
+ "Set Bluetooth streaming status",
+ HalBtSetStreamingStatus,
+ (void *) &localHalBtPluginData,
+ NULL,
+ 0)) {
+ AFB_ApiError(source->api, "%s: error while creating verb for bluetooth plugin : '%s'", __func__, HAL_BT_SET_STREAMING_STATUS_VERB);
+ return -2;
+ }
+
+ if(afb_dynapi_add_verb(source->api,
+ HAL_BT_GET_CONNECTED_DEVICES_VERB,
+ "Get connected Bluetooth devices list",
+ HalBtGetConnectedBluetoothDevices,
+ (void *) &localHalBtPluginData,
+ NULL,
+ 0)) {
+ AFB_ApiError(source->api, "%s: error while creating verb for bluetooth plugin : '%s'", __func__, HAL_BT_GET_CONNECTED_DEVICES_VERB);
+ return -3;
+ }
+
+ if(afb_dynapi_add_verb(source->api,
+ HAL_BT_GET_SELECTED_DEVICE_VERB,
+ "Get selected Bluetooth device",
+ HalBtGetSelectedBluetoothDevice,
+ (void *) &localHalBtPluginData,
+ NULL,
+ 0)) {
+ AFB_ApiError(source->api, "%s: error while creating verb for bluetooth plugin : '%s'", __func__, HAL_BT_GET_SELECTED_DEVICE_VERB);
+ return -4;
+ }
+
+ if(afb_dynapi_add_verb(source->api,
+ HAL_BT_SET_SELECTED_DEVICE_VERB,
+ "Set selected Bluetooth device",
+ HalBtSetSelectedBluetoothDevice,
+ (void *) &localHalBtPluginData,
+ NULL,
+ 0)) {
+ AFB_ApiError(source->api, "%s: error while creating verb for bluetooth plugin : '%s'", __func__, HAL_BT_SET_SELECTED_DEVICE_VERB);
+ return -5;
+ }
+
+ // Register to Bluetooth manager
+ wrap_json_pack(&toSendJ, "{s:s}", "value", BT_MANAGER_DEVICE_UPDATE_EVENT);
+ if(AFB_ServiceSync(source->api, BT_MANAGER_API, BT_MANAGER_SUBSCRIBE_VERB, toSendJ, &returnedJ)) {
+ AFB_ApiError(source->api,
+ "Error during call to verb %s of %s api",
+ BT_MANAGER_API,
+ BT_MANAGER_SUBSCRIBE_VERB);
+
+ return -6;
+ }
+ else if(! wrap_json_unpack(returnedJ, "{s:{s:s}}", "request", "info", NULL)) {
+ AFB_ApiError(source->api,
+ "Couldn't subscribe to event '%s' during call to verb '%s' of api '%s'",
+ BT_MANAGER_DEVICE_UPDATE_EVENT,
+ BT_MANAGER_SUBSCRIBE_VERB,
+ BT_MANAGER_API);
+ return -7;
+ }
+
+ if(AFB_ServiceSync(source->api, BT_MANAGER_API, BT_MANAGER_GET_DEVICES_VERB, NULL, &returnedJ)) {
+ AFB_ApiError(source->api,
+ "Error during call to verb %s of %s api",
+ BT_MANAGER_API,
+ BT_MANAGER_GET_DEVICES_VERB);
+
+ return -8;
+ }
+ else if(wrap_json_unpack(returnedJ, "{s:{s:o}}", "response", "list", &returnedBtList)) {
+ AFB_ApiError(source->api,
+ "Couldn't get bluetooth device list during call to verb '%s' of api '%s'",
+ BT_MANAGER_GET_DEVICES_VERB,
+ BT_MANAGER_API);
+ return -9;
+ }
+
+ if((err = HalBtDataHandleReceivedMutlipleBtDeviceData(&localHalBtPluginData, returnedBtList)))
+ return (10 * err);
+
+ if(localHalBtPluginData.selectedBtDevice) {
+ localHalBtPluginData.btStreamEnabled = 1;
+ /* TODO JAI : send selected device to softmixer (and enable stream here for now)
+ * Tell the softmixer that we want it as an input using 'bluealsa:HCI=hci0,DEV=F6:32:15:2A:80:70,PROFILE=a2dp'
+ string as capture associated with an 'uid' using smixer verb 'set-capture'
+ * Enable capture stream to playback using 'uid' used at 'set-capture' call
+ */
+ }
+
+ return 0;
+}
+
+// This receive Hal bluetooth plugin events
+CTLP_CAPI(events, source, argsJ, queryJ)
+{
+ struct HalBtDeviceData *previouslySelectedBtDevice = localHalBtPluginData.selectedBtDevice;
+
+ AFB_ApiNotice(source->api, "JAI: bt event received: %s", json_object_get_string(queryJ));
+
+ if(HalBtDataHandleReceivedSingleBtDeviceData(&localHalBtPluginData, queryJ)) {
+ AFB_ApiError(source->api, "Error while decoding bluetooth event received json (%s)", json_object_get_string(queryJ));
+ return -1;
+ }
+
+ if(localHalBtPluginData.selectedBtDevice && localHalBtPluginData.selectedBtDevice != previouslySelectedBtDevice) {
+ localHalBtPluginData.btStreamEnabled = 1;
+ /* TODO JAI : send selected device to softmixer (and enable stream here for now)
+ * Tell the softmixer that we want it as an input using 'bluealsa:HCI=hci0,DEV=F6:32:15:2A:80:70,PROFILE=a2dp'
+ string as capture associated with an 'uid' using smixer verb 'set-capture'
+ * Enable capture stream to playback using 'uid' used at 'set-capture' call
+ */
+ }
+ else if (! localHalBtPluginData.selectedBtDevice) {
+ localHalBtPluginData.btStreamEnabled = 0;
+ // TODO JAI: Disable capture stream to playback using 'uid' used at 'set-capture' call
+ }
+
+ return 0;
+} \ No newline at end of file