Android to Android, Tizen to Tizen will be supported by next patch.
Change-Id: I736724df83c57a2193ab591bd7463dd2368642ea
Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/16275
Tested-by: jenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: MyeongGi Jeong <myeong.jeong@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
int status);
+ private native static void caLeGattMtuChangedCallback(BluetoothGatt gatt, int mtu,
+ int status);
+
// Callback
private static BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
super.onReadRemoteRssi(gatt, rssi, status);
caManagerLeRemoteRssiCallback(gatt, rssi, status);
}
+
+ @Override
+ public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+ super.onMtuChanged(gatt, mtu, status);
+ caLeGattMtuChangedCallback(gatt, mtu, status);
+ }
};
private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
};
}
-
private native static void caLeGattServerNotificationSentCallback(BluetoothDevice device,
int status);
+ private native static void caLeGattServerMtuChangedCallback(BluetoothDevice gatt, int mtu);
+
// AdvertiseCallback
private native static void caLeAdvertiseStartSuccessCallback(
AdvertiseSettings settingsInEffect);
#include "logger.h"
/**
- * The MTU supported for BLE adapter
- */
-#define CA_SUPPORTED_BLE_MTU_SIZE 20
-
-/**
* The maximum port value for BLE packet format
*/
#define CA_SUPPORTED_BLE_MAX_PORT 127
#define CA_BLE_LENGTH_HEADER_SIZE 4
/**
- * The length payload size of the normal data segment (after first segment) for ble fragmentation.
- */
-#define CA_BLE_NORMAL_SEGMENT_PAYLOAD_SIZE ((CA_SUPPORTED_BLE_MTU_SIZE) \
- - (CA_BLE_HEADER_SIZE))
-
-/**
- * The length payload size of the first data segment for ble fragmentation.
- */
-#define CA_BLE_FIRST_SEGMENT_PAYLOAD_SIZE ((CA_BLE_NORMAL_SEGMENT_PAYLOAD_SIZE) \
- - (CA_BLE_LENGTH_HEADER_SIZE))
-
-/**
* Current Header version.
*/
#define HEADER_VERSION 1
* packet.
* @param[out] remainingLen Size of last packet before adding header.
* @param[out] totalLengh The total length of the data.
+ * @param[in] mtuSize MTU size.
*
* @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
* or other error values on error.
CAResult_t CAGenerateVariableForFragmentation(size_t dataLength,
uint32_t *midPacketCount,
size_t *remainingLen,
- size_t *totalLength);
+ size_t *totalLength,
+ uint16_t mtuSize);
/**
* This function is used to generate the CA BLE header to
* total data
* @param[in] dataHeader Pointer to the octet array that contain
* data header.
+ * @param[in] mtuSize MTU size.
*
* @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
* or other error values on error.
const uint8_t *sourceData,
const uint32_t sourceDataLength,
const uint32_t segmentNum,
- const uint8_t *dataHeader);
+ const uint8_t *dataHeader,
+ uint16_t mtuSize);
/**
* This function is used to parse the header in the receiver end. This
} CALEData_t;
/**
+ * The MTU supported for BLE adapter
+ */
+#define CA_DEFAULT_BLE_MTU_SIZE 20
+
+/**
+ * The MTU supported for BLE spec
+ */
+#define CA_SUPPORTED_BLE_MTU_SIZE 517
+
+/**
+ * The Header of the MTU supported for BLE spec
+ */
+#define CA_BLE_MTU_HEADER_SIZE 3
+
+/**
* This will be used to notify device status changes to the LE adapter layer.
* @param[in] adapter_state State of the adapter.
*/
#include "cacommon.h"
#include "caadapterutils.h"
#include "cafragmentation.h"
+#include "caleinterface.h"
/**
* Debugging tag for fragmentation module.
CAResult_t CAGenerateVariableForFragmentation(size_t dataLength,
uint32_t *midPacketCount,
size_t *remainingLen,
- size_t *totalLength)
+ size_t *totalLength,
+ uint16_t mtuSize)
{
- OIC_LOG_V(DEBUG, TAG, "IN, dataLength = %zu", dataLength);
+ OIC_LOG_V(DEBUG, TAG, "IN, dataLength = %zu, mtu = %zu", dataLength, mtuSize);
size_t remainDataSize = 0;
size_t dataOnlyLen =
- CA_SUPPORTED_BLE_MTU_SIZE - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE);
+ mtuSize - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE);
//total data size is smaller than 14 byte case.
if (dataLength < dataOnlyLen)
{
remainDataSize = dataLength - dataOnlyLen;
}
- if (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE <= 0)
+ if (mtuSize - CA_BLE_HEADER_SIZE <= 0)
{
OIC_LOG_V(ERROR, TAG, "BLE header size shouldn't be bigger than BLE MTU size.");
return CA_STATUS_FAILED;
}
- *midPacketCount = (uint32_t)remainDataSize / (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE);
- *remainingLen = (uint32_t)remainDataSize % (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE);
+ *midPacketCount = (uint32_t)remainDataSize / (mtuSize - CA_BLE_HEADER_SIZE);
+ *remainingLen = (uint32_t)remainDataSize % (mtuSize - CA_BLE_HEADER_SIZE);
uint32_t remainHeaderSize = CA_BLE_HEADER_SIZE * (*midPacketCount + (*remainingLen == 0 ? 0:1));
*totalLength = dataLength + (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE) + remainHeaderSize;
const uint8_t *sourceData,
const uint32_t sourceDataLength,
const uint32_t segmentNum,
- const uint8_t *dataHeader)
+ const uint8_t *dataHeader,
+ uint16_t mtuSize)
{
OIC_LOG(DEBUG, TAG, "IN");
VERIFY_NON_NULL(dataSegment, TAG, "dataSegment is NULL");
VERIFY_NON_NULL(dataHeader, TAG, "dataHeader is NULL");
- uint32_t index = CA_BLE_FIRST_SEGMENT_PAYLOAD_SIZE +
- (segmentNum * CA_BLE_NORMAL_SEGMENT_PAYLOAD_SIZE);
+ uint32_t index = (mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE) +
+ (segmentNum * (mtuSize - CA_BLE_HEADER_SIZE));
if (sourceDataLength < index + segmentPayloadLength)
{
OIC_LOG(DEBUG, TAG, "dataSegment will exceed");
static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
static bool g_setHighQoS = true;
+
/**
* check if retry logic for connection routine has to be stopped or not.
* in case of error value including this method, connection routine has to be stopped.
CALEClientUpdateSendCnt(env);
}
+CAResult_t CALEClientSendNegotiationMessage(const char* address)
+{
+ OIC_LOG_V(DEBUG, TAG, "CALEClientSendNegotiationMessage(%s)", address);
+ VERIFY_NON_NULL(address, TAG, "address is null");
+
+ return CALEClientSendUnicastMessageImpl(address, NULL, 0);
+}
+
CAResult_t CALEClientSendUnicastMessage(const char* address,
const uint8_t* data,
const uint32_t dataLen)
OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
data);
VERIFY_NON_NULL(address, TAG, "address is null");
- VERIFY_NON_NULL(data, TAG, "data is null");
if (!g_jvm)
{
(*env)->DeleteGlobalRef(env, g_sendBuffer);
g_sendBuffer = NULL;
}
- jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
- CACheckJNIException(env);
- (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
- CACheckJNIException(env);
- g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
- CACheckJNIException(env);
+
+ if (data && dataLen > 0)
+ {
+ jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+ CACheckJNIException(env);
+ (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+ CACheckJNIException(env);
+ g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+ CACheckJNIException(env);
+ }
// Target device to send message is just one.
g_targetCnt = 1;
OIC_LOG(INFO, TAG, "send success");
ret = CA_STATUS_OK;
}
+ else if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
+ STATE_SEND_MTU_NEGO_SUCCESS))
+ {
+ OIC_LOG(INFO, TAG, "mtu nego success");
+ ret = CA_STATUS_OK;
+ }
else
{
OIC_LOG(ERROR, TAG, "send failure");
return jni_obj_connectGatt;
}
+bool CALEClientIsConnected(const char* address)
+{
+ if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
+ STATE_SERVICE_CONNECTED))
+ {
+ OIC_LOG(DEBUG, TAG, "current state is connected");
+ return true;
+ }
+ OIC_LOG(DEBUG, TAG, "current state is not connected");
+ return false;
+}
+
CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
{
OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
return CA_STATUS_OK;
}
+CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
+{
+ VERIFY_NON_NULL(env, TAG, "env is null");
+ VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+
+ if (!CALEIsEnableBTAdapter(env))
+ {
+ OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ // get BluetoothGatt.requestMtu method
+ OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
+ jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
+ "requestMtu", "(I)Z");
+ if (!jni_mid_requestMtu)
+ {
+ OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
+ return CA_STATUS_FAILED;
+ }
+
+ // call requestMtu
+ OIC_LOG(INFO, TAG, "CALL API - requestMtu");
+ jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
+ if (!ret)
+ {
+ OIC_LOG(ERROR, TAG, "requestMtu has failed");
+ CACheckJNIException(env);
+ return CA_STATUS_FAILED;
+ }
+
+ return CA_STATUS_OK;
+}
+
CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
{
VERIFY_NON_NULL(env, TAG, "env is null");
return res;
}
+CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize)
+{
+ VERIFY_NON_NULL(address, TAG, "address is null");
+
+ oc_mutex_lock(g_deviceStateListMutex);
+ if (CALEClientIsDeviceInList(address))
+ {
+ CALEState_t* curState = CALEClientGetStateInfo(address);
+ if(!curState)
+ {
+ OIC_LOG(ERROR, TAG, "curState is null");
+ oc_mutex_unlock(g_deviceStateListMutex);
+ return CA_STATUS_FAILED;
+ }
+
+ curState->mtuSize = mtuSize;
+ OIC_LOG_V(INFO, TAG, "update state - addr: %s, mtu: %d",
+ curState->address, curState->mtuSize);
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "there is no state info in the list");
+ }
+ oc_mutex_unlock(g_deviceStateListMutex);
+ return CA_STATUS_OK;
+}
+
+uint16_t CALEClientGetMtuSize(const char* address)
+{
+ VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+
+ oc_mutex_lock(g_deviceStateListMutex);
+ if (CALEClientIsDeviceInList(address))
+ {
+ CALEState_t* curState = CALEClientGetStateInfo(address);
+ if(!curState)
+ {
+ OIC_LOG(ERROR, TAG, "curState is null");
+ oc_mutex_unlock(g_deviceStateListMutex);
+ return CA_DEFAULT_BLE_MTU_SIZE;
+ }
+
+ OIC_LOG_V(INFO, TAG, "state - addr: %s, mtu: %d",
+ curState->address, curState->mtuSize);
+ oc_mutex_unlock(g_deviceStateListMutex);
+ return curState->mtuSize;
+ }
+
+ oc_mutex_unlock(g_deviceStateListMutex);
+ return CA_DEFAULT_BLE_MTU_SIZE;
+}
+
CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
uint16_t target_state)
{
default:
break;
}
- OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
+ OIC_LOG_V(INFO, TAG, "update state - addr: %s, conn: %d, send: %d, ACFlag: %d, mtu: %d",
curState->address, curState->connectedState, curState->sendState,
- curState->autoConnectFlag);
+ curState->autoConnectFlag, curState->mtuSize);
}
else /** state is added newly **/
{
}
OICStrcpy(newstate->address, sizeof(newstate->address), address);
-
+ newstate->mtuSize = CA_DEFAULT_BLE_MTU_SIZE;
switch(state_type)
{
case CA_LE_CONNECTION_STATE:
int32_t position)
{
OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
- VERIFY_NON_NULL(data, TAG, "data is null");
VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
if (LE_UNICAST != type || position < 0)
goto error_exit;
}
- if (g_sendBuffer)
+ res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
+ if (CA_STATUS_OK != res)
{
- CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
- goto error_exit;
- }
+ OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
+ goto error_exit;
}
}
else
CALEClientSendFinish(env, gatt);
return;
}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
+ jobject obj,
+ jobject gatt,
+ jint mtu,
+ jint status)
+{
+ OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - mtu[%d-including Header size 3 byte)", mtu);
+ OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d", status);
+
+ (void)obj;
+
+ if (0 == status)
+ {
+ if (g_sendBuffer)
+ {
+ CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+ }
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "mtu nego is done");
+ jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+ if (!jni_address)
+ {
+ CALEClientSendFinish(env, gatt);
+ return;
+ }
+
+ const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+ if (!address)
+ {
+ CACheckJNIException(env);
+ (*env)->DeleteLocalRef(env, jni_address);
+ CALEClientSendFinish(env, gatt);
+ return;
+ }
+
+ // update mtu size
+ CAResult_t res = CALEClientSetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEClientSetMtuSize has failed");
+ }
+
+ res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
+ STATE_SEND_MTU_NEGO_SUCCESS);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+ }
+ CALEClientUpdateSendCnt(env);
+ (*env)->ReleaseStringUTFChars(env, jni_address, address);
+ (*env)->DeleteLocalRef(env, jni_address);
+ }
+ }
+}
static const uint16_t STATE_SEND_FAIL = 3;
static const uint16_t STATE_SENDING = 4;
static const uint16_t STATE_SEND_PREPARING = 5;
+static const uint16_t STATE_SEND_MTU_NEGO_SUCCESS = 6;
typedef struct le_state_info
{
uint16_t sendState;
jboolean autoConnectFlag;
jboolean isDescriptorFound;
+ uint16_t mtuSize;
} CALEState_t;
/**
void CALEClientSendFinish(JNIEnv *env, jobject gatt);
/**
+ * send negotiation message after gatt connection is done.
+ * @param[in] address remote address.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendNegotiationMessage(const char* address);
+
+/**
* send data for unicast (interface).
* @param[in] address remote address.
* @param[in] data data for transmission.
CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remoteAddress);
/**
+ * request MTU size negotiation to server.
+ * @param[in] env JNI interface pointer.
+ * @param[in] bluetoothGatt gatt object.
+ * @param[in] size MTU size.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size);
+/**
* start discovery server.
* @param[in] env JNI interface pointer.
* @param[in] bluetoothGatt Gatt profile object.
uint16_t target_state);
/**
+ * This function is used to set MTU size
+ * which negotiated between client and server device.
+ * @param[in] address remote address.
+ * @param[in] mtuSize MTU size.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize);
+
+/**
+ * get MTU size.
+ * @param[in] address the address of the remote device.
+ * @return mtu size negotiated from remote device.
+ */
+uint16_t CALEClientGetMtuSize(const char* address);
+
+/**
* check whether the remote address is existed or not.
* @param[in] address remote address.
* @return true or false.
CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect);
/**
+ * check connection status.
+ * @param[in] address the address of the remote device.
+ * @return true or false.
+ */
+bool CALEClientIsConnected(const char* address);
+
+/**
* set new interval time and working count.
* @param[in] intervalTime interval time(Seconds).
* @param[in] workingCount working count for selected interval time.
}
}
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerMtuChangedCallback(JNIEnv * env,
+ jobject obj,
+ jobject device,
+ jint mtu)
+{
+ VERIFY_NON_NULL_VOID(env, TAG, "env");
+ VERIFY_NON_NULL_VOID(obj, TAG, "obj");
+ VERIFY_NON_NULL_VOID(device, TAG, "device");
+
+ OIC_LOG_V(INFO, TAG, "gatt MTU size is changed (%d byte)", mtu);
+}
+
/**
* adapter common
*/
{
OIC_LOG(DEBUG, TAG, "this method is not supported");
}
+
+bool CALEServerIsConnected(const char* address)
+{
+ //@Todo
+ //it will be implemented next patch.
+ return true;
+}
+
+uint16_t CALEServerGetMtuSize(const char* address)
+{
+ VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+
+ //@Todo
+ //it will be implemented next patch.
+ return CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE;
+}
+
*/
void CALEServerTerminateConditionVaraibles();
+/**
+ * check connection status.
+ * @param[in] address the address of the remote device.
+ * @return true or false.
+ */
+bool CALEServerIsConnected(const char* address);
+
+/**
+ * get MTU size.
+ * @param[in] address the address of the remote device.
+ * @return mtu size negotiated from remote device.
+ */
+uint16_t CALEServerGetMtuSize(const char* address);
#ifdef __cplusplus
} /* extern "C" */
#endif
Java_org_iotivity_ca_CaLeClientInterface_caManagerLeRemoteRssiCallback
(JNIEnv *, jobject, jobject, jint, jint);
+/*
+ * Class: org_iotivity_ca_CaLeClientInterface
+ * Method: caLeGattMtuChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+
#ifdef __cplusplus
}
#endif
Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback
(JNIEnv *, jobject, jint);
+/*
+ * Class: org_iotivity_ca_CaLeServerInterface
+ * Method: caLeGattServerMtuChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerMtuChangedCallback
+(JNIEnv *, jobject, jobject, jint);
#ifdef __cplusplus
}
} CABLEAdapter_t;
/**
+ * mtu size to use in fragmentation logic.
+ * default value is 20 byte.
+ */
+static uint16_t g_mtuSize = CA_DEFAULT_BLE_MTU_SIZE;
+/**
* Callback to provide the status of the network change to CA layer.
*/
static CAAdapterChangeCallback g_networkCallback = NULL;
return;
}
+ if (!bleData->remoteEndpoint)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid endpoint of bledata!");
+ return;
+ }
+
+#if defined(__TIZEN__) || defined(__ANDROID__)
+ // get MTU size
+ g_mtuSize = CALEServerGetMtuSize(bleData->remoteEndpoint->addr);
+#endif
+ OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize);
+
uint32_t midPacketCount = 0;
size_t remainingLen = 0;
size_t totalLength = 0;
CAResult_t result = CAGenerateVariableForFragmentation(bleData->dataLen,
&midPacketCount,
&remainingLen,
- &totalLength);
+ &totalLength,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
uint32_t length = 0;
uint32_t dataLen = 0;
- if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+ if (g_mtuSize > totalLength)
{
length = totalLength;
dataLen = bleData->dataLen;
}
else
{
- length = CA_SUPPORTED_BLE_MTU_SIZE;
- dataLen = CA_BLE_FIRST_SEGMENT_PAYLOAD_SIZE;
+ length = g_mtuSize;
+ dataLen = g_mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
}
result = CAMakeFirstDataSegment(dataSegment,
{
// Send the remaining header.
result = CAMakeRemainDataSegment(dataSegment,
- CA_BLE_NORMAL_SEGMENT_PAYLOAD_SIZE,
+ g_mtuSize - CA_BLE_HEADER_SIZE,
bleData->data,
bleData->dataLen,
index,
- dataHeader);
+ dataHeader,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
CAUpdateCharacteristicsToGattClient(
bleData->remoteEndpoint->addr,
dataSegment,
- CA_SUPPORTED_BLE_MTU_SIZE);
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
return;
}
- OIC_LOG_V(DEBUG,
- CALEADAPTER_TAG,
- "Server Sent Unicast %d Data - data length [%zu]",
- index + 1,
- CA_SUPPORTED_BLE_MTU_SIZE);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]",
+ g_mtuSize);
}
- if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+ if (remainingLen && (totalLength > g_mtuSize))
{
// send the last segment of the data (Ex: 22 bytes of 622
// bytes of data when MTU is 200)
bleData->data,
bleData->dataLen,
index,
- dataHeader);
+ dataHeader,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
return;
}
+ if (!bleData->remoteEndpoint)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid endpoint of bledata!");
+ return;
+ }
+
+#if defined(__TIZEN__) || defined(__ANDROID__)
+ // get MTU size
+ if (false == CALEClientIsConnected(bleData->remoteEndpoint->addr))
+ {
+ // triggering to gatt connect and MTU negotiation
+ CAResult_t res = CALEClientSendNegotiationMessage(
+ bleData->remoteEndpoint->addr);
+
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR,
+ CALEADAPTER_TAG,
+ "CALEClientSendNegotiationMessage has failed, result [%d]",
+ res);
+
+ g_errorHandler(bleData->remoteEndpoint,
+ bleData->data,
+ bleData->dataLen,
+ res);
+ return;
+ }
+ }
+ g_mtuSize = CALEClientGetMtuSize(bleData->remoteEndpoint->addr);
+#endif
+ OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize);
+
uint32_t midPacketCount = 0;
size_t remainingLen = 0;
size_t totalLength = 0;
CAResult_t result = CAGenerateVariableForFragmentation(bleData->dataLen,
&midPacketCount,
&remainingLen,
- &totalLength);
+ &totalLength,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
uint32_t length = 0;
uint32_t dataLen = 0;
- if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+ if (g_mtuSize > totalLength)
{
length = totalLength;
dataLen = bleData->dataLen;
}
else
{
- length = CA_SUPPORTED_BLE_MTU_SIZE;
- dataLen = CA_BLE_FIRST_SEGMENT_PAYLOAD_SIZE;
+ length = g_mtuSize;
+ dataLen = g_mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
}
result = CAMakeFirstDataSegment(dataSegment,
uint32_t index = 0;
if (NULL != bleData->remoteEndpoint) //Sending Unicast Data
{
- OIC_LOG(DEBUG, CALEADAPTER_TAG, "Client Sending Unicast Data");
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Unicast Data");
// Send the first segment with the header.
result =
CAUpdateCharacteristicsToGattServer(
for (index = 0; index < iter; index++)
{
result = CAMakeRemainDataSegment(dataSegment,
- CA_BLE_NORMAL_SEGMENT_PAYLOAD_SIZE,
+ g_mtuSize - CA_BLE_HEADER_SIZE,
bleData->data,
bleData->dataLen,
index,
- dataHeader);
+ dataHeader,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
result = CAUpdateCharacteristicsToGattServer(
bleData->remoteEndpoint->addr,
dataSegment,
- CA_SUPPORTED_BLE_MTU_SIZE,
+ g_mtuSize,
LE_UNICAST, 0);
if (CA_STATUS_OK != result)
}
OIC_LOG_V(DEBUG,
CALEADAPTER_TAG,
- "Client Sent Unicast %d Data - data length [%zu]",
+ "Client Sent Unicast %d Data - data(mtu) length [%zu]",
index + 1,
- CA_SUPPORTED_BLE_MTU_SIZE);
+ g_mtuSize);
}
- if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+ if (remainingLen && (totalLength > g_mtuSize))
{
// send the last segment of the data (Ex: 22 bytes of 622
// bytes of data when MTU is 200)
bleData->data,
bleData->dataLen,
index,
- dataHeader);
+ dataHeader,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
CAResult_t result = CAGenerateVariableForFragmentation(dataLen,
&midPacketCount,
&remainingLen,
- &totalLength);
+ &totalLength,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
uint32_t length = 0;
uint32_t dataOnlyLen = 0;
- if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+ if (g_mtuSize > totalLength)
{
length = totalLength;
dataOnlyLen = dataLen;
}
else
{
- length = CA_SUPPORTED_BLE_MTU_SIZE;
- dataOnlyLen = CA_BLE_FIRST_SEGMENT_PAYLOAD_SIZE;
+ length = g_mtuSize;
+ dataOnlyLen = g_mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
}
result = CAMakeFirstDataSegment(dataSegment,
for (uint32_t iter = 0; iter < dataLimit; iter++)
{
result = CAMakeRemainDataSegment(dataSegment,
- CA_BLE_NORMAL_SEGMENT_PAYLOAD_SIZE,
+ g_mtuSize - CA_BLE_HEADER_SIZE,
data,
dataLen,
iter,
- dataHeader);
+ dataHeader,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
result = CAUpdateCharacteristicsToAllGattClients(
dataSegment,
- CA_SUPPORTED_BLE_MTU_SIZE);
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
CALEDoEvents();
}
- if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+ if (remainingLen && (totalLength > g_mtuSize))
{
// send the last segment of the data
OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
data,
dataLen,
dataLimit,
- dataHeader);
+ dataHeader,
+ g_mtuSize);
if (CA_STATUS_OK != result)
{
return CA_STATUS_OK;
}
+bool CALEClientIsConnected(const char* address)
+{
+ //@Todo
+ //it should be implemented after update Tizen 3.0
+ return true;
+}
+
+uint16_t CALEClientGetMtuSize(const char* address)
+{
+ VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+ //@Todo
+ //it should be implemented after update Tizen 3.0
+ return CA_DEFAULT_BLE_MTU_SIZE;
+}
+CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize)
+{
+ VERIFY_NON_NULL(address, TAG, "address is null");
+ //@Todo
+ //it should be implemented after update Tizen 3.0
+ return CA_STATUS_OK;
+}
* @retval ::CA_STATUS_FAILED Operation failed.
*/
CAResult_t CALEGattDiscoverServices(const char *remoteAddress);
+
+/**
+ * check connection status.
+ * @param[in] address the address of the remote device.
+ * @return true or false.
+ */
+bool CALEClientIsConnected(const char* address);
+
+/**
+ * get MTU size.
+ * @param[in] address the address of the remote device.
+ * @return mtu size negotiated from remote device.
+ */
+uint16_t CALEClientGetMtuSize(const char* address);
+
+/**
+ * This function is used to set MTU size
+ * which negotiated between client and server device.
+ * @param[in] address remote address.
+ * @param[in] mtuSize MTU size.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize);
+
#endif /* TZ_BLE_CLIENT_H_ */
{
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_DEFAULT_BLE_MTU_SIZE);
+
+ unsigned int mtu = CA_DEFAULT_BLE_MTU_SIZE + CA_BLE_MTU_HEADER_SIZE;
+ int 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;
+ }
+ 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;
+}
+
*/
void CASetLEConnectionStateChangedCallback(CALEConnectionStateChangedCallback connStateCb);
+/**
+ * check connection status.
+ * @param[in] address the address of the remote device.
+ * @return true or false.
+ */
+bool CALEServerIsConnected(const char* address);
+
+/**
+ * get MTU size.
+ * @param[in] address the address of the remote device.
+ * @return mtu size negotiated from remote device.
+ */
+uint16_t CALEServerGetMtuSize(const char* address);
+
#endif /* TZ_BLE_SERVER_H_ */
#include "oic_string.h"
#include "oic_malloc.h"
#include "cafragmentation.h"
+#include "caleinterface.h"
#define CA_TRANSPORT_ADAPTER_SCOPE 1000
+#define CA_BLE_FIRST_SEGMENT_PAYLOAD_SIZE (((CA_DEFAULT_BLE_MTU_SIZE) - (CA_BLE_HEADER_SIZE)) \
+ - (CA_BLE_LENGTH_HEADER_SIZE))
+
class CATests : public testing::Test {
protected:
EXPECT_EQ(CA_STATUS_OK, CAGenerateVariableForFragmentation(dataLen,
&midPacketCount,
&remainingLen,
- &totalLength));
+ &totalLength,
+ CA_DEFAULT_BLE_MTU_SIZE));
uint8_t dataHeader[CA_BLE_HEADER_SIZE] = {0};
const uint8_t tmpSourcePort = 1;
data,
dataLen,
0,
- dataHeader));
+ dataHeader,
+ CA_DEFAULT_BLE_MTU_SIZE));
EXPECT_TRUE(dataSegment != NULL);
free(data);
EXPECT_EQ(CA_STATUS_OK, CAGenerateVariableForFragmentation(dataLen,
&midPacketCount,
&remainingLen,
- &totalLength));
+ &totalLength,
+ CA_SUPPORTED_BLE_MTU_SIZE));
uint8_t dataHeader[CA_BLE_HEADER_SIZE] = {0};
const uint8_t tmpSourcePort = 1;