#include "cathreadpool.h"
#include "caipadapter.h"
#include "cainterface.h"
+#include "caipinterface.h"
+#include <coap/utlist.h>
#ifdef RA_ADAPTER
#include "caraadapter.h"
#include "catcpadapter.h"
#endif
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#include "ca_adapter_net_ssl.h"
+#endif
+
#define TAG "OIC_CA_INF_CTR"
#define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
{OIC_LOG(ERROR, TAG, "memory error");goto memory_error_exit;} }
-
-
static CAConnectivityHandler_t *g_adapterHandler = NULL;
static uint32_t g_numberOfAdapters = 0;
static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
-static CANetworkChangeCallback g_networkChangeCallback = NULL;
-
static CAErrorHandleCallback g_errorHandleCallback = NULL;
+static struct CANetworkCallback_t * g_networkChangeCallbackList = NULL;
+
+/**
+ * network callback structure is handling
+ * for adapter state changed and connection state changed event.
+ */
+typedef struct CANetworkCallback_t {
+
+ /** Linked list; for multiple callback list.*/
+ struct CANetworkCallback_t * next;
+
+ /** Adapter state changed event callback. */
+ CAAdapterStateChangedCB adapter;
+
+ /** Connection state changed event callback. */
+ CAConnectionStateChangedCB conn;
+
+} CANetworkCallback_t;
+
static int CAGetAdapterIndex(CATransportAdapter_t cType)
{
for (uint32_t index=0 ; index < g_numberOfAdapters ; index++)
return index;
}
}
+ OIC_LOG_V(ERROR, TAG, "adapter info [%d]", g_numberOfAdapters);
return -1;
}
static void CARegisterCallback(CAConnectivityHandler_t handler)
{
- if(handler.startAdapter == NULL ||
+ if (handler.startAdapter == NULL ||
handler.startListenServer == NULL ||
handler.stopListenServer == NULL ||
handler.startDiscoveryServer == NULL ||
OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", handler.cType);
}
+/**
+ * Add a network callback from caller to the network callback list
+ *
+ * @param adapterCB adapter state changed callback
+ * @param connCB connection state changed callback
+ *
+ * @return
+ * CAResult_t
+ */
+static CAResult_t AddNetworkStateChangedCallback(CAAdapterStateChangedCB adapterCB,
+ CAConnectionStateChangedCB connCB)
+{
+ OIC_LOG(DEBUG, TAG, "Add NetworkStateChanged Callback");
+
+ if (!adapterCB || !connCB)
+ {
+ OIC_LOG(ERROR, TAG, "parameter is null");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ CANetworkCallback_t* callback = NULL;
+ LL_FOREACH(g_networkChangeCallbackList, callback)
+ {
+ if (callback && adapterCB == callback->adapter && connCB == callback->conn)
+ {
+ OIC_LOG(DEBUG, TAG, "this callback is already added");
+ return CA_STATUS_OK;
+ }
+ }
+
+ callback = (CANetworkCallback_t *) OICCalloc(1, sizeof(CANetworkCallback_t));
+ if (NULL == callback)
+ {
+ OIC_LOG(ERROR, TAG, "Memory allocation failed during registration");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ callback->adapter = adapterCB;
+ callback->conn = connCB;
+ LL_APPEND(g_networkChangeCallbackList, callback);
+ OIC_LOG_V(INFO, TAG, "Added NetworkStateChanged Callback [%p]", callback);
+
+ return CA_STATUS_OK;
+}
+
+/**
+ * Remove a network callback from the network callback list
+ *
+ * @param adapterCB adapter state changed callback
+ * @param connCB connection state changed callback
+ *
+ * @return
+ * CAResult_t
+ */
+static CAResult_t RemoveNetworkStateChangedCallback(CAAdapterStateChangedCB adapterCB,
+ CAConnectionStateChangedCB connCB)
+{
+ OIC_LOG(DEBUG, TAG, "Remove NetworkStateChanged Callback");
+
+ CANetworkCallback_t* callback = NULL;
+ LL_FOREACH(g_networkChangeCallbackList, callback)
+ {
+ if (callback && adapterCB == callback->adapter && connCB == callback->conn)
+ {
+ OIC_LOG(DEBUG, TAG, "remove specific callback");
+ LL_DELETE(g_networkChangeCallbackList, callback);
+ OICFree(callback);
+ return CA_STATUS_OK;
+ }
+ }
+ return CA_STATUS_OK;
+}
+
#ifdef RA_ADAPTER
CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
{
}
#endif
-static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
- const void *data, uint32_t dataLen)
+static CAResult_t CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
+ const void *data, uint32_t dataLen)
{
if (g_networkPacketReceivedCallback != NULL)
{
- g_networkPacketReceivedCallback(sep, data, dataLen);
+ return g_networkPacketReceivedCallback(sep, data, dataLen);
}
else
{
- OIC_LOG(ERROR, TAG, "network packet received callback is NULL!");
+ OIC_LOG(INFO, TAG, "network packet received callback is NULL!");
+ return CA_STATUS_OK;
+ }
+}
+
+static void CAAdapterChangedCallback(CATransportAdapter_t adapter, CANetworkStatus_t status)
+{
+ // Call the callback.
+ CANetworkCallback_t* callback = NULL;
+ LL_FOREACH(g_networkChangeCallbackList, callback)
+ {
+ if (callback && callback->adapter)
+ {
+ OIC_LOG_V(INFO, TAG, "IN application adapter changed callback [%p]", callback);
+ if (CA_INTERFACE_UP == status)
+ {
+ callback->adapter(adapter, true);
+ }
+ else if (CA_INTERFACE_DOWN == status)
+ {
+ callback->adapter(adapter, false);
+ }
+ OIC_LOG_V(INFO, TAG, "OUT application adapter changed callback [%p]", callback);
+ }
}
+ OIC_LOG_V(DEBUG, TAG, "[%d] adapter status is changed to [%d]", adapter, status);
}
-static void CANetworkChangedCallback(const CAEndpoint_t *info, CANetworkStatus_t status)
+#if defined(TCP_ADAPTER) || defined(EDR_ADAPTER) || defined(LE_ADAPTER)
+static void CAConnectionChangedCallback(const CAEndpoint_t *info, bool isConnected)
{
// Call the callback.
- if (g_networkChangeCallback != NULL)
+ CANetworkCallback_t* callback = NULL;
+ LL_FOREACH(g_networkChangeCallbackList, callback)
{
- g_networkChangeCallback(info, status);
+ if (callback && callback->conn)
+ {
+ callback->conn(info, isConnected);
+ }
}
+ OIC_LOG_V(DEBUG, TAG, "[%s] connection status is changed to [%d]", info->addr, isConnected);
}
+#endif
static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint,
const void *data, uint32_t dataLen,
}
}
-void CAInitializeAdapters(ca_thread_pool_t handle)
+void CAInitializeAdapters(ca_thread_pool_t handle, CATransportAdapter_t transportType)
{
- OIC_LOG(DEBUG, TAG, "initialize adapters..");
+ OIC_LOG_V(DEBUG, TAG, "initialize adapters %d", transportType);
+
+ // Initialize ssl adapter.
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ if (CA_STATUS_OK != CAinitSslAdapter())
+ {
+ OIC_LOG(ERROR, TAG, "Failed to init SSL adapter");
+ }
+#endif
// Initialize adapters and register callback.
#ifdef IP_ADAPTER
- CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- CAAdapterErrorHandleCallback, handle);
+ if ((transportType & CA_ADAPTER_IP) || (CA_DEFAULT_ADAPTER == transportType)
+ || (transportType == CA_ALL_ADAPTERS))
+ {
+ CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+ CAAdapterErrorHandleCallback, handle);
+ }
#endif /* IP_ADAPTER */
#ifdef EDR_ADAPTER
- CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- CAAdapterErrorHandleCallback, handle);
+ if ((transportType & CA_ADAPTER_RFCOMM_BTEDR) || (CA_DEFAULT_ADAPTER == transportType)
+ || (transportType == CA_ALL_ADAPTERS))
+ {
+ CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+ CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+ }
#endif /* EDR_ADAPTER */
#ifdef LE_ADAPTER
- CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- CAAdapterErrorHandleCallback, handle);
+ if ((transportType & CA_ADAPTER_GATT_BTLE) || (CA_DEFAULT_ADAPTER == transportType)
+ || (transportType == CA_ALL_ADAPTERS))
+ {
+ CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+ CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+ }
#endif /* LE_ADAPTER */
#ifdef RA_ADAPTER
- CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- handle);
+ if ((transportType & CA_ADAPTER_REMOTE_ACCESS) || (CA_DEFAULT_ADAPTER == transportType)
+ || (transportType == CA_ALL_ADAPTERS))
+ {
+ CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+ handle);
+ }
#endif /* RA_ADAPTER */
#ifdef TCP_ADAPTER
- CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- CAAdapterErrorHandleCallback, handle);
+ if ((transportType & CA_ADAPTER_TCP) || (CA_DEFAULT_ADAPTER == transportType)
+ || (transportType == CA_ALL_ADAPTERS))
+ {
+ CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+ CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+ }
#endif /* TCP_ADAPTER */
#ifdef NFC_ADAPTER
- CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- CAAdapterErrorHandleCallback, handle);
+ if ((transportType & CA_ADAPTER_NFC) || (CA_DEFAULT_ADAPTER == transportType)
+ || (transportType == CA_ALL_ADAPTERS))
+ {
+ CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+ CAAdapterErrorHandleCallback, handle);
+ }
#endif /* NFC_ADAPTER */
}
g_networkPacketReceivedCallback = callback;
}
-void CASetNetworkChangeCallback(CANetworkChangeCallback callback)
+void CASetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB,
+ CAConnectionStateChangedCB connCB)
{
- OIC_LOG(DEBUG, TAG, "Set network handle callback");
+ OIC_LOG(DEBUG, TAG, "Set network monitoring callback");
+ CAResult_t res = AddNetworkStateChangedCallback(adapterCB, connCB);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "AddNetworkStateChangedCallback has failed");
+ }
+}
- g_networkChangeCallback = callback;
+CAResult_t CAUnsetNetworkMonitorCallbacks(CAAdapterStateChangedCB adapterCB,
+ CAConnectionStateChangedCB connCB)
+{
+ OIC_LOG(DEBUG, TAG, "Unset network monitoring callback");
+ CAResult_t res = RemoveNetworkStateChangedCallback(adapterCB, connCB);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "RemoveNetworkStateChangedCallback has failed");
+ }
+ return res;
}
void CASetErrorHandleCallback(CAErrorHandleCallback errorCallback)
resSize += tempSize[index];
}
+#ifndef __TIZENRT__
OIC_LOG_V(DEBUG,
TAG,
- "%zu adapter network info size is %" PRIu32 " res:%d",
+ "%" PRIu32 " adapter network info size is %" PRIu32 " res:%d",
index,
tempSize[index],
res);
+#endif
}
}
if (resSize == 0)
{
+ OICFree(tempInfo);
+ OICFree(tempSize);
if (res == CA_ADAPTER_NOT_ENABLED || res == CA_NOT_SUPPORTED)
{
- OICFree(tempInfo);
- OICFree(tempSize);
return res;
}
- return CA_STATUS_FAILED;
+ else
+ {
+ return CA_STATUS_FAILED;
+ }
}
// #3. add data into result
return CA_MEMORY_ALLOC_FAILED;
}
-CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
+CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length,
+ CADataType_t dataType)
{
if (endpoint == NULL)
{
if (-1 == index)
{
- OIC_LOG(ERROR, TAG, "unknown transport type!");
+ OIC_LOG_V(ERROR, TAG, "unknown transport type[%d]", connType);
return CA_STATUS_INVALID_PARAM;
}
if (NULL != g_adapterHandler[index].sendData)
{
OIC_LOG(DEBUG, TAG, "unicast message to adapter");
- sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length);
+ sentDataLen = g_adapterHandler[index].sendData(endpoint, data, length, dataType);
}
if (sentDataLen != (int32_t)length)
return CA_STATUS_OK;
}
-CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length)
+CAResult_t CASendMulticastData(const CAEndpoint_t *endpoint, const void *data, uint32_t length,
+ CADataType_t dataType)
{
u_arraylist_t *list = CAGetSelectedNetworkList();
if (!list)
{
void* ptrType = u_arraylist_get(list, i);
- if(NULL == ptrType)
+ if (NULL == ptrType)
{
continue;
}
int index = CAGetAdapterIndex(connType);
if (0 > index)
- if (-1 == index)
{
- OIC_LOG(DEBUG, TAG, "unknown connectivity type!");
+ OIC_LOG(ERROR, TAG, "unknown connectivity type!");
continue;
}
return CA_MEMORY_ALLOC_FAILED;
}
memcpy(payload, data, length);
- sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length);
+ sentDataLen = g_adapterHandler[index].sendDataToAll(endpoint, payload, length, dataType);
OICFree(payload);
}
}
}
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ CAdeinitSslAdapter();
+#endif
+
OICFree(g_adapterHandler);
g_adapterHandler = NULL;
g_numberOfAdapters = 0;
}
#endif
+#ifdef IP_ADAPTER
+CAResult_t CASetMulticastTTL(size_t ttl)
+{
+ return CAIPSetMulticastTTL(ttl);
+}
+
+CAResult_t CAGetMulticastTTL(size_t *ttl)
+{
+ return CAIPGetMulticastTTL(ttl);
+}
+#endif
+
+#ifdef TCP_ADAPTER
+CAResult_t CADisconnectSession(const CAEndpoint_t *endpoint)
+{
+ return CATCPDisconnectSession(endpoint);
+}
+#endif
+
+#ifdef LE_ADAPTER
+void CAStartGattServer()
+{
+ CALEStartGattServer();
+}
+
+void CAStopGattServer()
+{
+ CALEStopGattServer();
+}
+#endif