Use GATT server's get mtu size API instead of GATT client API
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / bt_le_adapter / tizen / caleserver_mcd.c
index a7273e7..9f3791f 100644 (file)
 #include "oic_string.h"
 #include "oic_malloc.h"
 #include "caleutil.h"
+#include "cautilinterface.h"
+#ifndef BLE_TIZEN_40
+#include <bluetooth_internal.h>
+#endif
 
 /**
  * Logging tag for module name
  */
 //#define TAG "OIC_CA_LE_SERVER_MCD"
 #define TAG BLE_SERVER_MCD_TAG
-/**
- * Initial buffer size for Gatt Server.
- */
-#define CA_LE_INITIAL_BUF_SIZE 512
 
 /**
  * The handle of the OIC server.
@@ -64,6 +64,17 @@ static bt_gatt_h g_gattWriteCharPath = NULL;
 static bt_advertiser_h g_hAdvertiser = NULL;
 
 /**
+ * Function called just before starting advertising
+ * provided data are used to setServerAdvertisementData
+ */
+static CAAdvertisementDataGetterCB g_leServerAdvertisementDataGetter = NULL;
+
+/**
+ * Control if advertise will start automatically
+ */
+static bool g_leServerAutoAdvertisement = true;
+
+/**
  * Callback register with LE adapter.  This callback is called on reception of any
  * data from the remote device.
  */
@@ -135,9 +146,15 @@ static bool cutom_scanrsp_flag = false;
 static char *custom_scanrsp_data = NULL;
 static int custom_scanrsp_data_length = 0;
 
+/**
+ * Maximum length of BLE advertisement packet data size is acctually 24 bytes,
+ * but for safety reason 1 additional byte is allocated.
+ */
+const int g_leAdvPacketDataSizeMax = 25;
+
+
 CAResult_t CAsetServerAdvertisementData(const char *data, int length)
 {
-    int res = 0;
     CAResult_t ret = CA_STATUS_OK;
 
     OIC_LOG(DEBUG, TAG, "IN");
@@ -149,20 +166,45 @@ CAResult_t CAsetServerAdvertisementData(const char *data, int length)
     }
 
     oc_mutex_lock(g_leServerStateMutex);
+    CAsetServerAdvertisementDataImpl(data, length);
+    oc_mutex_unlock(g_leServerStateMutex);
 
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return ret;
+}
+
+void CAsetServerAdvertisementDataImpl(const char *data, int length)
+{
     cutom_adv_flag = true;
     custom_adv_data = data;
     custom_adv_data_length = length;
 
+    OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
+}
+
+void CAsetServerAdvertisementDataGetter(CAAdvertisementDataGetterCB getter)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leServerStateMutex);
+    g_leServerAdvertisementDataGetter = getter;
     oc_mutex_unlock(g_leServerStateMutex);
 
-    OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
     OIC_LOG(DEBUG, TAG, "OUT");
+}
 
-    return ret;
+void CAsetServerAutoAdvertisement(bool autoAdvertisement)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leServerStateMutex);
+    g_leServerAutoAdvertisement = autoAdvertisement;
+    oc_mutex_unlock(g_leServerStateMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
-CAResult_t CAsetServerSanResponseData(const char *data, int length)
+CAResult_t CAsetServerScanResponseData(const char *data, int length)
 {
     int res = 0;
     CAResult_t ret = CA_STATUS_OK;
@@ -223,11 +265,18 @@ void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddr
         CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
         oc_mutex_unlock(g_LEClientListMutex);
 
-        res = CALEStartAdvertise();
-        if (CA_STATUS_OK != res)
+        if(g_leServerAutoAdvertisement)
         {
-            OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
-            return;
+            res = CALEStartAdvertise();
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
+                return;
+            }
+        }
+        else
+        {
+            OIC_LOG(WARNING, TAG, "Auto advertisement is DISABLED. Advertising is not started.");
         }
     }
 }
