#define CA_COAP 5683
#define CA_SECURE_COAP 5684
-#define INTERFACE_NAME_MAX 16
-
-typedef struct
-{
- char name[INTERFACE_NAME_MAX];
- uint32_t index;
- uint32_t flags;
- uint16_t family;
- char addr[MAX_ADDR_STR_SIZE_CA];
-} CAInterface_t;
-
-
-/**
- * Callback to be notified when IP adapter connection state changes.
- *
- * @param[in] adapter Transport adapter.
- * @param[in] status Connection status either ::CA_INTERFACE_UP or ::CA_INTERFACE_DOWN.
- * @see CAIPSetConnectionStateChangeCallback() for registration.
- */
-typedef void (*CAIPConnectionStateChangeCallback)(CATransportAdapter_t adapter, CANetworkStatus_t status);
-
-/**
- * Set callback for receiving local IP adapter connection status.
- *
- * @param[in] adapter Callback to be notified when IP adapter connection state changes.
- */
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback);
-
-/**
- * Set callback for receiving local IP adapter connection status.
- *
- * @param[in] callback Callback to be notified when IP adapter connection state changes.
- */
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback);
-
-/**
- * Get a list of CAInterface_t items.
- *
- * @return List of CAInterface_t items.
- */
-u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
-
-/**
- * Find a new network interface.
- *
- * @return Description of interface (or NULL if no change)
- */
-CAInterface_t *CAFindInterfaceChange();
/**
* Let the network monitor update the polling interval.
*/
void CAWakeUpForChange();
-/**
- * Start network monitor.
- *
- * @return ::CA_STATUS_OK or Appropriate error code.
- */
-CAResult_t CAIPStartNetworkMonitor();
-
-/**
- * Stops network monitor.
- *
- * @return ::CA_STATUS_OK or Appropriate error code.
- */
-CAResult_t CAIPStopNetworkMonitor();
-
/**
* Set callback for error handling.
*
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file caipnwmonitor.h
+ * This file provides APIs IP network monitor modules.
+ */
+
+#ifndef CA_IP_NW_INTERFACE_H_
+#define CA_IP_NW_INTERFACE_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define INTERFACE_NAME_MAX 16
+
+/**
+ * Callback to be notified when IP adapter network state changes.
+ *
+ * @param[in] adapter Transport adapter.
+ * @param[in] status Connection status either ::CA_INTERFACE_UP or ::CA_INTERFACE_DOWN.
+ * @see CAIPSetConnectionStateChangeCallback() for registration.
+ */
+typedef void (*CAIPAdapterStateChangeCallback)(CATransportAdapter_t adapter,
+ CANetworkStatus_t status);
+
+typedef struct
+{
+ char name[INTERFACE_NAME_MAX];
+ uint32_t index;
+ uint32_t flags;
+ uint16_t family;
+ char addr[MAX_ADDR_STR_SIZE_CA];
+} CAInterface_t;
+
+typedef struct CAIPCBData_t
+{
+ struct CAIPCBData_t *next;
+ CATransportAdapter_t adapter;
+ CAIPAdapterStateChangeCallback callback;
+} CAIPCBData_t;
+
+/**
+ * Set callback for receiving local IP/TCP adapter connection status.
+ *
+ * @param[in] callback Callback to be notified when IP/TCP adapter connection state changes.
+ * @param[in] adapter Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter);
+
+/**
+ * Unset callback for receiving local IP/TCP adapter connection status.
+ *
+ * @param[in] adapter Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter);
+
+/**
+ * Get a list of CAInterface_t items.
+ *
+ * @param[in] desiredIndex Network interface index.
+ * @return List of CAInterface_t items.
+ */
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex);
+
+/**
+ * Find a new network interface.
+ *
+ * @return Description of interface (or NULL if no change)
+ */
+CAInterface_t *CAFindInterfaceChange();
+
+/**
+ * Start network monitor.
+ *
+ * @param[in] callback Callback to be notified when IP/TCP adapter connection state changes.
+ * @param[in] adapter Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter);
+
+/**
+ * Stops network monitor.
+ *
+ * @param[in] adapter Transport adapter.
+ * @return ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CA_IP_NW_INTERFACE_H_ */
#include <arpa/inet.h>
#include <linux/if.h>
+#include <coap/utlist.h>
#include "caadapterutils.h"
+#include "caipnwmonitor.h"
#include "logger.h"
#include "oic_malloc.h"
#include "oic_string.h"
#define TAG "OIC_CA_IP_MONITOR"
#define NETLINK_MESSAGE_LENGTH (4096)
-static CAIPConnectionStateChangeCallback g_networkChangeCallback;
+/**
+ * Used to storing adapter changes callback interface.
+ */
+static struct CAIPCBData_t *g_adapterCallbackList = NULL;
+/**
+ * Create new interface item to add in activated interface list.
+ * @param[in] index Network interface index number.
+ * @param[in] name Network interface name.
+ * @param[in] family Network interface family type.
+ * @param[in] addr New interface address.
+ * @param[in] flags The active flag word of a device.
+ * @return CAInterface_t objects.
+ */
static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
const char *addr, int flags);
+/**
+ * Add created new interface item activated interface list.
+ * @param[in] iflist Network interface array list.
+ * @param[in] index Network interface index number.
+ * @param[in] name Network interface name.
+ * @param[in] family Network interface family type.
+ * @param[in] addr New interface address.
+ * @param[in] flags The active flag word of a device.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
const char *name, int family, const char *addr, int flags);
+/**
+ * Initialize JNI interface.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
CAResult_t CAIPJniInit();
/**
- * destroy JNI interface.
+ * Destroy JNI interface.
* @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
*/
static CAResult_t CAIPDestroyJniInterface();
#define MAX_INTERFACE_INFO_LENGTH 1024 // allows 32 interfaces from SIOCGIFCONF
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
{
- return CAIPJniInit();
+ CAResult_t res = CAIPJniInit();
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "failed to initialize ip jni interface");
+ return res;
+ }
+
+ return CAIPSetNetworkMonitorCallback(callback, adapter);
}
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
{
- return CAIPDestroyJniInterface();
+ CAIPUnSetNetworkMonitorCallback(adapter);
+
+ // if there is no callback to pass the changed status, stop monitoring.
+ if (!g_adapterCallbackList)
+ {
+ return CAIPDestroyJniInterface();
+ }
+
+ return CA_STATUS_OK;
}
int CAGetPollingInterval(int interval)
return interval;
}
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
{
- g_networkChangeCallback = callback;
+ CAIPCBData_t *cbitem = NULL;
+ LL_FOREACH(g_adapterCallbackList, cbitem)
+ {
+ if (cbitem && cbitem->adapter)
+ {
+ cbitem->callback(cbitem->adapter, status);
+ }
+ }
+}
+
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
+{
+ if (!callback)
+ {
+ OIC_LOG(ERROR, TAG, "callback is null");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ CAIPCBData_t *cbitem = NULL;
+ LL_FOREACH(g_adapterCallbackList, cbitem)
+ {
+ if (cbitem && adapter == cbitem->adapter && callback == cbitem->callback)
+ {
+ OIC_LOG(DEBUG, TAG, "this callback is already added");
+ return CA_STATUS_OK;
+ }
+ }
+
+ cbitem = (CAIPCBData_t *)OICCalloc(1, sizeof(*cbitem));
+ if (!cbitem)
+ {
+ OIC_LOG(ERROR, TAG, "Malloc failed");
+ return CA_STATUS_FAILED;
+ }
+
+ cbitem->adapter = adapter;
+ cbitem->callback = callback;
+ LL_APPEND(g_adapterCallbackList, cbitem);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
+{
+ CAIPCBData_t *cbitem = NULL;
+ CAIPCBData_t *tmpCbitem = NULL;
+ LL_FOREACH_SAFE(g_adapterCallbackList, cbitem, tmpCbitem)
+ {
+ if (cbitem && adapter == cbitem->adapter)
+ {
+ OIC_LOG(DEBUG, TAG, "remove specific callback");
+ LL_DELETE(g_adapterCallbackList, cbitem);
+ OICFree(cbitem);
+ return CA_STATUS_OK;
+ }
+ }
+ return CA_STATUS_OK;
}
CAInterface_t *CAFindInterfaceChange()
(void)class;
OIC_LOG(DEBUG, TAG, "Wifi is in Activated State");
- g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_UP);
+ CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
}
JNIEXPORT void JNICALL
(void)class;
OIC_LOG(DEBUG, TAG, "Wifi is in Deactivated State");
- g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_DOWN);
+ CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
}
#include "cacommon.h"
#include "caadapterinterface.h"
#include "caipadapter.h"
+#include "caipnwmonitor.h"
#include "caipadapterutils_eth.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
#include "logger.h"
#include "cacommon.h"
#include "caipadapter.h"
+#include "caipnwmonitor.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
#include "oic_string.h"
// defined & used (as-is defined in the linux socket headers).
#define AF_INET (2)
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
{
return CA_STATUS_OK;
}
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
{
return CA_STATUS_OK;
}
#include "logger.h"
#include "cacommon.h"
#include "caipadapter.h"
+#include "caipnwmonitor.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
#include "oic_string.h"
// defined & used (as-is defined in the linux socket headers).
#define AF_INET (2)
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
{
return CA_STATUS_OK;
}
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
{
return CA_STATUS_OK;
}
#include "cainterface.h"
#include "caadapterinterface.h"
#include "caipadapter.h"
+#include "caipnwmonitor.h"
#include "caipadapterutils_eth.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
#include "cainterface.h"
#include "caadapterinterface.h"
#include "caipadapter.h"
+#include "caipnwmonitor.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
#include "oic_string.h"
#include <string.h>
#include <stdint.h>
+#include "caipnwmonitor.h"
#include "caipinterface.h"
#include "caqueueingthread.h"
#include "caadapterutils.h"
#endif // SINGLE_THREAD
-void CAIPConnectionStateCB(CATransportAdapter_t adapter, CANetworkStatus_t status)
+void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
{
if (g_networkChangeCallback)
{
CAIPSetErrorHandler(CAIPErrorHandler);
CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
-#ifndef SINGLE_THREAD
- CAIPSetConnectionStateChangeCallback(CAIPConnectionStateCB);
-#endif
+
#ifdef __WITH_DTLS__
if (CA_STATUS_OK != CAinitSslAdapter())
{
caglobals.ip.u4.port = caglobals.ports.udp.u4;
caglobals.ip.u4s.port = caglobals.ports.udp.u4s;
- CAIPStartNetworkMonitor();
+ CAIPStartNetworkMonitor(CAIPAdapterHandler, CA_ADAPTER_IP);
#ifdef SINGLE_THREAD
uint16_t unicastPort = 55555;
// Address is hardcoded as we are using Single Interface
}
#endif
- CAIPStopNetworkMonitor();
+ CAIPStopNetworkMonitor(CA_ADAPTER_IP);
CAIPStopServer();
//Re-initializing the Globals to start them again
CAInitializeIPGlobals();
#include <coap/pdu.h>
#include "caipinterface.h"
+#include "caipnwmonitor.h"
#include "caadapterutils.h"
#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
#include "ca_adapter_net_ssl.h"
g_packetReceivedCallback = callback;
}
-void CAIPSetConnectionStateChangeCallback(CAIPConnectionStateChangeCallback callback)
-{
- CAIPSetNetworkMonitorCallback(callback);
-}
-
static void sendData(int fd, const CAEndpoint_t *endpoint,
const void *data, uint32_t dlen,
const char *cast, const char *fam)
#endif
#include "camutex.h"
+#include "caipnwmonitor.h"
#include "caadapterutils.h"
#include "logger.h"
#include "oic_malloc.h"
#include "oic_string.h"
+#include <coap/utlist.h>
#define TAG "OIC_CA_IP_MONITOR"
*/
static u_arraylist_t *g_netInterfaceList = NULL;
-static CAIPConnectionStateChangeCallback g_networkChangeCallback = NULL;
+/**
+ * Used to storing adapter changes callback interface.
+ */
+static struct CAIPCBData_t *g_adapterCallbackList = NULL;
+/**
+ * Initialize the network interface monitoring list.
+ */
static CAResult_t CAIPInitializeNetworkMonitorList();
+
+/**
+ * Destroy the network interface monitoring list.
+ */
static void CAIPDestroyNetworkMonitorList();
+
+/**
+ * Compare the interface with the already added interface in list.
+ */
+static bool CACmpNetworkList(uint32_t ifiindex);
+
+/**
+ * Add new network interface in list.
+ */
+static CAResult_t CAAddNetworkMonitorList(CAInterface_t *ifitem);
+
+/**
+ * Remove network interace from list.
+ */
+static void CARemoveNetworkMonitorList(int ifiindex);
+
+/**
+ * Pass the changed network status through the stored callback.
+ */
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status);
+
+/**
+ * Create new interface item.
+ */
static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
const char *addr, int flags);
uint32_t list_length = u_arraylist_length(g_netInterfaceList);
for (uint32_t list_index = 0; list_index < list_length; list_index++)
{
- CAInterface_t *currItem = (CAInterface_t *) u_arraylist_get(g_netInterfaceList, list_index);
+ CAInterface_t *currItem = (CAInterface_t *) u_arraylist_get(g_netInterfaceList,
+ list_index);
if (currItem->index == ifiindex)
{
ca_mutex_unlock(g_networkMonitorContextMutex);
return;
}
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
{
- return CAIPInitializeNetworkMonitorList();
+ CAResult_t res = CAIPInitializeNetworkMonitorList();
+ if (CA_STATUS_OK == res)
+ {
+ return CAIPSetNetworkMonitorCallback(callback, adapter);
+ }
+ return res;
}
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
{
CAIPDestroyNetworkMonitorList();
- return CA_STATUS_OK;
+ return CAIPUnSetNetworkMonitorCallback(adapter);
}
int CAGetPollingInterval(int interval)
return interval;
}
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
{
- g_networkChangeCallback = callback;
+ CAIPCBData_t *cbitem = NULL;
+ LL_FOREACH(g_adapterCallbackList, cbitem)
+ {
+ if (cbitem && cbitem->adapter)
+ {
+ cbitem->callback(cbitem->adapter, status);
+ }
+ }
+}
+
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
+{
+ if (!callback)
+ {
+ OIC_LOG(ERROR, TAG, "callback is null");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ CAIPCBData_t *cbitem = NULL;
+ LL_FOREACH(g_adapterCallbackList, cbitem)
+ {
+ if (cbitem && adapter == cbitem->adapter && callback == cbitem->callback)
+ {
+ OIC_LOG(DEBUG, TAG, "this callback is already added");
+ return CA_STATUS_OK;
+ }
+ }
+
+ cbitem = (CAIPCBData_t *)OICCalloc(1, sizeof(*cbitem));
+ if (!cbitem)
+ {
+ OIC_LOG(ERROR, TAG, "Malloc failed");
+ return CA_STATUS_FAILED;
+ }
+
+ cbitem->adapter = adapter;
+ cbitem->callback = callback;
+ LL_APPEND(g_adapterCallbackList, cbitem);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
+{
+ CAIPCBData_t *cbitem = NULL;
+ CAIPCBData_t *tmpCbitem = NULL;
+ LL_FOREACH_SAFE(g_adapterCallbackList, cbitem, tmpCbitem)
+ {
+ if (cbitem && adapter == cbitem->adapter)
+ {
+ OIC_LOG(DEBUG, TAG, "remove specific callback");
+ LL_DELETE(g_adapterCallbackList, cbitem);
+ OICFree(cbitem);
+ return CA_STATUS_OK;
+ }
+ }
+ return CA_STATUS_OK;
}
static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
if (isFound)
{
CARemoveNetworkMonitorList(ifiIndex);
- if (g_networkChangeCallback)
- {
- g_networkChangeCallback(CA_ADAPTER_IP ,CA_INTERFACE_DOWN);
- }
+ CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
}
continue;
}
u_arraylist_destroy(iflist);
return NULL;
}
- OIC_LOG(DEBUG, TAG, "Got ifaddrs");
struct ifaddrs *ifa = NULL;
for (ifa = ifp; ifa; ifa = ifa->ifa_next)
OICFree(newifitem);
goto exit;
}
- if (g_networkChangeCallback)
- {
- g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_UP);
- }
+ CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
OIC_LOG_V(DEBUG, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);
}
}
#include <arpa/inet.h>
#include <netinet/in.h>
+#include "caipnwmonitor.h"
#include "caadapterutils.h"
#include "logger.h"
#include "oic_malloc.h"
#include "oic_string.h"
+#include <coap/utlist.h>
#define TAG "IP_MONITOR"
#define NETLINK_MESSAGE_LENGTH (4096)
-static CAIPConnectionStateChangeCallback g_networkChangeCallback;
+/**
+ * Used to storing adapter changes callback interface.
+ */
+static struct CAIPCBData_t *g_adapterCallbackList = NULL;
+/**
+ * Create new interface item.
+ */
static CAInterface_t *CANewInterfaceItem(int index, char *name, int family,
const char *addr, int flags);
+/**
+ * Add new network interface in list.
+ */
static CAResult_t CAAddInterfaceItem(u_arraylist_t *iflist, int index,
char *name, int family, const char *addr, int flags);
+/**
+ * Pass the changed network status through the stored callback.
+ */
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status);
+
+/**
+ * Callback function to received connection state changes.
+ */
static void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
void *userData);
+/**
+ * Callback function to received device state changes.
+ */
static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
return interval;
}
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
{
- g_networkChangeCallback = callback;
+ CAIPCBData_t *cbitem = NULL;
+ LL_FOREACH(g_adapterCallbackList, cbitem)
+ {
+ if (cbitem && cbitem->adapter)
+ {
+ cbitem->callback(cbitem->adapter, status);
+ }
+ }
+}
+
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
+{
+ if (!callback)
+ {
+ OIC_LOG(ERROR, TAG, "callback is null");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ CAIPCBData_t *cbitem = NULL;
+ LL_FOREACH(g_adapterCallbackList, cbitem)
+ {
+ if (cbitem && adapter == cbitem->adapter && callback == cbitem->callback)
+ {
+ OIC_LOG(DEBUG, TAG, "this callback is already added");
+ return CA_STATUS_OK;
+ }
+ }
+
+ cbitem = (CAIPCBData_t *)OICCalloc(1, sizeof(*cbitem));
+ if (!cbitem)
+ {
+ OIC_LOG(ERROR, TAG, "Malloc failed");
+ return CA_STATUS_FAILED;
+ }
+
+ cbitem->adapter = adapter;
+ cbitem->callback = callback;
+ LL_APPEND(g_adapterCallbackList, cbitem);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
+{
+ CAIPCBData_t *cbitem = NULL;
+ CAIPCBData_t *tmpCbitem = NULL;
+ LL_FOREACH_SAFE(g_adapterCallbackList, cbitem, tmpCbitem)
+ {
+ if (cbitem && adapter == cbitem->adapter)
+ {
+ OIC_LOG(DEBUG, TAG, "remove specific callback");
+ LL_DELETE(g_adapterCallbackList, cbitem);
+ OICFree(cbitem);
+ return CA_STATUS_OK;
+ }
+ }
+ return CA_STATUS_OK;
}
CAInterface_t *CAFindInterfaceChange()
return foundNewInterface;
}
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
{
OIC_LOG(DEBUG, TAG, "IN");
- // Initialize Wifi service
- wifi_error_e ret = wifi_initialize();
- if (WIFI_ERROR_NONE != ret)
- {
- OIC_LOG(ERROR, TAG, "wifi_initialize failed");
- return CA_STATUS_FAILED;
- }
-
- // Set callback for receiving state changes
- ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
- if (WIFI_ERROR_NONE != ret)
- {
- OIC_LOG(ERROR, TAG, "wifi_set_device_state_changed_cb failed");
- return CA_STATUS_FAILED;
- }
-
- // Set callback for receiving connection state changes
- ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
- if (WIFI_ERROR_NONE != ret)
+ if (!g_adapterCallbackList)
{
- OIC_LOG(ERROR, TAG, "wifi_set_connection_state_changed_cb failed");
- return CA_STATUS_FAILED;
+ // Initialize Wifi service
+ wifi_error_e ret = wifi_initialize();
+ if (WIFI_ERROR_NONE != ret)
+ {
+ OIC_LOG(ERROR, TAG, "wifi_initialize failed");
+ return CA_STATUS_FAILED;
+ }
+
+ // Set callback for receiving state changes
+ ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
+ if (WIFI_ERROR_NONE != ret)
+ {
+ OIC_LOG(ERROR, TAG, "wifi_set_device_state_changed_cb failed");
+ return CA_STATUS_FAILED;
+ }
+
+ // Set callback for receiving connection state changes
+ ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
+ if (WIFI_ERROR_NONE != ret)
+ {
+ OIC_LOG(ERROR, TAG, "wifi_set_connection_state_changed_cb failed");
+ return CA_STATUS_FAILED;
+ }
}
- OIC_LOG(DEBUG, TAG, "OUT");
- return CA_STATUS_OK;
+ return CAIPSetNetworkMonitorCallback(callback, adapter);
}
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
{
OIC_LOG(DEBUG, TAG, "IN");
- // Reset callback for receiving state changes
- wifi_error_e ret = wifi_unset_device_state_changed_cb();
- if (WIFI_ERROR_NONE != ret)
- {
- OIC_LOG(ERROR, TAG, "wifi_unset_device_state_changed_cb failed");
- }
-
- // Reset callback for receiving connection state changes
- ret = wifi_unset_connection_state_changed_cb();
- if (WIFI_ERROR_NONE != ret)
- {
- OIC_LOG(ERROR, TAG, "wifi_unset_connection_state_changed_cb failed");
- }
-
- // Deinitialize Wifi service
- ret = wifi_deinitialize();
- if (WIFI_ERROR_NONE != ret)
+ CAIPUnSetNetworkMonitorCallback(adapter);
+ if (!g_adapterCallbackList)
{
- OIC_LOG(ERROR, TAG, "wifi_deinitialize failed");
+ // Reset callback for receiving state changes
+ wifi_error_e ret = wifi_unset_device_state_changed_cb();
+ if (WIFI_ERROR_NONE != ret)
+ {
+ OIC_LOG(ERROR, TAG, "wifi_unset_device_state_changed_cb failed");
+ }
+
+ // Reset callback for receiving connection state changes
+ ret = wifi_unset_connection_state_changed_cb();
+ if (WIFI_ERROR_NONE != ret)
+ {
+ OIC_LOG(ERROR, TAG, "wifi_unset_connection_state_changed_cb failed");
+ }
+
+ // Deinitialize Wifi service
+ ret = wifi_deinitialize();
+ if (WIFI_ERROR_NONE != ret)
+ {
+ OIC_LOG(ERROR, TAG, "wifi_deinitialize failed");
+ }
}
- OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
if (WIFI_CONNECTION_STATE_CONNECTED == state)
{
- g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_UP);
+ CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
}
else
{
- g_networkChangeCallback(CA_ADAPTER_IP, CA_INTERFACE_DOWN);
+ CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
}
OIC_LOG(DEBUG, TAG, "OUT");
#include "logger.h"
#include "oic_malloc.h"
#include "oic_string.h"
+#include "caipnwmonitor.h"
#define TAG "IP_MONITOR"
* @todo Implement network interface monitoring in case the IP changes.
* Not critical for win32 bring-up.
*/
-CAResult_t CAIPStartNetworkMonitor()
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
{
return CA_STATUS_OK;
}
* @todo Implement network interface monitoring in case the IP changes.
* Not critical for win32 bring-up.
*/
-CAResult_t CAIPStopNetworkMonitor()
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
+
{
return CA_STATUS_OK;
}
* @todo Implement network interface monitoring.
* Not critical for win32 bring-up.
*/
-void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+ CATransportAdapter_t adapter)
{
- return;
+ return CA_NOT_SUPPORTED;
}
bool IsValidAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex, uint16_t family)
#include <inttypes.h>
#include "cainterface.h"
+#include "caipnwmonitor.h"
#include "catcpadapter.h"
#include "catcpinterface.h"
#include "caqueueingthread.h"
g_connKeepAliveCallback = ConnHandler;
}
+void CATCPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
+{
+ if (g_networkChangeCallback)
+ {
+ g_networkChangeCallback(adapter, status);
+ }
+
+ if (CA_INTERFACE_DOWN == status)
+ {
+ OIC_LOG(DEBUG, TAG, "Network status is down, close all session");
+ CATCPStopServer();
+ }
+ else if (CA_INTERFACE_UP == status)
+ {
+ OIC_LOG(DEBUG, TAG, "Network status is up, create new socket for listening");
+
+ CAResult_t ret = CA_STATUS_FAILED;
+#ifndef SINGLE_THREAD
+ ret = CATCPStartServer((const ca_thread_pool_t)caglobals.tcp.threadpool);
+#else
+ ret = CATCPStartServer();
+#endif
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(DEBUG, TAG, "CATCPStartServer failed[%d]", ret);
+ }
+ }
+}
+
static void CAInitializeTCPGlobals()
{
caglobals.tcp.ipv4.fd = -1;
{
OIC_LOG(DEBUG, TAG, "IN");
- // Specific the port number received from application.
+ // Start network monitoring to receive adapter status changes.
+ CAIPStartNetworkMonitor(CATCPAdapterHandler, CA_ADAPTER_TCP);
+
+ // Set the port number received from application.
caglobals.tcp.ipv4.port = caglobals.ports.tcp.u4;
caglobals.tcp.ipv6.port = caglobals.ports.tcp.u6;
OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
return CA_STATUS_FAILED;
}
-
#else
CAResult_t ret = CATCPStartServer();
if (CA_STATUS_OK != ret)
CAResult_t CAStopTCP()
{
+ CAIPStopNetworkMonitor(CA_ADAPTER_TCP);
+
#ifndef SINGLE_THREAD
if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
{
CAQueueingThreadStop(g_sendQueueHandle);
}
+ CATCPDeinitializeQueueHandles();
#endif
CATCPStopServer();
void CATerminateTCP()
{
+ CAStopTCP();
CATCPSetPacketReceiveCallback(NULL);
-
-#ifndef SINGLE_THREAD
- CATCPDeinitializeQueueHandles();
-#endif
}
void CATCPSendDataThread(void *threadData)
#endif
#include "catcpinterface.h"
+#include "caipnwmonitor.h"
#include <coap/pdu.h>
#include "caadapterutils.h"
#include "camutex.h"
svritem = (CATCPSessionInfo_t *) u_arraylist_get(caglobals.tcp.svrlist, i);
if (svritem && svritem->fd >= 0)
{
+#ifdef __WITH_TLS__
+ if (CA_STATUS_OK != CAcloseSslConnection(&svritem->sep.endpoint))
+ {
+ OIC_LOG(ERROR, TAG, "Failed to close TLS session");
+ }
+#endif
shutdown(svritem->fd, SHUT_RDWR);
close(svritem->fd);
-
OICFree(svritem->data);
svritem->data = NULL;
+
+ // pass the connection information to CA Common Layer.
+ if (g_connectionCallback)
+ {
+ g_connectionCallback(&(svritem->sep.endpoint), false);
+ }
}
}
u_arraylist_destroy(caglobals.tcp.svrlist);
+ caglobals.tcp.svrlist = NULL;
ca_mutex_unlock(g_mutexObjectList);
}