From e815fdaec657810c9ee8f33dc943dd5e9b7dab5f Mon Sep 17 00:00:00 2001 From: Matt Ranostay Date: Mon, 3 Dec 2018 02:43:10 -0800 Subject: plugins: hal-bt: update to new bluetooth binding API Switch to using media events to detect audio sink transport states for connected devices. Bug-AGL: SPEC-1986 Change-Id: I834d5387ccd76d5ec0946f56536840736a7d96e0 Signed-off-by: Matt Ranostay --- plugins/lib/bluetooth/hal-bt-data.c | 89 ++++++++++++++++++++++++++++--------- plugins/lib/bluetooth/hal-bt-data.h | 3 +- plugins/lib/bluetooth/hal-bt.c | 44 +++++++----------- plugins/lib/bluetooth/hal-bt.h | 8 ++-- 4 files changed, 90 insertions(+), 54 deletions(-) (limited to 'plugins') diff --git a/plugins/lib/bluetooth/hal-bt-data.c b/plugins/lib/bluetooth/hal-bt-data.c index f3cb0e4..6a70495 100644 --- a/plugins/lib/bluetooth/hal-bt-data.c +++ b/plugins/lib/bluetooth/hal-bt-data.c @@ -23,6 +23,7 @@ #include +#include "hal-bt.h" #include "hal-bt-data.h" /******************************************************************************* @@ -96,9 +97,9 @@ struct HalBtDeviceData *HalBtDataAddBtDeviceToBtDeviceList(struct HalBtDeviceDat if(wrap_json_unpack(currentSingleBtDeviceDataJ, "{s:s s:s s:s}", - "Name", ¤tBtDeviceName, - "Address", ¤tBtDeviceAddress, - "Path", ¤tBtDevicePath)) { + "name", ¤tBtDeviceName, + "address", ¤tBtDeviceAddress, + "adapter", ¤tBtDevicePath)) { HalBtDataRemoveSelectedBtDeviceFromList(firstBtDeviceData, currentBtDeviceData); return NULL; } @@ -168,14 +169,59 @@ struct HalBtDeviceData *HalBtDataSearchBtDeviceByAddress(struct HalBtDeviceData return NULL; } -int HalBtDataHandleReceivedSingleBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentSingleBtDeviceDataJ) +int HalBtDataHandleReceivedMediaBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentSingleBtMediaDataJ) { - int btProfilesCount; + const char *currentBtType = NULL, *currentBtAction = NULL; + + AFB_ApiT api = halBtPluginData->currentHalApiHandle; + json_object *returnedJ, *returnedBtList = NULL; + int err = 0; + + wrap_json_unpack(currentSingleBtMediaDataJ, "{s:s}", "type", ¤tBtType); + + if(currentBtType && strcmp(currentBtType, "transport")) + return 0; + + wrap_json_unpack(currentSingleBtMediaDataJ, "{s:s}", "action", ¤tBtAction); + + if(currentBtAction && strcmp(currentBtAction, "added") && strcmp(currentBtAction, "removed")) + return 0; + + // UGLY HACK: This should be actually detecting if a device is disconnected + // SPEC-2010 has been created to track the removal of this. + usleep(1000 * 100); + + if(AFB_ServiceSync(api, BT_MANAGER_API, BT_MANAGER_GET_DEVICES_VERB, NULL, &returnedJ)) { + AFB_ApiError(api, "Error during call to verb '%s' of '%s' api (%s)", + BT_MANAGER_GET_DEVICES_VERB, + BT_MANAGER_API, + json_object_get_string(returnedJ)); + return -1; + } + else if(wrap_json_unpack(returnedJ, "{s:{s:o}}", "response", "devices", &returnedBtList)) { + AFB_ApiError(api, + "Couldn't get bluetooth device list during call to verb '%s' of api '%s'", + BT_MANAGER_GET_DEVICES_VERB, + BT_MANAGER_API); + json_object_put(returnedJ); + return -1; + } - unsigned int idx = 0, currentBtDeviceIsConnected, currentBtDeviceIsA2DP; + if((returnedBtList) && (err = HalBtDataHandleReceivedMutlipleBtDeviceData(halBtPluginData, returnedBtList))) + err = 10 * err; - char *currentBtDeviceAddress, *currentBtDeviceIsConnectedString, *currentBtDeviceIsAVPConnectedString; + json_object_put(returnedJ); + + return err; +} + +int HalBtDataHandleReceivedSingleBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentSingleBtDeviceDataJ) +{ + unsigned int currentBtDeviceIsConnected = 0; + unsigned int currentBtDeviceIsA2DP = 0; + unsigned int idx = 0; + char *currentBtDeviceAddress; json_object *currentBtAllProfilesJ = NULL, *currentBtCurrentProfileJ; struct HalBtDeviceData *currentBtDevice; @@ -183,11 +229,10 @@ int HalBtDataHandleReceivedSingleBtDeviceData(struct HalBtPluginData *halBtPlugi return -1; if(wrap_json_unpack(currentSingleBtDeviceDataJ, - "{s:s s:s s:s s?:o}", - "Address", ¤tBtDeviceAddress, - "Connected", ¤tBtDeviceIsConnectedString, - "AVPConnected", ¤tBtDeviceIsAVPConnectedString, - "UUIDs", ¤tBtAllProfilesJ)) { + "{s:s s:b s?:o}", + "address", ¤tBtDeviceAddress, + "connected", ¤tBtDeviceIsConnected, + "uuids", ¤tBtAllProfilesJ)) { return -2; } @@ -197,7 +242,7 @@ int HalBtDataHandleReceivedSingleBtDeviceData(struct HalBtPluginData *halBtPlugi } if(json_object_is_type(currentBtAllProfilesJ, json_type_array)) { - btProfilesCount = json_object_array_length(currentBtAllProfilesJ); + int btProfilesCount = json_object_array_length(currentBtAllProfilesJ); while(idx < btProfilesCount) { currentBtCurrentProfileJ = json_object_array_get_idx(currentBtAllProfilesJ, idx); @@ -211,17 +256,10 @@ int HalBtDataHandleReceivedSingleBtDeviceData(struct HalBtPluginData *halBtPlugi idx++; } } - else if(json_object_is_type(currentBtAllProfilesJ, json_type_string) && - ! strncasecmp(json_object_get_string(currentBtAllProfilesJ), A2DP_AUDIOSOURCE_UUID, sizeof(A2DP_AUDIOSOURCE_UUID))) { - currentBtDeviceIsA2DP = 1; - } if(! currentBtDeviceIsA2DP) return 0; - currentBtDeviceIsConnected = ((! strncmp(currentBtDeviceIsConnectedString, "True", strlen(currentBtDeviceIsConnectedString))) && - (! strncmp(currentBtDeviceIsAVPConnectedString, "True", strlen(currentBtDeviceIsAVPConnectedString)))); - currentBtDevice = HalBtDataSearchBtDeviceByAddress(&halBtPluginData->first, currentBtDeviceAddress); if(currentBtDevice && ! currentBtDeviceIsConnected) { @@ -268,9 +306,16 @@ int HalBtDataHandleReceivedMutlipleBtDeviceData(struct HalBtPluginData *halBtPlu btDeviceNumber = json_object_array_length(currentMultipleBtDeviceDataJ); for(idx = 0; idx < btDeviceNumber; idx++) { - if((err = HalBtDataHandleReceivedSingleBtDeviceData(halBtPluginData, json_object_array_get_idx(currentMultipleBtDeviceDataJ, (unsigned int) idx)))) { + struct json_object *jobj = json_object_array_get_idx(currentMultipleBtDeviceDataJ, (unsigned int) idx); + struct json_object *val; + + if(!json_object_object_get_ex(jobj, "properties", &val)) + continue; + + err = HalBtDataHandleReceivedSingleBtDeviceData(halBtPluginData, val); + + if(err) return ((int) idx * err * 10); - } } return 0; diff --git a/plugins/lib/bluetooth/hal-bt-data.h b/plugins/lib/bluetooth/hal-bt-data.h index 36e0430..b759582 100644 --- a/plugins/lib/bluetooth/hal-bt-data.h +++ b/plugins/lib/bluetooth/hal-bt-data.h @@ -58,7 +58,8 @@ struct HalBtPluginData { // Exported verbs for 'struct HalBtDeviceData' list (available in 'struct HalBtPluginData') handling int HalBtDataGetNumberOfBtDeviceInList(struct HalBtDeviceData **firstBtDeviceData); struct HalBtDeviceData *HalBtDataSearchBtDeviceByAddress(struct HalBtDeviceData **firstBtDeviceData, char *btAddress); +int HalBtDataHandleReceivedMediaBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentSingleBtMediaDataJ); int HalBtDataHandleReceivedSingleBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentSingleBtDeviceDataJ); int HalBtDataHandleReceivedMutlipleBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentMultipleBtDeviceDataJ); -#endif /* _HAL_BT_DATA_INCLUDE_ */ \ No newline at end of file +#endif /* _HAL_BT_DATA_INCLUDE_ */ diff --git a/plugins/lib/bluetooth/hal-bt.c b/plugins/lib/bluetooth/hal-bt.c index a4791e1..1a53c0d 100644 --- a/plugins/lib/bluetooth/hal-bt.c +++ b/plugins/lib/bluetooth/hal-bt.c @@ -49,7 +49,8 @@ CTLP_INIT(plugin, callbacks) unsigned int idx; - char *btStreamZone, *returnedInfo; + char *btStreamZone; + struct json_object *returnedState; CtlConfigT *ctrlConfig; @@ -80,19 +81,18 @@ CTLP_INIT(plugin, callbacks) return -3; } - if(AFB_ServiceSync(plugin->api, BT_MANAGER_API, BT_MANAGER_GET_POWER_INFO, NULL, &returnedJ)) { - if((! wrap_json_unpack(returnedJ, "{s:{s:s}}", "request", "info", &returnedInfo)) && - (! strncmp(returnedInfo, "Unable to get power status", strlen(returnedInfo)))) { + if(AFB_ServiceSync(plugin->api, BT_MANAGER_API, BT_MANAGER_GET_ADAPTER_INFO, NULL, &returnedJ)) { + if(wrap_json_unpack(returnedJ, "{s:{s:b}}", "response", "powered", &returnedState)) { AFB_ApiWarning(plugin->api, - "No bluetooth receiver detected when calling verb '%s' of '%s' api, bluetooth is disable because not reachable", - BT_MANAGER_GET_POWER_INFO, + "No bluetooth receiver detected when calling verb '%s' of '%s' api, bluetooth is disabled because not reachable", + BT_MANAGER_GET_ADAPTER_INFO, BT_MANAGER_API); return 0; } else { AFB_ApiError(plugin->api, "Error during call to verb '%s' of '%s' api (%s)", - BT_MANAGER_GET_POWER_INFO, + BT_MANAGER_GET_ADAPTER_INFO, BT_MANAGER_API, json_object_get_string(returnedJ)); return -4; @@ -106,7 +106,7 @@ CTLP_INIT(plugin, callbacks) } wrap_json_pack(&actionsToAdd, "{s:s s:s}", - "uid", "Bluetooth-Manager/device_updated", + "uid", "Bluetooth-Manager/media", "action", "plugin://hal-bt#events"); if(currentHalData->status != HAL_STATUS_AVAILABLE) { @@ -298,7 +298,7 @@ CTLP_CAPI(init, source, argsJ, queryJ) return -6; } - else if(! wrap_json_unpack(returnedJ, "{s:{s:s}}", "request", "info", &returnedInfo)) { + else if(wrap_json_unpack(returnedJ, "{s:{s:s}}", "request", "info", &returnedInfo)) { AFB_ApiError(source->api, "Couldn't subscribe to event '%s' during call to verb '%s' of api '%s' (error '%s')", BT_MANAGER_DEVICE_UPDATE_EVENT, @@ -311,24 +311,14 @@ CTLP_CAPI(init, source, argsJ, queryJ) json_object_put(returnedJ); if(AFB_ServiceSync(source->api, BT_MANAGER_API, BT_MANAGER_GET_DEVICES_VERB, NULL, &returnedJ)) { - if((! wrap_json_unpack(returnedJ, "{s:{s:s}}", "request", "info", &returnedInfo)) && - (! strncmp(returnedInfo, "No find devices", strlen(returnedInfo)))) { - AFB_ApiInfo(source->api, - "No bluetooth devices returned by call to verb '%s' of '%s' api", - BT_MANAGER_GET_DEVICES_VERB, - BT_MANAGER_API); - } - else { - AFB_ApiError(source->api, - "Error during call to verb '%s' of '%s' api (%s)", - BT_MANAGER_GET_DEVICES_VERB, - BT_MANAGER_API, - json_object_get_string(returnedJ)); - + AFB_ApiError(source->api, + "Error during call to verb '%s' of '%s' api (%s)", + BT_MANAGER_GET_DEVICES_VERB, + BT_MANAGER_API, + json_object_get_string(returnedJ)); return -7; - } } - else if(wrap_json_unpack(returnedJ, "{s:{s:o}}", "response", "list", &returnedBtList)) { + else if(wrap_json_unpack(returnedJ, "{s:{s:o}}", "response", "devices", &returnedBtList)) { AFB_ApiError(source->api, "Couldn't get bluetooth device list during call to verb '%s' of api '%s'", BT_MANAGER_GET_DEVICES_VERB, @@ -375,7 +365,7 @@ CTLP_CAPI(events, source, argsJ, queryJ) return 0; } - if(HalBtDataHandleReceivedSingleBtDeviceData(&localHalBtPluginData, queryJ)) { + if(HalBtDataHandleReceivedMediaBtDeviceData(&localHalBtPluginData, queryJ)) { AFB_ApiError(source->api, "Error while decoding bluetooth event received json (%s)", json_object_get_string(queryJ)); return -1; } @@ -403,4 +393,4 @@ CTLP_CAPI(events, source, argsJ, queryJ) } return 0; -} \ No newline at end of file +} diff --git a/plugins/lib/bluetooth/hal-bt.h b/plugins/lib/bluetooth/hal-bt.h index af5f6c3..120c166 100644 --- a/plugins/lib/bluetooth/hal-bt.h +++ b/plugins/lib/bluetooth/hal-bt.h @@ -25,10 +25,10 @@ #define HAL_BT_PLUGIN_NAME "hal-bt" #define BT_MANAGER_API "Bluetooth-Manager" -#define BT_MANAGER_GET_POWER_INFO "power" +#define BT_MANAGER_GET_ADAPTER_INFO "adapter_state" #define BT_MANAGER_SUBSCRIBE_VERB "subscribe" -#define BT_MANAGER_GET_DEVICES_VERB "discovery_result" +#define BT_MANAGER_GET_DEVICES_VERB "managed_objects" -#define BT_MANAGER_DEVICE_UPDATE_EVENT "device_updated" +#define BT_MANAGER_DEVICE_UPDATE_EVENT "media" -#endif /* _HAL_BT_INCLUDE_ */ \ No newline at end of file +#endif /* _HAL_BT_INCLUDE_ */ -- cgit 1.2.3-korg