CAResult_t CAAppendBLECharInfo( bt_gatt_attribute_h characteristic, CHAR_TYPE type, BLEServiceInfo *bleServiceInfo) { OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); VERIFY_NON_NULL(characteristic, NULL, "Param characteristic is NULL"); VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL"); if (BLE_GATT_READ_CHAR == type ) { int ret = bt_gatt_clone_attribute_handle(&((bleServiceInfo)->read_char), characteristic); if (BT_ERROR_NONE != ret) { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "read_char clone failed with ret [%d]", ret); return CA_STATUS_FAILED; } } else if (BLE_GATT_WRITE_CHAR == type) { int ret = bt_gatt_clone_attribute_handle(&((bleServiceInfo)->write_char), characteristic); if (BT_ERROR_NONE != ret) { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "write_char clone failed with ret [%d]", ret); return CA_STATUS_FAILED; } } OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); return CA_STATUS_OK; }
void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total, bt_gatt_attribute_h descriptor, bt_gatt_attribute_h characteristic, void *userData) { OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICCalloc(1, sizeof( stGattCharDescriptor_t)); VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!"); stTemp->desc = (uint8_t *)OICMalloc(total); if (NULL == stTemp->desc) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed"); OICFree(stTemp); return; } memcpy(stTemp->desc, descriptor, total); OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "result[%d] format[%d] total[%d]", result, format, total); OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic); bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic); stTemp->total = total; ca_mutex_lock(g_bleClientThreadPoolMutex); if (NULL == g_bleClientThreadPool) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL"); bt_gatt_destroy_attribute_handle(stTemp->characteristic); OICFree(stTemp->desc); OICFree(stTemp); ca_mutex_unlock(g_bleClientThreadPoolMutex); return; } CAResult_t ret = ca_thread_pool_add_task(g_bleClientThreadPool, CASetCharacteristicDescriptorValueThread, stTemp); if (CA_STATUS_OK != ret) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed"); bt_gatt_destroy_attribute_handle(stTemp->characteristic); OICFree(stTemp->desc); OICFree(stTemp); ca_mutex_unlock(g_bleClientThreadPoolMutex); return; } OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "LE Client initialization flow complete"); ca_mutex_unlock(g_bleClientThreadPoolMutex); OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); }
CAResult_t CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h service, BLEServiceInfo **bleServiceInfo) { OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); VERIFY_NON_NULL(bdAddress, NULL, "Param bdAddress is NULL"); VERIFY_NON_NULL(service, NULL, "Param service is NULL"); VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL"); *bleServiceInfo = (BLEServiceInfo *) OICCalloc(1, sizeof(BLEServiceInfo)); if (NULL == *bleServiceInfo) { OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "Malloc failed!"); return CA_STATUS_FAILED; } size_t len = strlen(bdAddress); (*bleServiceInfo)->bdAddress = (char *) OICMalloc(sizeof(char) * (len + 1)); if (NULL == (*bleServiceInfo)->bdAddress) { OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "Malloc failed!"); OICFree(*bleServiceInfo); return CA_STATUS_FAILED; } strncpy((*bleServiceInfo)->bdAddress, bdAddress, len + 1); if (service) { int32_t ret = bt_gatt_clone_attribute_handle(&((*bleServiceInfo)->service_clone), service); if (BT_ERROR_NONE != ret) { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "service handle clone failed with ret [%d]", ret); OICFree((*bleServiceInfo)->bdAddress); OICFree(*bleServiceInfo); return CA_STATUS_FAILED; } } OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); return CA_STATUS_OK; }
bool CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int index, int count, void *userData) { OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false); VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false); OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service, index, count); CAResult_t result = CAVerifyOICServiceByServiceHandle(service); if (CA_STATUS_OK == result) { OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service"); OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes"); result = CABleGattWatchCharacteristicChanges(service); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattWatchCharacteristicChanges failed!"); return false; } stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1, sizeof(stGattServiceInfo_t)); VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Calloc Failed", false); char *bdAddress = (char *)userData; stTemp->address = OICStrdup(bdAddress); if (NULL == stTemp->address) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!"); OICFree(stTemp); return false; } BLEServiceInfo *bleServiceInfo = NULL; result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! "); OICFree(stTemp->address); OICFree(stTemp); OICFree(bleServiceInfo); return false; } if (NULL == bleServiceInfo ) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL"); OICFree(stTemp->address); OICFree(stTemp); OICFree(bleServiceInfo); return false; } OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG , " serviceInfo remote address [%s]", bleServiceInfo->bdAddress); ca_mutex_lock(g_bleServiceListMutex); result = CAAddBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo); ca_mutex_unlock(g_bleServiceListMutex); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!"); OICFree(stTemp->address); OICFree(stTemp); CAFreeBLEServiceInfo(bleServiceInfo); return false; } ca_mutex_lock(g_bleClientThreadPoolMutex); if (NULL == g_bleClientThreadPool) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL"); OICFree(stTemp->address); OICFree(stTemp); ca_mutex_lock(g_bleServiceListMutex); CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress); ca_mutex_unlock(g_bleServiceListMutex); ca_mutex_unlock(g_bleClientThreadPoolMutex); return false; } bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), service); result = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverCharThread, stTemp); if (CA_STATUS_OK != result) { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", result); OICFree(stTemp->address); OICFree(stTemp); ca_mutex_lock(g_bleServiceListMutex); CARemoveBLEServiceInfoToList(&g_bLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress); ca_mutex_unlock(g_bleServiceListMutex); ca_mutex_unlock(g_bleClientThreadPoolMutex); return false; } ca_mutex_unlock(g_bleClientThreadPoolMutex); } OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT "); return true;; }
bool CABleGattCharacteristicsDiscoveredCb(int result, int inputIndex, int total, bt_gatt_attribute_h characteristic, void *userData) { OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false); VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false); OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "result [%d] input_index [%d] total [%d]", result, inputIndex, total); BLEServiceInfo *bleServiceInfo = NULL; ca_mutex_lock(g_bleServiceListMutex); char *bdAddress = (char *) userData; CAGetBLEServiceInfo(g_bLEServiceList, bdAddress, &bleServiceInfo); ca_mutex_unlock(g_bleServiceListMutex); char *uuid = NULL; bt_gatt_get_service_uuid(characteristic, &uuid); VERIFY_NON_NULL_RET(uuid, TZ_BLE_CLIENT_TAG, "uuid is NULL", false); OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "New Characteristics[%s] of uuid[%s] is obtained", (char *)characteristic, uuid); if(0 == strcasecmp(uuid, CA_GATT_RESPONSE_CHRC_UUID)) // Server will read on this characterisctics { OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Read characteristics is obtained"); OICFree(uuid); CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_READ_CHAR, bleServiceInfo); if (CA_STATUS_OK != retVal) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! "); return false; } stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICCalloc(1, sizeof(stGattServiceInfo_t)); VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "calloc failed!", false); stTemp->address = OICStrdup(bdAddress); if (NULL == stTemp->address) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed!"); OICFree(stTemp); return false; } bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic); ca_mutex_lock(g_bleClientThreadPoolMutex); if (NULL == g_bleClientThreadPool) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_bleClientThreadPool is NULL"); bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); OICFree(stTemp->address); OICFree(stTemp); ca_mutex_unlock(g_bleClientThreadPoolMutex); return false; } retVal = ca_thread_pool_add_task(g_bleClientThreadPool, CADiscoverDescriptorThread, stTemp); if (CA_STATUS_OK != retVal) { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "ca_thread_pool_add_task failed with ret [%d]", retVal); bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); OICFree(stTemp->address); OICFree(stTemp); ca_mutex_unlock(g_bleClientThreadPoolMutex); return false; } ca_mutex_unlock(g_bleClientThreadPoolMutex); } else if (0 == strcasecmp(uuid, CA_GATT_REQUEST_CHRC_UUID)) // Server will write on this characteristics. { OICFree(uuid); OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG , "Write characteristics is obtained"); CAResult_t retVal = CAAppendBLECharInfo(characteristic, BLE_GATT_WRITE_CHAR, bleServiceInfo); if (CA_STATUS_OK != retVal) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed "); return false; } } else { OICFree(uuid); OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "service_uuid characteristics is UNKNOWN"); return false; } OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); return true; }