@@ -278,7 +327,7 @@ CAResult_t CAStartLEGattServer()
 
     // For Read Characteristics.
     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
-                                              CA_LE_INITIAL_BUF_SIZE, true);
+                                              sizeof(charReadValue), true);
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
@@ -292,7 +341,7 @@ CAResult_t CAStartLEGattServer()
 
 
     ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
-            CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
+            sizeof(charWriteValue), false); // For Write Characteristics.
     if (CA_STATUS_OK != ret )
     {
         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
@@ -309,16 +358,23 @@ CAResult_t CAStartLEGattServer()
         CATerminateLEGattServer();
         return CA_STATUS_FAILED;
     }
-
-    ret = CALEStartAdvertise();
-    if (CA_STATUS_OK != ret)
+    
+    if(g_leServerAutoAdvertisement)
     {
-        OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
-        oc_mutex_unlock(g_leServerStateMutex);
-        CATerminateLEGattServer();
-        return CA_STATUS_FAILED;
+        ret = CALEStartAdvertise();
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
+            oc_mutex_unlock(g_leServerStateMutex);
+            CATerminateLEGattServer();
+            return CA_STATUS_FAILED;
+        }
     }
-
+    else
+    {
+        OIC_LOG(WARNING, TAG, "Auto advertisement is DISABLED. Advertising is not started.");
+    }
+    
     g_isLEGattServerStarted = true;
 
     oc_mutex_unlock(g_leServerStateMutex);
@@ -348,13 +404,32 @@ void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_han
 CAResult_t CALEStartAdvertise()
 {
     OIC_LOG(DEBUG, TAG, "IN");
+    char * data = NULL;
+
+    if(g_leServerAdvertisementDataGetter)
+    {
+        int length;
+        data = (char*) malloc(g_leAdvPacketDataSizeMax);
+        g_leServerAdvertisementDataGetter(g_leAdvPacketDataSizeMax, data, &length);
+        if(!data || length <= 0)
+        {
+            OIC_LOG(WARNING, TAG, "Invalid data. Custom advertisement data will not be set.");
+        }
+        else
+        {
+            CAsetServerAdvertisementDataImpl(data, length);
+        }
+    }
 
     CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
     }
-
+    
+    //This array is freed here because it's used in CALEStartAdvertiseImpl() method (freeing earlier causes bluetooth to crash)
+    if(data)
+        free(data);
     OIC_LOG(DEBUG, TAG, "OUT");
     return res;
 }
@@ -682,6 +757,7 @@ CAResult_t CAInitLEGattServer()
         {
             OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
                       CALEGetErrorMsg(ret));
+            bt_gatt_server_deinitialize();
             return CA_STATUS_FAILED;
         }
     }
@@ -699,7 +775,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);
@@ -707,7 +784,8 @@ 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;
 
@@ -716,7 +794,8 @@ CAResult_t CADeInitLEGattServer()
     {
         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");
@@ -1103,14 +1182,54 @@ uint16_t CALEServerGetMtuSize(const char* address)
     OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
 
-    unsigned int mtu;
-    int ret = bt_device_get_att_mtu(address, &mtu);
+    unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE;
+    int ret = 0;
+
+#ifdef BLE_TIZEN_55
+    ret = bt_gatt_server_get_device_mtu(address, &mtu);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_server_get_device_mtu failed with return [%s]", CALEGetErrorMsg(ret));
+        return CA_DEFAULT_BLE_MTU_SIZE;
+    }
+#else
+#ifdef BLE_TIZEN_40
+    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;
+    }
+#else
+    ret = bt_device_get_att_mtu(address, &mtu);
     if (0 != ret)
     {
         OIC_LOG_V(ERROR, TAG,
                   "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
         return CA_DEFAULT_BLE_MTU_SIZE;
     }
+#endif // BLE_TIZEN_40
+#endif // BLE_TIZEN_55
+
     OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
     OIC_LOG(DEBUG, TAG, "OUT");
     return mtu - CA_BLE_MTU_HEADER_SIZE;