From 92eb34c496de489f288c0eb59c9d84d6cf31decd Mon Sep 17 00:00:00 2001 From: Jonathan Aillet Date: Fri, 24 Aug 2018 20:17:12 +0200 Subject: 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 --- plugins/lib/bluetooth/hal-bt-data.c | 220 ++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 plugins/lib/bluetooth/hal-bt-data.c (limited to 'plugins/lib/bluetooth/hal-bt-data.c') diff --git a/plugins/lib/bluetooth/hal-bt-data.c b/plugins/lib/bluetooth/hal-bt-data.c new file mode 100644 index 0000000..d56d0db --- /dev/null +++ b/plugins/lib/bluetooth/hal-bt-data.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author Jonathan Aillet + * + * 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 +#include +#include + +#include + +#include "hal-bt-data.h" + +/******************************************************************************* + * Bt device data handling functions * + ******************************************************************************/ + +int HalBtDataRemoveSelectedBtDeviceFromList(struct HalBtDeviceData **firstBtDeviceData, struct HalBtDeviceData *btDeviceDataToRemove) +{ + struct HalBtDeviceData *currentBtDevice, *matchingBtDevice; + + if(! firstBtDeviceData || ! btDeviceDataToRemove) + return -1; + + currentBtDevice = *firstBtDeviceData; + + if(currentBtDevice == btDeviceDataToRemove) { + *firstBtDeviceData = currentBtDevice->next; + matchingBtDevice = currentBtDevice; + } + else { + while(currentBtDevice && currentBtDevice->next != btDeviceDataToRemove) + currentBtDevice = currentBtDevice->next; + + if(currentBtDevice) { + matchingBtDevice = currentBtDevice->next; + currentBtDevice->next = currentBtDevice->next->next; + } + else { + return -2; + } + } + + free(matchingBtDevice->uid); + free(matchingBtDevice->name); + free(matchingBtDevice->address); + + free(matchingBtDevice); + + return 0; +} + +struct HalBtDeviceData *HalBtDataAddBtDeviceToBtDeviceList(struct HalBtDeviceData **firstBtDeviceData, json_object *currentSingleBtDeviceDataJ) +{ + char *currentBtDeviceName, *currentBtDeviceAddress; + + struct HalBtDeviceData *currentBtDeviceData; + + if(! firstBtDeviceData || ! currentSingleBtDeviceDataJ) + return NULL; + + currentBtDeviceData = *firstBtDeviceData; + + if(! currentBtDeviceData) { + + currentBtDeviceData = (struct HalBtDeviceData *) calloc(1, sizeof(struct HalBtDeviceData)); + if(! currentBtDeviceData) + return NULL; + + *firstBtDeviceData = currentBtDeviceData; + } + else { + + while(currentBtDeviceData->next) + currentBtDeviceData = currentBtDeviceData->next; + + currentBtDeviceData->next = calloc(1, sizeof(struct HalBtDeviceData)); + if(! currentBtDeviceData) + return NULL; + + currentBtDeviceData = currentBtDeviceData->next; + } + + if(wrap_json_unpack(currentSingleBtDeviceDataJ, + "{s:s s:s}", + "Name", ¤tBtDeviceName, + "Address", ¤tBtDeviceAddress)) { + HalBtDataRemoveSelectedBtDeviceFromList(firstBtDeviceData, currentBtDeviceData); + return NULL; + } + + if(asprintf(¤tBtDeviceData->uid, "BT#%s", currentBtDeviceAddress) == -1) { + HalBtDataRemoveSelectedBtDeviceFromList(firstBtDeviceData, currentBtDeviceData); + return NULL; + } + + if(! (currentBtDeviceData->name = strdup(currentBtDeviceName))) { + HalBtDataRemoveSelectedBtDeviceFromList(firstBtDeviceData, currentBtDeviceData); + return NULL; + } + + if(! (currentBtDeviceData->address = strdup(currentBtDeviceAddress))) { + HalBtDataRemoveSelectedBtDeviceFromList(firstBtDeviceData, currentBtDeviceData); + return NULL; + } + + return currentBtDeviceData; +} + +int HalBtDataGetNumberOfBtDeviceInList(struct HalBtDeviceData **firstBtDeviceData) +{ + unsigned int btDeviceNb = 0; + + struct HalBtDeviceData *currentBtDeviceData; + + if(! firstBtDeviceData) + return -1; + + currentBtDeviceData = *firstBtDeviceData; + + while(currentBtDeviceData) { + currentBtDeviceData = currentBtDeviceData->next; + btDeviceNb++; + } + + return btDeviceNb; +} + +struct HalBtDeviceData *HalBtDataSearchBtDeviceByAddress(struct HalBtDeviceData **firstBtDeviceData, char *btAddress) +{ + struct HalBtDeviceData *currentBtDevice; + + if(! firstBtDeviceData || ! btAddress) + return NULL; + + currentBtDevice = *firstBtDeviceData; + + while(currentBtDevice) { + if(! strcmp(btAddress, currentBtDevice->address)) + return currentBtDevice; + + currentBtDevice = currentBtDevice->next; + } + + return NULL; +} + +int HalBtDataHandleReceivedSingleBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentSingleBtDeviceDataJ) +{ + unsigned int currentBtDeviceIsConnected; + + char *currentBtDeviceAddress, *currentBtDeviceIsConnectedString; + + struct HalBtDeviceData *currentBtDevice; + if(! halBtPluginData || ! currentSingleBtDeviceDataJ) + return -1; + + if(wrap_json_unpack(currentSingleBtDeviceDataJ, + "{s:s s:s}", + "Address", ¤tBtDeviceAddress, + "Connected", ¤tBtDeviceIsConnectedString)) { + return -2; + } + + currentBtDeviceIsConnected = ! strncmp(currentBtDeviceIsConnectedString, "True", strlen(currentBtDeviceIsConnectedString)); + currentBtDevice = HalBtDataSearchBtDeviceByAddress(&halBtPluginData->first, currentBtDeviceAddress); + + if(currentBtDevice && ! currentBtDeviceIsConnected) { + if(HalBtDataRemoveSelectedBtDeviceFromList(&halBtPluginData->first, currentBtDevice)) + return -3; + + if(halBtPluginData->selectedBtDevice == currentBtDevice) + halBtPluginData->selectedBtDevice = halBtPluginData->first; + } + else if(! currentBtDevice && currentBtDeviceIsConnected) { + + if(! HalBtDataAddBtDeviceToBtDeviceList(&halBtPluginData->first, currentSingleBtDeviceDataJ)) + return -4; + + if(! halBtPluginData->selectedBtDevice) + halBtPluginData->selectedBtDevice = halBtPluginData->first; + } + + return 0; +} + +int HalBtDataHandleReceivedMutlipleBtDeviceData(struct HalBtPluginData *halBtPluginData, json_object *currentMultipleBtDeviceDataJ) +{ + int err = 0; + size_t idx, btDeviceNumber; + + if(! halBtPluginData || ! currentMultipleBtDeviceDataJ) + return -1; + + if(! json_object_is_type(currentMultipleBtDeviceDataJ, json_type_array)) + return -2; + + 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)))) + return ((int) idx * err * 10); + } + + return 0; +} \ No newline at end of file -- cgit 1.2.3-korg