X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=resource%2Fcsdk%2Fconnectivity%2Fsrc%2Fbt_le_adapter%2Ftizen%2Fcaleserver.c;h=019984ddd6a6f878ca3c24e64ac16de3a9d9d6de;hb=refs%2Ftags%2Fsubmit%2Ftizen_5.0%2F20181219.005848;hp=f21b6373aa665c2867017fe98fa26c3d71d6e0e2;hpb=dbdccd21aa801bdf33b6277f17387b2dda7eb50a;p=platform%2Fupstream%2Fiotivity.git diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c index f21b637..019984d 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c @@ -21,11 +21,13 @@ #include "caleserver.h" #include "cacommon.h" #include "cacommonutil.h" -#include "camutex.h" +#include "octhread.h" #include "caqueueingthread.h" #include "cagattservice.h" +#include "oic_string.h" #include "oic_malloc.h" #include "caleutil.h" +#include /** * Logging tag for module name @@ -33,11 +35,6 @@ #define TAG "OIC_CA_LE_SERVER" /** - * Initial buffer size for Gatt Server. - */ -#define CA_LE_INITIAL_BUF_SIZE 512 - -/** * The handle of the OIC server. */ static bt_gatt_server_h g_gattServer = NULL; @@ -71,7 +68,7 @@ static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL; /** * Callback to notify any error in LE adapter. */ -static CABLEErrorHandleCallback g_serverErrorCallback; +static CABLEErrorHandleCallback g_serverErrorCallback = NULL; /** * To keep the state of GATT server if started or not. @@ -81,28 +78,28 @@ static bool g_isLEGattServerStarted = false; /** * Mutex to synchronize the calls to start and stop server. */ -static ca_mutex g_leServerStateMutex = NULL; +static oc_mutex g_leServerStateMutex = NULL; /** * Mutex to synchronize writing operations on the characteristics. */ -static ca_mutex g_leCharacteristicMutex = NULL; +static oc_mutex g_leCharacteristicMutex = NULL; /** * Mutex to synchronize to creation of OIC service. */ -static ca_mutex g_leServiceMutex = NULL; +static oc_mutex g_leServiceMutex = NULL; /** * Mutex to synchronize access to the requestResponse callback to be called * when the data needs to be sent from GATTClient. */ -static ca_mutex g_leReqRespCbMutex = NULL; +static oc_mutex g_leReqRespCbMutex = NULL; /** * Mutex to synchronize the task to be pushed to thread pool. */ -static ca_mutex g_leServerThreadPoolMutex = NULL; +static oc_mutex g_leServerThreadPoolMutex = NULL; /** * Reference to threadpool. @@ -114,36 +111,60 @@ static ca_thread_pool_t g_leServerThreadPool = NULL; */ static GMainLoop *g_eventLoop = NULL; -static CALEConnectionStateChangedCallback g_connStateCb = NULL; +/** + * This contains the list of OIC clients connected to the server. + */ +static LEClientInfoList *g_LEClientList = NULL; -void CASetLEConnectionStateChangedCallback(CALEConnectionStateChangedCallback connStateCb) -{ - g_connStateCb = connStateCb; -} +/** + * Mutex to synchronize access to LE ClientList. + */ +static oc_mutex g_LEClientListMutex = NULL; void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress) { VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address"); + CAResult_t res = CA_STATUS_OK; if (connected) { OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress); - if (g_connStateCb) + char *addr = OICStrdup(remoteAddress); + oc_mutex_lock(g_LEClientListMutex); + res = CAAddLEClientInfoToList(&g_LEClientList, addr); + if (CA_STATUS_OK != res) + { + OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed"); + oc_mutex_unlock(g_LEClientListMutex); + OICFree(addr); + return; + } + oc_mutex_unlock(g_LEClientListMutex); + + res = CALEStopAdvertise(); + if (CA_STATUS_OK != res) { - g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, true); + OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res); + return; } } else { OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress); - if (g_connStateCb) + oc_mutex_lock(g_LEClientListMutex); + CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress); + oc_mutex_unlock(g_LEClientListMutex); + + res = CALEStartAdvertise(); + if (CA_STATUS_OK != res) { - g_connStateCb(CA_ADAPTER_GATT_BTLE, remoteAddress, false); + OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res); + return; } } } -void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server, +void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server, bt_gatt_h characteristic, bool completed, void *user_data) { OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result); @@ -153,24 +174,82 @@ CAResult_t CAStartLEGattServer() { OIC_LOG(DEBUG, TAG, "IN"); - ca_mutex_lock(g_leServerThreadPoolMutex); - if (NULL == g_leServerThreadPool) + oc_mutex_lock(g_leServerStateMutex); + if (true == g_isLEGattServerStarted) + { + OIC_LOG(ERROR, TAG, "Gatt Server is already running"); + oc_mutex_unlock(g_leServerStateMutex); + return CA_STATUS_OK; + } + + CAResult_t ret = CAInitLEGattServer(); + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret); + oc_mutex_unlock(g_leServerStateMutex); + CATerminateLEGattServer(); + return CA_STATUS_FAILED; + } + + ret = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID); + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret); + oc_mutex_unlock(g_leServerStateMutex); + CATerminateLEGattServer(); + return CA_STATUS_FAILED; + } + + static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID; + char charReadValue[] = {33, 44, 55, 66}; // These are initial random values + + // For Read Characteristics. + ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue, + sizeof(charReadValue), true); + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret); + oc_mutex_unlock(g_leServerStateMutex); + CATerminateLEGattServer(); + return CA_STATUS_FAILED; + } + + static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID; + char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values + + + ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue, + sizeof(charWriteValue), false); // For Write Characteristics. + if (CA_STATUS_OK != ret ) + { + OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret); + oc_mutex_unlock(g_leServerStateMutex); + CATerminateLEGattServer(); + return CA_STATUS_FAILED; + } + + ret = CARegisterLEServicewithGattServer(g_gattSvcPath); + if (CA_STATUS_OK != ret ) { - OIC_LOG(ERROR, TAG, "g_leServerThreadPool is NULL"); - ca_mutex_unlock(g_leServerThreadPoolMutex); + OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret); + oc_mutex_unlock(g_leServerStateMutex); + CATerminateLEGattServer(); return CA_STATUS_FAILED; } - CAResult_t ret = ca_thread_pool_add_task(g_leServerThreadPool, CAStartLEGattServerThread, - NULL); + ret = CALEStartAdvertise(); if (CA_STATUS_OK != ret) { - OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret); - ca_mutex_unlock(g_leServerThreadPoolMutex); + OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret); + oc_mutex_unlock(g_leServerStateMutex); + CATerminateLEGattServer(); return CA_STATUS_FAILED; } - ca_mutex_unlock(g_leServerThreadPoolMutex); + g_isLEGattServerStarted = true; + + oc_mutex_unlock(g_leServerStateMutex); + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -179,14 +258,35 @@ void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_han void *user_data) { OIC_LOG(DEBUG, TAG, "IN"); - if(notify) + if (notify) { OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client"); + CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1, + true, "notifyChar success"); + } + else + { + CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1, + false, "notifyChar failure"); } OIC_LOG(DEBUG, TAG, "OUT"); } -CAResult_t CALEStartAdvertise(const char *serviceUUID) +CAResult_t CALEStartAdvertise() +{ + OIC_LOG(DEBUG, TAG, "IN"); + + CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID); + if (CA_STATUS_OK != res) + { + OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res); + } + + OIC_LOG(DEBUG, TAG, "OUT"); + return res; +} + +CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID) { OIC_LOG(DEBUG, TAG, "IN"); @@ -258,118 +358,26 @@ CAResult_t CALEStopAdvertise() return CA_STATUS_OK; } -void CAStartLEGattServerThread(void *data) -{ - OIC_LOG(DEBUG, TAG, "IN"); - ca_mutex_lock(g_leServerStateMutex); - if (true == g_isLEGattServerStarted) - { - OIC_LOG(ERROR, TAG, "Gatt Server is already running"); - ca_mutex_unlock(g_leServerStateMutex); - CATerminateLEGattServer(); - return; - } - - CAResult_t ret = CAInitLEGattServer(); - if (CA_STATUS_OK != ret) - { - OIC_LOG_V(ERROR, TAG, "CAInitLEGattService failed[%d]", ret); - ca_mutex_unlock(g_leServerStateMutex); - CATerminateLEGattServer(); - return; - } - - char *serviceUUID = CA_GATT_SERVICE_UUID; - - ret = CAAddNewLEServiceInGattServer(serviceUUID); - if (CA_STATUS_OK != ret) - { - OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret); - ca_mutex_unlock(g_leServerStateMutex); - CATerminateLEGattServer(); - return; - } - - static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID; - char charReadValue[] = {33, 44, 55, 66}; // These are initial random values - - // For Read Characteristics. - ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue, - CA_LE_INITIAL_BUF_SIZE, true); - if (CA_STATUS_OK != ret) - { - OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret); - ca_mutex_unlock(g_leServerStateMutex); - CATerminateLEGattServer(); - return; - } - - static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID; - char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values - - - ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue, - CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics. - if (CA_STATUS_OK != ret ) - { - OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret); - ca_mutex_unlock(g_leServerStateMutex); - CATerminateLEGattServer(); - return; - } - - ret = CARegisterLEServicewithGattServer(g_gattSvcPath); - if (CA_STATUS_OK != ret ) - { - OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret); - ca_mutex_unlock(g_leServerStateMutex); - CATerminateLEGattServer(); - return; - } - - ret = CALEStartAdvertise(serviceUUID); - if (CA_STATUS_OK != ret) - { - OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret); - ca_mutex_unlock(g_leServerStateMutex); - CATerminateLEGattServer(); - return; - } - - g_isLEGattServerStarted = true; - - ca_mutex_unlock(g_leServerStateMutex); - - OIC_LOG(DEBUG, TAG, "LE Server initialization complete."); - - GMainContext *thread_context = NULL; - - thread_context = g_main_context_new(); - - g_eventLoop = g_main_loop_new(thread_context, FALSE); - - g_main_context_push_thread_default(thread_context); - - g_main_loop_run(g_eventLoop); - - OIC_LOG(DEBUG, TAG, "OUT"); -} - CAResult_t CAStopLEGattServer() { OIC_LOG(DEBUG, TAG, "IN"); - ca_mutex_lock(g_leServerStateMutex); + oc_mutex_lock(g_leServerStateMutex); if (false == g_isLEGattServerStarted) { OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop"); - ca_mutex_unlock(g_leServerStateMutex); + oc_mutex_unlock(g_leServerStateMutex); return CA_STATUS_OK; } g_isLEGattServerStarted = false; + oc_mutex_lock(g_LEClientListMutex); + CADisconnectAllClient(g_LEClientList); + g_LEClientList = NULL; + oc_mutex_unlock(g_LEClientListMutex); + CAResult_t res = CALEStopAdvertise(); { OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res); @@ -395,13 +403,14 @@ CAResult_t CAStopLEGattServer() // Kill g main loops and kill threads g_main_loop_quit(g_eventLoop); } + g_eventLoop = NULL; } else { OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL"); } - ca_mutex_unlock(g_leServerStateMutex); + oc_mutex_unlock(g_leServerStateMutex); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -427,18 +436,18 @@ void CATerminateLEGattServer() OIC_LOG(DEBUG, TAG, "IN"); // Service and characteristics path will be freed by the platform. - ca_mutex_lock(g_leServiceMutex); + oc_mutex_lock(g_leServiceMutex); g_gattSvcPath = NULL; - ca_mutex_unlock(g_leServiceMutex); + oc_mutex_unlock(g_leServiceMutex); - ca_mutex_lock(g_leCharacteristicMutex); + oc_mutex_lock(g_leCharacteristicMutex); g_gattReadCharPath = NULL; g_gattWriteCharPath = NULL; - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); - ca_mutex_lock(g_leServerThreadPoolMutex); + oc_mutex_lock(g_leServerThreadPoolMutex); g_leServerThreadPool = NULL; - ca_mutex_unlock(g_leServerThreadPoolMutex); + oc_mutex_unlock(g_leServerThreadPoolMutex); // Terminating all mutex variables. CATerminateGattServerMutexVariables(); @@ -450,43 +459,64 @@ CAResult_t CAInitGattServerMutexVariables() OIC_LOG(DEBUG, TAG, "IN"); if (NULL == g_leServerStateMutex) { - g_leServerStateMutex = ca_mutex_new(); + g_leServerStateMutex = oc_mutex_new(); if (NULL == g_leServerStateMutex) { - OIC_LOG(ERROR, TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, TAG, "oc_mutex_new failed"); return CA_STATUS_FAILED; } } if (NULL == g_leServiceMutex) { - g_leServiceMutex = ca_mutex_new(); + g_leServiceMutex = oc_mutex_new(); if (NULL == g_leServiceMutex) { - OIC_LOG(ERROR, TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, TAG, "oc_mutex_new failed"); return CA_STATUS_FAILED; } } if (NULL == g_leCharacteristicMutex) { - g_leCharacteristicMutex = ca_mutex_new(); + g_leCharacteristicMutex = oc_mutex_new(); if (NULL == g_leCharacteristicMutex) { - OIC_LOG(ERROR, TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, TAG, "oc_mutex_new failed"); return CA_STATUS_FAILED; } } if (NULL == g_leReqRespCbMutex) { - g_leReqRespCbMutex = ca_mutex_new(); + g_leReqRespCbMutex = oc_mutex_new(); if (NULL == g_leReqRespCbMutex) { - OIC_LOG(ERROR, TAG, "ca_mutex_new failed"); + OIC_LOG(ERROR, TAG, "oc_mutex_new failed"); return CA_STATUS_FAILED; } } + + if (NULL == g_leServerThreadPoolMutex) + { + g_leServerThreadPoolMutex = oc_mutex_new(); + if (NULL == g_leServerThreadPoolMutex) + { + OIC_LOG(ERROR, TAG, "oc_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == g_LEClientListMutex) + { + g_LEClientListMutex = oc_mutex_new(); + if (NULL == g_LEClientListMutex) + { + OIC_LOG(ERROR, TAG, "oc_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -494,18 +524,24 @@ CAResult_t CAInitGattServerMutexVariables() void CATerminateGattServerMutexVariables() { OIC_LOG(DEBUG, TAG, "IN"); - ca_mutex_free(g_leServerStateMutex); + oc_mutex_free(g_leServerStateMutex); g_leServerStateMutex = NULL; - ca_mutex_free(g_leServiceMutex); + oc_mutex_free(g_leServiceMutex); g_leServiceMutex = NULL; - ca_mutex_free(g_leCharacteristicMutex); + oc_mutex_free(g_leCharacteristicMutex); g_leCharacteristicMutex = NULL; - ca_mutex_free(g_leReqRespCbMutex); + oc_mutex_free(g_leReqRespCbMutex); g_leReqRespCbMutex = NULL; + oc_mutex_free(g_leServerThreadPoolMutex); + g_leServerThreadPoolMutex = NULL; + + oc_mutex_free(g_LEClientListMutex); + g_LEClientListMutex = NULL; + OIC_LOG(DEBUG, TAG, "OUT"); } @@ -521,22 +557,18 @@ CAResult_t CAInitLEGattServer() return CA_STATUS_FAILED; } - bt_gatt_server_h server; - - ret = bt_gatt_server_create(&server); - if (0 != ret) + if (!g_gattServer) { - OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]", - CALEGetErrorMsg(ret)); - return CA_STATUS_FAILED; - } - - if (NULL != g_gattServer) - { - OICFree(g_gattServer); - g_gattServer = NULL; + OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server.."); + ret = bt_gatt_server_create(&g_gattServer); + if (0 != ret) + { + OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]", + CALEGetErrorMsg(ret)); + bt_gatt_server_deinitialize(); + return CA_STATUS_FAILED; + } } - g_gattServer = server; OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -551,7 +583,8 @@ CAResult_t CADeInitLEGattServer() { OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]", CALEGetErrorMsg(ret)); - return CA_STATUS_FAILED; + // CONPRO-1181 continue even bt API fails during DeInit + //return CA_STATUS_FAILED; } ret = bt_gatt_server_destroy(g_gattServer); @@ -559,15 +592,18 @@ CAResult_t CADeInitLEGattServer() { OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]", CALEGetErrorMsg(ret)); - return CA_STATUS_FAILED; + // CONPRO-1181 continue even bt API fails during DeInit + //return CA_STATUS_FAILED; } + g_gattServer = NULL; ret = bt_gatt_server_deinitialize(); if (0 != ret) { OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]", CALEGetErrorMsg(ret)); - return CA_STATUS_FAILED; + // CONPRO-1181 continue even bt API fails during DeInit + //return CA_STATUS_FAILED; } OIC_LOG(DEBUG, TAG, "OUT"); @@ -577,9 +613,9 @@ CAResult_t CADeInitLEGattServer() void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle) { OIC_LOG(DEBUG, TAG, "IN"); - ca_mutex_lock(g_leServerThreadPoolMutex); + oc_mutex_lock(g_leServerThreadPoolMutex); g_leServerThreadPool = handle; - ca_mutex_unlock(g_leServerThreadPoolMutex); + oc_mutex_unlock(g_leServerThreadPoolMutex); OIC_LOG(DEBUG, TAG, "OUT"); } @@ -591,42 +627,34 @@ CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID) OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID); - bt_gatt_h service = NULL; bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY; - int ret = bt_gatt_service_create(serviceUUID, type, &service); + oc_mutex_lock(g_leServiceMutex); + int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath); if (0 != ret) { + oc_mutex_unlock(g_leServiceMutex); OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]", - CALEGetErrorMsg(ret)); + CALEGetErrorMsg(ret)); return CA_STATUS_FAILED; } + oc_mutex_unlock(g_leServiceMutex); - if (NULL != service) + if (g_gattSvcPath) { - OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)service); - - ca_mutex_lock(g_leServiceMutex); - - if (NULL != g_gattSvcPath) - { - OICFree(g_gattSvcPath); - g_gattSvcPath = NULL; - } - g_gattSvcPath = service; - - ca_mutex_unlock(g_leServiceMutex); + OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath); } OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } -void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server, - bt_gatt_h charPath, int offset, char *charValue, +void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id, + bt_gatt_server_h server, bt_gatt_h charPath, + bool response_needed, int offset, const char *charValue, int charValueLen, void *userData) { - OIC_LOG(DEBUG, TAG, "IN"); + OIC_LOG(INFO, TAG, "IN - WriteCharCB"); if (NULL == charValue || NULL == remoteAddress) { @@ -646,22 +674,32 @@ void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h s memcpy(data, charValue, charValueLen); - ca_mutex_lock(g_leReqRespCbMutex); + oc_mutex_lock(g_leReqRespCbMutex); if (NULL == g_leServerDataReceivedCallback) { OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!"); - ca_mutex_unlock(g_leReqRespCbMutex); + oc_mutex_unlock(g_leReqRespCbMutex); OICFree(data); return; } - OIC_LOG(DEBUG, TAG, "Sending data up !"); + OIC_LOG(INFO, TAG, "Sending data up !"); uint32_t sentLength = 0; g_leServerDataReceivedCallback(remoteAddress, data, charValueLen, &sentLength); - ca_mutex_unlock(g_leReqRespCbMutex); + oc_mutex_unlock(g_leReqRespCbMutex); OICFree(data); - OIC_LOG(DEBUG, TAG, "OUT"); + + OIC_LOG_V(INFO, TAG, "response needed flag: %d", response_needed); + if (response_needed) + { + OIC_LOG(INFO, TAG, "send response to remote client"); + bt_gatt_server_send_response(request_id, + BT_GATT_REQUEST_TYPE_WRITE, offset, + BT_ERROR_NONE, NULL, 0); + } + + OIC_LOG(INFO, TAG, "OUT - WriteCharCB"); } CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath) @@ -680,12 +718,20 @@ CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath) return CA_STATUS_FAILED; } - ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath, - CALEGattRemoteCharacteristicWriteCb, NULL); + ret = bt_gatt_server_start(); + if (0 != ret) + { + OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]", + CALEGetErrorMsg(ret)); + return CA_STATUS_FAILED; + } + + ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath, + CALEGattRemoteCharacteristicWriteCb, NULL); if (0 != ret) { - OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]", + OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_write_value_requested_cb failed with ret[%s]", CALEGetErrorMsg(ret)); return CA_STATUS_FAILED; } @@ -702,16 +748,16 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE; int properties; - if(read) + if (read) { - properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ; + properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ; } else { properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ; } - bt_gatt_h charPath; + bt_gatt_h charPath = NULL; int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue, charValueLen, &charPath); @@ -728,11 +774,13 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch if (read) { - ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL); + ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath, + CALENotificationCb, + NULL); if (0 != ret) { OIC_LOG_V(ERROR, TAG, - "bt_gatt_server_set_notification_state_change_cb failed with ret[%s]", + "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]", CALEGetErrorMsg(ret)); return CA_STATUS_FAILED; } @@ -747,7 +795,7 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch return CA_STATUS_FAILED; } - ca_mutex_lock(g_leCharacteristicMutex); + oc_mutex_lock(g_leCharacteristicMutex); if (read) { @@ -759,6 +807,7 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch &descriptor); if (0 != ret) { + oc_mutex_unlock(g_leCharacteristicMutex); OIC_LOG_V(ERROR, TAG, "bt_gatt_descriptor_create failed with ret[%s]", CALEGetErrorMsg(ret)); @@ -768,31 +817,21 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor); if (0 != ret) { + oc_mutex_unlock(g_leCharacteristicMutex); OIC_LOG_V(ERROR, TAG, "bt_gatt_characteristic_add_descriptor failed with ret[%s]", CALEGetErrorMsg(ret)); return CA_STATUS_FAILED; } - if (NULL != g_gattReadCharPath) - { - OICFree(g_gattReadCharPath); - g_gattReadCharPath = NULL; - } g_gattReadCharPath = charPath; - } else { - if (NULL != g_gattWriteCharPath) - { - OICFree(g_gattWriteCharPath); - g_gattWriteCharPath = NULL; - } g_gattWriteCharPath = charPath; } - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -808,12 +847,12 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_ OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address); - ca_mutex_lock(g_leCharacteristicMutex); + oc_mutex_lock(g_leCharacteristicMutex); if (NULL == g_gattReadCharPath) { OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL"); - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); return CA_STATUS_FAILED; } @@ -822,21 +861,22 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_ { OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret)); - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); return CA_STATUS_FAILED; } - ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB, - address, NULL); + ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath, + CALEServerNotificationSentCB, + address, NULL); if (0 != ret) { OIC_LOG_V(ERROR, TAG, - "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret)); - ca_mutex_unlock(g_leCharacteristicMutex); + "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]", CALEGetErrorMsg(ret)); + oc_mutex_unlock(g_leCharacteristicMutex); return CA_STATUS_FAILED; } - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -848,12 +888,12 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uin VERIFY_NON_NULL(charValue, TAG, "charValue"); - ca_mutex_lock(g_leCharacteristicMutex); + oc_mutex_lock(g_leCharacteristicMutex); if (NULL == g_gattReadCharPath) { OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL"); - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); return CA_STATUS_FAILED; } @@ -861,21 +901,22 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uin if (0 != ret) { OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret)); - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); return CA_STATUS_FAILED; } - ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB, - NULL, NULL); + ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath, + CALEServerNotificationSentCB, + NULL, NULL); if (0 != ret) { OIC_LOG_V(ERROR, TAG, - "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret)); - ca_mutex_unlock(g_leCharacteristicMutex); + "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]", CALEGetErrorMsg(ret)); + oc_mutex_unlock(g_leCharacteristicMutex); return CA_STATUS_FAILED; } - ca_mutex_unlock(g_leCharacteristicMutex); + oc_mutex_unlock(g_leCharacteristicMutex); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; @@ -885,9 +926,9 @@ void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback) { OIC_LOG(DEBUG, TAG, "IN"); - ca_mutex_lock(g_leReqRespCbMutex); + oc_mutex_lock(g_leReqRespCbMutex); g_leServerDataReceivedCallback = callback; - ca_mutex_unlock(g_leReqRespCbMutex); + oc_mutex_unlock(g_leReqRespCbMutex); OIC_LOG(DEBUG, TAG, "OUT"); } @@ -896,3 +937,47 @@ void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback) { g_serverErrorCallback = callback; } + +bool CALEServerIsConnected(const char* address) +{ + //@Todo + return true; +} + +uint16_t CALEServerGetMtuSize(const char* address) +{ + OIC_LOG(DEBUG, TAG, "IN"); + VERIFY_NON_NULL_RET(address, TAG, "address is null", + CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE); + + unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE; + int ret = 0; + + bt_gatt_client_h client = NULL; + ret = bt_gatt_client_create(address, &client); + if (0 != ret) + { + OIC_LOG_V(ERROR, TAG, + "bt_gatt_client_create failed with return [%s]", CALEGetErrorMsg(ret)); + return CA_DEFAULT_BLE_MTU_SIZE; + } + + ret = bt_gatt_client_get_att_mtu(client, &mtu); + if (0 != ret) + { + OIC_LOG_V(ERROR, TAG, + "bt_gatt_client_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret)); + return CA_DEFAULT_BLE_MTU_SIZE; + } + + ret = bt_gatt_client_destroy(client); + if (0 != ret) + { + OIC_LOG_V(ERROR, TAG, + "bt_gatt_client_destroy failed with return [%s]", CALEGetErrorMsg(ret)); + return CA_DEFAULT_BLE_MTU_SIZE; + } + + OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu); + return mtu - CA_BLE_MTU_HEADER_SIZE; +}