--- /dev/null
+Project Name: IoTivity
+Release Version No: CA_v0.61
+API Version: CA_v0.8
+
+Release Description:
+Connectivity Abstraction provides a unified approach to send different OIC messages across multiple transports.
+
+Supported Platform OS:
+1) Ubuntu 12.0.4 and above:
+ Connectivity : WIFI, ETHERNET
+ Security : DTLS for WIFI
+2) Tizen 2.3
+ Connectivity : WIFI, EDR, BLE(1:1).
+3) Arduino Mega
+ Connectivity : WIFI, ETH,BLE
+4) Android 5.0s
+ Connectivity : WIFI, BLE
+
+Preconditions:
+1)gcc 4.6.3 and above.
+2)glib library (sudo apt-get install libglib2.0-dev) for linux, tizen and android devices
+3)libcoap.a library ( do make @lib/libcoap-4.1.1)
+4)tinyDTLS library for DTLS enabled applications( enable DTLS = 1 in makefile @connectivity\build/linux)
+5)Ethernet, BLE, TimedActions, Timer libraries for arduino support.
+
+Scope of Release:
+1. Supported APIs ( please check below APIs)
+2. Samples to test for Supported APIs.
+3. OIC Coding guidelines followed based on the current CSDK source.
+4. Multi-Threaded, Single threaded Connectivity abstraction.
+5. Executed Open Source Verification and Prevent analysis.
+Type of Release: Source
+The following Connectivity Abstraction API features are supported in this release:
+
+Supported APIs
+CAInitialize()
+CATerminate()
+CAStartListeningServer()
+CAStartDiscoveryServer()
+CARegisterHandler()
+CAhandleRequestResponse()
+FindResource()
+SendRequest()
+SendResponse()
+SelectNetwork()
+UnselectNetwork()
+SendNotification()
+AdvertizeResource()
+CAGenerateToken()
+CADestryToken()
+CAGetNetworkInfo()
+
+
+Known and Open Issues:
+1) OIC Log, OIC Malloc will be removed once name changes applied to OIC Bases code.
+2) Tizen platform BLE stack is not stable. So we may see random crashes.
+3) GetDtlsPskCredentials is implemented in sample which will be replace by security call during integration
+
+How to Build for Linux:
+Follow below steps to execute CA Client / server in different systems
+Step 1: Build Libcoap library
+Make File Location @connectivity\lib\libcoap-4.1.1
+Step 2: Build CA library
+Make File Location @connectivity\build\linux
+Step 3: Samples
+Make File Location @connectivity\samples\linux
+
+Execution:
+linux$ export LD_LIBRARY_PATH=../../build/out/
+linux$ ./out/sample_main
+
+
+Follow below sequence to test
+
+Client Option: c
+Server Option: s
+
+Client Option: f (provide a/light)
+Server Option: h (will pick from queue and send response)
+Client Option: h (to pick server response)
+
+Client Option: r (provide “ServerIP:5383/a/request”)
+Server Option: h (will pick from queue and send response)
+Client Option: h (to pick server response)
+
+Server Option: a
+Client Option: h (to pick server response)
+
+Server Option: b (provide ServerIP:5383/a/notify)
+Client Option: h (to pick server response)
+
+Client: Server side: n for network selection (WIFI enabled by default)
+
+
+How to Build for Linux/DTLS:
+sudo ./sample.sh WITH_DTLS @@connectivity\samples\linux
#define CA_OPTION_OBSERVE 6
/**
+ @brief Max length of ID
+ */
+#define DTLS_PSK_ID_LEN 16
+
+/**
+ @brief Max length of PSK
+ */
+#define DTLS_PSK_PSK_LEN 16
+
+/**
+ @brief version
+ */
+#define DtlsPskCredsBlobVer_1 1
+
+/**
+ @brief current version
+ */
+#define DtlsPskCredsBlobVer_CurrentVersion DtlsPskCredsBlobVer_1
+
+
+/**
@brief Payload information from resource model
*/
-typedef char* CAPayload_t;
+typedef char *CAPayload_t;
/**
@brief URI for the OIC base.CA considers relative URI as the URI.
*/
-typedef char* CAURI_t;
+typedef char *CAURI_t;
/**
@brief Token information for mapping the request and responses by resource model
*/
-typedef char* CAToken_t;
+typedef char *CAToken_t;
/**
@brief Boolean value used for specifying the success or failure
CAAddress_t addressInfo;
/** Connectivity of the endpoint**/
CAConnectivityType_t connectivityType;
+ /** Secure connection**/
+ CABool_t isSecured;
} CARemoteEndpoint_t;
CAAddress_t addressInfo;
/** Connectivity type that localconnectivity avaialble **/
CAConnectivityType_t type;
+ /** Secure connection**/
+ CABool_t isSecured;
} CALocalConnectivity_t;
/**
CA_DESTINATION_DISCONNECTED,
CA_STATUS_FAILED,
CA_NOT_SUPPORTED
-/* Result code - END HERE */
+ /* Result code - END HERE */
} CAResult_t;
/**
CA_BAD_REQ = 400,
CA_BAD_OPT = 402,
CA_NOT_FOUND = 404
-/* Response status code - END HERE */
+ /* Response status code - END HERE */
} CAResponseResult_t;
/**
{
/**Qos for the request **/
CAMessageType_t type;
+ /** Message id.
+ * if message id is zero, it will generated by CA inside.
+ * otherwise, you can use it.**/
+ uint16_t messageId;
/** Token for CA**/
CAToken_t token;
/** Header Options for the request **/
- CAHeaderOption_t * options;
+ CAHeaderOption_t *options;
/** Number of Header options**/
uint8_t numOptions;
/** payload of the request **/
CAInfo_t info;
} CAResponseInfo_t;
+/**
+ * Credentials for a device. Includes identity and the associated PSK.
+ */
+typedef struct
+{
+ unsigned char clientIdentity[DTLS_PSK_ID_LEN];
+ unsigned char rsClientPsk[DTLS_PSK_PSK_LEN];
+} CADtlsPskCreds_t;
+
+/**
+ * Binary blob containing device identity and the credentials for all devices
+ * trusted by this device.
+ */
+typedef struct
+{
+ uint16_t blobVer; /**< version of the blob */
+ uint16_t reserved; /**< reserved for future use */
+ unsigned char rsIdentity[DTLS_PSK_ID_LEN]; /**< identity of self */
+ uint32_t num; /**< number of credentials in this blob */
+ CADtlsPskCreds_t *creds; /**< list of credentials. Size of this
+ array is determined by 'num' variable. */
+} CADtlsPskCredsBlob_t;
+
#ifdef __cplusplus
} /* extern "C" */
#endif
* @param requestInfo [IN ] information for the request.
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CASendRequestToAll(const CAGroupEndpoint_t* object,
- const CARequestInfo_t* requestInfo);
+CAResult_t CASendRequestToAll(const CAGroupEndpoint_t *object,
+ const CARequestInfo_t *requestInfo);
/**
* @brief Send the response
* @param responseInfo [IN ] information for the response.
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CASendNotification(const CARemoteEndpoint_t *object, CAResponseInfo_t *responseInfo);
+CAResult_t CASendNotification(const CARemoteEndpoint_t *object,
+ CAResponseInfo_t *responseInfo);
/**
* @brief for advertise the resource
* @param numOptions [IN] number of options
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token,
- CAHeaderOption_t* options,uint8_t numOptions);
+CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token,
+ CAHeaderOption_t *options, uint8_t numOptions);
/**
* @brief Select network to use
BUILD := debug
PLATFORM := linux
TRANSPORT := ALL
+ARDUINO_DIR := /usr/share/arduino
APPNAME := casample
OBJ_DIR := ./bin
VERSION_MAJOR := 0
else ifeq ($(PLATFORM),arduinomega)
$(info *********ArduinoMega Build!!**********)
all:
- sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(APPNAME)
- sudo sh arduino/build.sh make $(PLATFORM) $(TRANSPORT) $(APPNAME)
+ sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
+ sudo sh arduino/build.sh make $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
clean:
- sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(APPNAME)
+ sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
install:
- sudo sh arduino/build.sh install $(PLATFORM) $(TRANSPORT) $(APPNAME)
+ sudo sh arduino/build.sh install $(PLATFORM) $(TRANSPORT) $(ARDUINO_DIR) $(APPNAME)
else
$(info *********error**********)
LOCAL_SRC_FILES = \
caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c \
- canetworkconfigurator.c caprotocolmessage.c \
+ canetworkconfigurator.c caprotocolmessage.c caretransmission.c \
caqueueingthread.c \
$(ADAPTER_UTILS)/caadapterutils.c $(ADAPTER_UTILS)/camessagequeue.c \
$(ADAPTER_UTILS)/camsgparser.c \
Setting Wi-Fi SSID and Password for Arduino Wi-FI Shield
=====================================
-PreCondition: In connectivity\src\wifi_adapter\arduino\cawifiadapterutils.cpp
+PreCondition: In connectivity\src\wifi_adapter\arduino\cawifiserver.cpp
Update the SSID and Password credentials before testing with Wi-Fi Shield
char ssid[] = ""; // your network SSID (name)
char pass[] = ""; // your network password
Compiling Interface APIs for ARDUINOMEGA:
========================================
-PREREQ: Arduino MUST be installed in the machine where we compile
-1) Open the local.properties file and change the path for ARDUINO_DIR to your own arduino installation directory.
-2) Similarly change the path for ARDUINO_TOOLS_DIR to your arduino tools directory.
-NOTE: We have changed local.properties so that, this could be a generic location (/usr/share/arduino).
-So, this assumes arduino files to be installed in this location. If there's a change, we need to change accordingly in local.properties.
-
+PREREQ: Arduino MUST be installed in the machine where we compile. Suppose ARDUINO_DIR = <PATH_TO_ARDUINO_INSTALL_DIR>/arduino-1.5.x
+1) Patch the Wiznet Ethernet library with the patch available at :
+ I. connectivity\lib\extlibs\arduino_linux_ethernet_cpp.patch
+ II.connectivity\lib\extlibs\arduino_linux_ethernet_socket_cpp.patch
+ Place both these libraries in the ARDUINO_DIR/libraries/ folder where remaining libraries are present.
+2) Arduino builds are dependent on latest Time and TimedAction libraries. Download it from here:
+ I. http://playground.arduino.cc/Code/Time
+ II.http://playground.arduino.cc/Code/TimedAction
3) Go to "connectivity\build\arduino" directory, Open Makefile and change ARDUINO_PORT according to connected PORT
-4) Go to "connectivity\build" directory. To build a specific TRANSPORT [ETHERNET,BLE,WIFI], use the following command :
- sudo make PLATFORM=arduinomega TRANSPORT=<ETHERNET/BLE/WIFI>
+4) BUILD : Go to "connectivity\build" directory. To build a specific TRANSPORT [ETHERNET,BLE,WIFI], use the following command :
+ sudo make PLATFORM=arduinomega TRANSPORT=<ETHERNET/BLE/WIFI> ARDUINO_DIR = <PATH_TO_ARDUINO_INSTALL_DIR>/arduino-1.5.x
Note: Prior to building for BLE Transport, following additional steps are required:
- Copy the directory "connectivity\src\bt_le_adapter\arduino\external\RBL_nRF8001" to "arduino-<x.x.x>/library" folder
- Download BLE library from internet and place it in "arduino-<x.x.x>/library" folder
-
-
+
Flashing Interface APIs for ARDUINOMEGA:
========================================
Precondition: Connect Arduino Mega Board to Linux PC. Open Arduino IDE and select corresponding connected PORT
ifeq ($(TRANSPORT),ETHERNET)
SDIR_ARD_ETH = $(ARDUINO_DIR)/libraries/Ethernet/src
SDIR_ARD_ETH_UTIL = $(ARDUINO_DIR)/libraries/Ethernet/src/utility
- SDIR_ARD_ETH1 = $(BASE_DIR)/src/ethernet_adapter/arduino/
+ SDIR_ARD_ETH1 = $(BASE_DIR)/src/ethernet_adapter/arduino/:$(BASE_DIR)/src/ethernet_adapter/
SDIR_ARD_PLATFORM = $(SDIR_ARD_CORE1):$(SDIR_ARD_TIME):$(SDIR_ARD_TIMED_ACTION):$(SDIR_ARD_BASE1):$(SDIR_ARD_BASE2):$(SDIR_ARD_SPI) \
$(SDIR_ARD_CALOGIC):$(SDIR_ARD_UTIL):$(SDIR_ARD_ETH):$(SDIR_ARD_ETH_UTIL):$(SDIR_ARD_ETH1)
else ifeq ($(TRANSPORT),WIFI)
SDIR_ARD_WIFI = $(ARDUINO_DIR)/libraries/WiFi/src
SDIR_ARD_WIFI_UTIL = $(ARDUINO_DIR)/libraries/WiFi/src/utility
- SDIR_ARD_WIFI1 = $(BASE_DIR)/src/wifi_adapter/arduino/
+ SDIR_ARD_WIFI1 = $(BASE_DIR)/src/wifi_adapter/arduino/:$(BASE_DIR)/src/wifi_adapter/
SDIR_ARD_PLATFORM = $(SDIR_ARD_CORE1):$(SDIR_ARD_TIME):$(SDIR_ARD_TIMED_ACTION):$(SDIR_ARD_BASE1):$(SDIR_ARD_BASE2):$(SDIR_ARD_SPI) \
$(SDIR_ARD_CALOGIC):$(SDIR_ARD_UTIL):$(SDIR_ARD_WIFI):$(SDIR_ARD_WIFI_UTIL):$(SDIR_ARD_WIFI1)
else ifeq ($(TRANSPORT),BLE)
else ifeq ($(TRANSPORT),WIFI)
IDIR_ARD_WIFI = $(ARDUINO_DIR)/libraries/WiFi/src
IDIR_ARD_WIFI_UTIL = $(ARDUINO_DIR)/libraries/WiFi/src/utility
- IDIR_ARD_WIFI1 = $(BASE_DIR)/src/wifi_adapter/arduino/
INC_DIR_PLATFORM = -I$(IDIR_ARD_CORE1) -I$(IDIR_ARD_CORE2) -I$(IDIR_ARD_CORE3) \
-I$(INCD_ARD_TIME) -I$(INCD_ARD_TIMED_ACTION) \
-I$(IDIR_ARD_SPI) \
-I$(INCD_ARD_BASE1) -I$(INCD_ARD_BASE2) -I$(INCD_ARD_BASE3) \
-I$(INCD_ARD_BASE4) -I$(IDIR_ARD_ETH_UTIL) -I$(IDIR_ARD_WIFI) \
- -I$(IDIR_ARD_WIFI_UTIL) -I$(IDIR_ARD_WIFI1)
+ -I$(IDIR_ARD_WIFI_UTIL)
else ifeq ($(TRANSPORT),BLE)
IDIR_ARD_BLE = $(ARDUINO_DIR)/libraries/BLE
IDIR_ARD_RBL = $(ARDUINO_DIR)/libraries/RBL_nRF8001
main.cpp.o new.cpp.o Print.cpp.o Stream.cpp.o Tone.cpp.o USBCore.cpp.o WMath.cpp.o WString.cpp.o
SPI_OBJ = SPI.cpp.o
TIMED_OBJ = TimedAction.cpp.o
-LOGGER_OBJ = logger.cpp.o oic_logger.c.o oic_console_logger.c.o oic_malloc.c.o uarraylist.c.o
+LOGGER_OBJ = logger.cpp.o oic_logger.c.o oic_console_logger.c.o oic_malloc.c.o oic_string.c.o uarraylist.c.o
UTIL_OBJ = caadapterutils.c.o camsgparser.c.o
CACOMMON_OBJ = caconnectivitymanager_singlethread.c.o cainterfacecontroller_singlethread.c.o camessagehandler_singlethread.c.o canetworkconfigurator_singlethread.c.o caprotocolmessage.c.o \
- caremotehandler.c.o
+ caremotehandler.c.o caretransmission_singlethread.cpp.o
ifeq ($(TRANSPORT),ETHERNET)
ETH_CPPOBJ = Dhcp.o Dns.o Ethernet.o EthernetUdp.o EthernetClient.o
ETH_UTIL_CPPOBJ = socket.o w5100.o
- INTERFACE_OBJ = caethernetadapterutils.cpp.o caethernetadapter.c.o
+ INTERFACE_OBJ = caethernetadapterutils.cpp.o caethernetclient.cpp.o caethernetserver.cpp.o caethernetnwmonitor.cpp.o caethernetadapter_singlethread.c.o
PLATFORM_OBJS = $(CORE_COBJ) $(CORE_CPPOBJ) $(SPI_OBJ) $(TIMED_OBJ) $(LOGGER_OBJ) $(INTERFACE_OBJ) $(ETH_CPPOBJ) $(ETH_UTIL_CPPOBJ) $(UTIL_OBJ) $(CACOMMON_OBJ)
else ifeq ($(TRANSPORT),WIFI)
WIFI_CPPOBJ = WiFi.cpp.o WiFiClient.cpp.o WiFiServer.cpp.o WiFiUdp.cpp.o
WIFI_UTIL_CPPOBJ = server_drv.cpp.o spi_drv.cpp.o wifi_drv.cpp.o
- INTERFACE_OBJ = cawifiadapterutils.cpp.o cawifiadapter.c.o
+ INTERFACE_OBJ = cawificlient.cpp.o cawifiserver.cpp.o cawifinwmonitor.cpp.o cawifiadapter_singlethread.c.o
PLATFORM_OBJS = $(CORE_COBJ) $(CORE_CPPOBJ) $(SPI_OBJ) $(TIMED_OBJ) $(LOGGER_OBJ) $(INTERFACE_OBJ) $(WIFI_CPPOBJ) $(WIFI_UTIL_CPPOBJ) $(UTIL_OBJ) $(CACOMMON_OBJ)
else ifeq ($(TRANSPORT),BLE)
BLE_OBJ = aci_queue.cpp.o aci_setup.cpp.o acilib.cpp.o hal_aci_tl.cpp.o lib_aci.cpp.o
if echo $1 | grep -q -i "make"
then
cd ../lib/libcoap-4.1.1/
-sudo make -f makefile_arduino.mak PLATFORM=$2
+sudo make -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4
cd ../../build/arduino
-sudo make PLATFORM=$2 TRANSPORT=$3 APP_NAME=$4
+sudo make PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5
else
cd ../lib/libcoap-4.1.1/
-sudo make $1 -f makefile_arduino.mak PLATFORM=$2
+sudo make $1 -f makefile_arduino.mak PLATFORM=$2 ARDUINO_DIR=$4
cd ../../build/arduino/
-sudo make $1 PLATFORM=$2 TRANSPORT=$3 APP_NAME=$4
+sudo make $1 PLATFORM=$2 TRANSPORT=$3 ARDUINO_DIR=$4 APP_NAME=$5
fi
\ No newline at end of file
BUILD = debug
PLATFORM = linux
TRANSPORT = ALL
+DTLS = 0
OBJ_DIR = ./$(BUILD)
VERSION_MAJOR = 0
VERSION_MINOR = 1
ETHERNET = ETHERNET_ADAPTER
#Add Pre processor definitions
+
DEFINE_FLAG = -D$(EDR) -D$(LE) -D$(WIFI) -D$(ETHERNET)
+ifeq ($(DTLS),1)
+DEFINE_FLAG += -D__WITH_DTLS__
+endif
#Add For memory checking
#DEBUG_FLAG = -DENABLE_MALLOC_DEBUG
#Add Debug flags here
##
libcoap_build_dir = $(PROJECT_LIB_PATH)/libcoap-4.1.1
-LDFLAGS := -L$(libcoap_build_dir)
-LDLIBS := -lcoap
+ifeq ($(DTLS),1)
+libtiny_lib_dir = $(PROJECT_LIB_PATH)/extlibs/tinydtls
+
+LDFLAGS := -L$(libcoap_build_dir) -L$(libtiny_lib_dir)
+LDLIBS := -lcoap -ltinydtls
+else
+LDFLAGS := -L$(libcoap_build_dir)
+LDLIBS := -lcoap
+endif
BUILD_FLAG.debug = $(DEFINE_FLAG) $(DEBUG_FLAG)
BUILD_FLAG.release = $(DEFINE_FLAG)
BUILD_FLAG = $(BUILD_FLAG.$(BUILD))
## file declaration
##
COMPONENT_SRCS := logger.c oic_logger.c oic_console_logger.c oic_malloc.c oic_string.c uqueue.c uarraylist.c umutex.c uthreadpool.c
+COMPONENT_SRCS += caretransmission.c
COMPONENT_SRCS += caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c caqueueingthread.c canetworkconfigurator.c caprotocolmessage.c
-COMPONENT_SRCS += caadapterutils.c camessagequeue.c
+COMPONENT_SRCS += caadapterutils.c
COMPONENT_SRCS += caethernetadapter.c cawifiadapter.c caedradapter.c caleadapter.c
COMPONENT_SRCS += cawifiserver.c cawificlient.c cawifinwmonitor.c
COMPONENT_SRCS += caethernetserver.c caethernetclient.c caethernetnwmonitor.c
+ifeq ($(DTLS),1)
+COMPONENT_SRCS += caadapternetdtls.c
+endif
COMPONENT_OBJS = $(COMPONENT_SRCS:%.c=$(OBJ_DIR)/%.o)
##
-I$(WIFI_ADAPTER_PATH) \
-I$(BT_ADAPTER_PATH) \
-I$(BLE_ADAPTER_PATH) \
- -I$(libcoap_build_dir)
+ -I$(libcoap_build_dir)
+
+ifeq ($(DTLS),1)
+ IFLAGS += -I$(libtiny_lib_dir)
+endif
DFLAGS = -D__LINUX__ -DWITH_POSIX $(BUILD_FLAG)
BUILD := debug
PLATFORM := tizen
OBJ_DIR := ./bin
+ROOT_DIR := .
VERSION_MAJOR := 0
VERSION_MINOR := 1
VERSION_PATCH := 0
LIBCOAP=./lib/libcoap-4.1.1/
LIBCOAP_OBJ_DIR=./lib/libcoap-4.1.1/obj
+TINYDTLS=./lib/extlibs/tinydtls
+TINYDTLS_OBJ_DIR=./lib/extlibs/tinydtls/obj
+
# TODO : Currently Hardcoded WIFI_ADAPTER. Change it to generic
CFLAGS.debug = -DWITH_POSIX -D__TIZEN__ -Wall -std=c99 -DSLP_SDK_LOG -g -D_GNU_SOURCE -DTIZEN_DEBUG_ENABLE -DTB_LOG $(ADAPTER_MACRO)
CFLAGS.release = -DWITH_POSIX -D__TIZEN__ -Wall -std=c99 -DSLP_SDK_LOG -D_GNU_SOURCE -DTIZEN_DEBUG_ENABLE -DTB_LOG $(ADAPTER_MACRO)
# Include files will be copied into a single folder on gbsbuild.
# NO NEED to mention the path explicitly.
+CA_INC = $(ROOT_DIR)/
+DTLS_INC = $(ROOT_DIR)/dtls/
+
+INC_DIRS := -I$(CA_INC)
+INC_DIRS += -I$(DTLS_INC)
+
SRC = $(wildcard *.c)
OBJECTS = $(patsubst %.c, %.o, $(SRC))
ar rcs liboicinterface.a $(OBJECTS) $(LIBCOAP_OBJ_DIR)/*.o
%.o : %.c
- $(CC) -c $(CFLAGS.$(BUILD)) $(COMPILEFLAG) $< -o $@
+ $(CC) -c $(CFLAGS.$(BUILD)) $(COMPILEFLAG) $(INC_DIRS) $< -o $@
pack:
cd $sourcedir/tizen
mkdir ./tmp
+mkdir -p ./tmp/dtls
cp -R ./* $sourcedir/tizen/tmp/
rm -rf $sourcedir/tizen/tmp/tmp/
cp -R ../../inc/* $sourcedir/tizen/tmp/
+cp -R ../../lib/extlibs/tinydtls/* $sourcedir/tizen/tmp/dtls/
cp -R ../../api/* $sourcedir/tizen/tmp/
cp ../../src/adapter_util/* $sourcedir/tizen/tmp/
# Including All CA Adapter code for Tizen Compilation
cp -R ../../common/inc/* $sourcedir/tizen/tmp/
cp ../../src/* $sourcedir/tizen/tmp/
cp ../../lib/libcoap-4.1.1/*.h $sourcedir/tizen/tmp/
+cp -R ../../lib/extlibs/tinydtls/*.h $sourcedir/tizen/tmp/tinydtls/
cp ../../lib $sourcedir/tizen/tmp/ -rf
adapterMacro=""
#multiple definition error.
rm -rf *_singlethread.*
+rm -rf *dtls.*
+
#cd $builddir
#cp -R ./* $sourcedir/tmp/
#endif
/* Basic interface: */
-oic_log_ctx_t *oic_log_make_ctx(void* world, const oic_log_level level, oic_log_init_t init,
- oic_log_destroy_t destroy, oic_log_flush_t flush, oic_log_set_level_t set_level,
- oic_log_write_level_t write_level, oic_log_set_module_t set_module);
+oic_log_ctx_t *oic_log_make_ctx(void *world, const oic_log_level level, oic_log_init_t init,
+ oic_log_destroy_t destroy, oic_log_flush_t flush, oic_log_set_level_t set_level,
+ oic_log_write_level_t write_level, oic_log_set_module_t set_module);
void oic_log_destroy(oic_log_ctx_t *ctx);
typedef struct _oic_log_ctx
{
- void* ctx;
+ void *ctx;
oic_log_level log_level;
- char* module_name;
+ char *module_name;
/* Required interface: */
int (*init)(struct _oic_log_ctx *, void *);
* @brief API to creates array list and initializes the elements.
* @return u_arraylist_t if Success, NULL otherwise
*/
-u_arraylist_t* u_arraylist_create();
+u_arraylist_t *u_arraylist_create();
/**
* @brief Resets and deletes the array list
* [IN] index of array list
* @return void pointer of the data
*/
-void* u_arraylist_get(const u_arraylist_t *list, uint32_t index);
+void *u_arraylist_get(const u_arraylist_t *list, uint32_t index);
/**
* @brief Add data in the array list
* [IN] index of array list
* @return void pointer of the data
*/
-void* u_arraylist_remove(u_arraylist_t *list, uint32_t index);
+void *u_arraylist_remove(u_arraylist_t *list, uint32_t index);
/**
* @brief Returns the length of the array list
#ifndef __UMUTEX_H_
#define __UMUTEX_H_
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <stdint.h>
#include "cacommon.h"
struct u_queue_element_t
{
/* pointer to queue message */
- u_queue_message_t* message;
+ u_queue_message_t *message;
/* Pointer to next queue element*/
- u_queue_element* next;
+ u_queue_element *next;
};
/**
typedef struct u_queue_t
{
/* Head of the queue */
- u_queue_element* element;
+ u_queue_element *element;
/* Number of messages in Queue*/
uint32_t count;
} u_queue_t;
* @brief API to creates queue and initializes the elements.
* @return u_queue_t pointer if Success, NULL otherwise
*/
-u_queue_t* u_queue_create();
+u_queue_t *u_queue_create();
/**
* @fn u_queue_delete
* @return CAResult_t - CA_STATUS_OK, if Success
* @return CA_STATUS_FAILED - otherwise
*/
-CAResult_t u_queue_delete(u_queue_t* queue);
+CAResult_t u_queue_delete(u_queue_t *queue);
/**
* @fn u_queue_add_element
* @return CAResult_t - CA_STATUS_OK, if Success
* @return CA_STATUS_FAILED - otherwise
*/
-CAResult_t u_queue_add_element(u_queue_t* queue, u_queue_message_t *message);
+CAResult_t u_queue_add_element(u_queue_t *queue, u_queue_message_t *message);
/**
* @fn u_queue_get_element
* @return pointer to Message, if Success
* @return NULL - otherwise
*/
-u_queue_message_t* u_queue_get_element(u_queue_t* queue);
+u_queue_message_t *u_queue_get_element(u_queue_t *queue);
/**
* @fn u_queueRemoveElement
* @return CAResult_t - CA_STATUS_OK, if Success
* @return CA_STATUS_FAILED - otherwise
*/
-CAResult_t u_queue_remove_element(u_queue_t* queue);
+CAResult_t u_queue_remove_element(u_queue_t *queue);
/**
* @fn u_queue_get_size
* Input : queue - pointer to queue
* Return : number of elements in queue
*/
-uint32_t u_queue_get_size(u_queue_t* queue);
+uint32_t u_queue_get_size(u_queue_t *queue);
/**
* @fn u_queue_reset
* @return CAResult_t - CA_STATUS_OK, if Success
* @return CA_STATUS_FAILED - otherwise
*/
-CAResult_t u_queue_reset(u_queue_t* queue);
+CAResult_t u_queue_reset(u_queue_t *queue);
/**
* @fn u_queue_get_head
* @return pointer to Message, if Success
* @return NULL - otherwise
*/
-u_queue_message_t* u_queue_get_head(u_queue_t* queue);
+u_queue_message_t *u_queue_get_head(u_queue_t *queue);
#ifdef __cplusplus
} /* extern "C" */
// Convert LogLevel to platform-specific severity level. Store in PROGMEM on Arduino
#ifdef __ANDROID__
#ifdef ADB_SHELL
-static const char * LEVEL[] =
+static const char *LEVEL[] =
{ "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
#else
#else //#elif __TIZEN__
LOGD(logStr);
/*#ifdef LOG_TAG
- #undef LOG_TAG
- #define LOG_TAG tag
- #endif
+#undef LOG_TAG
+#define LOG_TAG tag
+#endif
if(level == DEBUG || level == INFO){
LOGD(logStr);
}else if(level == WARNING){
oic_log_ctx_t *oic_make_console_logger()
{
return oic_log_make_ctx(NULL, OIC_LOG_ALL, oic_console_logger_init, oic_console_logger_destroy,
- oic_console_logger_flush, oic_console_logger_set_level, oic_console_logger_write,
- oic_console_logger_set_module);
+ oic_console_logger_flush, oic_console_logger_set_level, oic_console_logger_write,
+ oic_console_logger_set_module);
}
int oic_console_logger_init(oic_log_ctx_t *ctx, void *world)
#include <string.h>
#include <stdlib.h>
-oic_log_ctx_t *oic_log_make_ctx(void* world, const oic_log_level level, oic_log_init_t init,
- oic_log_destroy_t destroy, oic_log_flush_t flush, oic_log_set_level_t set_level,
- oic_log_write_level_t write_level, oic_log_set_module_t set_module)
+oic_log_ctx_t *oic_log_make_ctx(void *world, const oic_log_level level, oic_log_init_t init,
+ oic_log_destroy_t destroy, oic_log_flush_t flush, oic_log_set_level_t set_level,
+ oic_log_write_level_t write_level, oic_log_set_module_t set_module)
{
oic_log_ctx_t *log_ctx;
if (0 == init || 0 == destroy || 0 == flush || 0 == set_level || 0 == write_level
- || 0 == set_module)
+ || 0 == set_module)
return 0;
if (__OIC_LOG_MIN__ > level || __OIC_LOG_MAX__ < level)
list->size = U_ARRAYLIST_DEFAULT_SIZE;
list->length = 0;
- if (!(list->data = (void*) OICMalloc(list->size * sizeof(void*))))
+ if (!(list->data = (void *) OICMalloc(list->size * sizeof(void *))))
{
OIC_LOG_V(DEBUG, TAG, "Out of memory");
OICFree(list);
list->size--;
list->length--;
+ // check minimum size.
+ list->size = (list->size <= U_ARRAYLIST_DEFAULT_SIZE) ? U_ARRAYLIST_DEFAULT_SIZE : list->size;
+
if (!(list->data = (void **) realloc(list->data, list->size * sizeof(void *))))
{
return NULL;
{
if (NULL == mutex)
{
- OIC_LOG_V(ERROR, TAG ,"u_mutex_lock, Invalid mutex !");
+ OIC_LOG_V(ERROR, TAG , "u_mutex_lock, Invalid mutex !");
return;
}
{
if (NULL == mutex)
{
- OIC_LOG_V(ERROR, TAG,"u_mutex_trylock, Invalid mutex !");
+ OIC_LOG_V(ERROR, TAG, "u_mutex_trylock, Invalid mutex !");
return CA_FALSE;
}
{
if (NULL == mutex)
{
- OIC_LOG_V(ERROR, TAG,"u_mutex_unlock, Invalid mutex !");
+ OIC_LOG_V(ERROR, TAG, "u_mutex_unlock, Invalid mutex !");
return;
}
{
if (NULL == mutex)
{
- OIC_LOG_V(ERROR, TAG,"u_mutex_free, Invalid mutex !");
+ OIC_LOG_V(ERROR, TAG, "u_mutex_free, Invalid mutex !");
return;
}
{
if (NULL == cond)
{
- OIC_LOG_V(ERROR, TAG,"u_cond_signal, Invalid condition !");
+ OIC_LOG_V(ERROR, TAG, "u_cond_signal, Invalid condition !");
return;
}
{
if (NULL == cond)
{
- OIC_LOG_V(ERROR, TAG,"u_cond_broadcast, Invalid condition !");
+ OIC_LOG_V(ERROR, TAG, "u_cond_broadcast, Invalid condition !");
return;
}
{
if (NULL == mutex)
{
- OIC_LOG_V(ERROR, TAG,"u_cond_wait, Invalid mutex !");
+ OIC_LOG_V(ERROR, TAG, "u_cond_wait, Invalid mutex !");
return;
}
if (NULL == cond)
{
- OIC_LOG_V(ERROR, TAG,"u_cond_wait, Invalid condition !");
+ OIC_LOG_V(ERROR, TAG, "u_cond_wait, Invalid condition !");
return;
}
{
if (NULL == mutex)
{
- OIC_LOG_V(ERROR, TAG,"u_cond_wait, Invalid mutex !");
+ OIC_LOG_V(ERROR, TAG, "u_cond_wait, Invalid mutex !");
return;
}
if (NULL == cond)
{
- OIC_LOG_V(ERROR, TAG,"u_cond_wait, Invalid condition !");
+ OIC_LOG_V(ERROR, TAG, "u_cond_wait, Invalid condition !");
return;
}
{
if (NULL == cond)
{
- OIC_LOG_V(ERROR, TAG,"u_cond_free, Invalid condition !");
+ OIC_LOG_V(ERROR, TAG, "u_cond_free, Invalid condition !");
return;
}
* limitations under the License.
*
******************************************************************/
+
/**
* @file uthreadpool.c
* @brief This file provides APIs related to thread pool
#include "uthreadpool.h"
#include "logger.h"
#include "oic_malloc.h"
+
#define TAG PCF("UTHREADPOOL")
/**
}
return CA_STATUS_FAILED;
}
+
*thread_pool = (u_thread_pool_t) gThreadpool;
OIC_LOG(DEBUG, TAG, "OUT");
void u_thread_pool_free(u_thread_pool_t thread_pool)
{
OIC_LOG(DEBUG, TAG, "IN");
- if(NULL == thread_pool)
+ if (NULL == thread_pool)
{
- OIC_LOG(DEBUG, TAG, "thread_pool is NULL. Its already freed.");
- return;
+ OIC_LOG(DEBUG, TAG, "thread_pool is NULL. Its already freed.");
+ return;
}
+
GThreadPool *threadpool = (GThreadPool *) thread_pool;
g_thread_pool_free(threadpool, TRUE, TRUE);
{
u_thread_msg_t *message = (u_thread_msg_t *) thread_data;
- if (message && message->func)
- {
- OIC_LOG(DEBUG, TAG, "Calling routine with data as parameter");
- message->func(message->data);
- }
- else
+ if (NULL == message)
{
OIC_LOG(ERROR, TAG, "Invalid task data");
return;
}
- //Free message
+ if(message->func)
+ {
+ OIC_LOG(DEBUG, TAG, "Calling routine with data as parameter");
+ message->func(message->data);
+ }
+
+ // Free message
OICFree(message);
message = NULL;
}
--- /dev/null
+Project Name: IoTivity
+Release Version No: CA_v0.6
+API Version: CA_v0.7
+
+Release Description:
+Connectivity Abstraction provides a unified approach to send different OIC messages across multiple transports.
+
+Supported Platform OS:
+1) Ubuntu 12.0.4 and above:
+ Connectivity : WIFI, ETHERNET
+ Security : DTLS for WIFI
+2) Tizen 2.3
+ Connectivity : WIFI, EDR, BLE(1:1).
+3) Arduino Mega
+ Connectivity : WIFI, ETH,BLE
+4) Android 5.0s
+ Connectivity : WIFI, BLE
+
+Preconditions:
+1)gcc 4.6.3 and above.
+2)glib library (sudo apt-get install libglib2.0-dev) for linux, tizen and android devices
+3)libcoap.a library ( do make @lib/libcoap-4.1.1)
+4)tinyDTLS library for DTLS enabled applications( enable DTLS = 1 in makefile @connectivity\build/linux)
+5)Ethernet, BLE, TimedActions, Timer libraries for arduino support.
+
+Scope of Release:
+1. Supported APIs ( please check below APIs)
+2. Samples to test for Supported APIs.
+3. OIC Coding guidelines followed based on the current CSDK source.
+4. Multi-Threaded, Single threaded Connectivity abstraction.
+5. Executed Open Source Verification and Prevent analysis.
+Type of Release: Source
+The following Connectivity Abstraction API features are supported in this release:
+
+Supported APIs
+CAInitialize()
+CATerminate()
+CAStartListeningServer()
+CAStartDiscoveryServer()
+CARegisterHandler()
+CAhandleRequestResponse()
+FindResource()
+SendRequest()
+SendResponse()
+SelectNetwork()
+UnselectNetwork()
+SendNotification()
+AdvertizeResource()
+CAGenerateToken()
+CADestryToken()
+CAGetNetworkInfo()
+
+
+Known and Open Issues:
+1) OIC Log, OIC Malloc will be removed once name changes applied to OIC Bases code.
+2) Tizen platform BLE stack is not stable. So we may see random crashes.
+3) GetDtlsPskCredentials is implemented in sample which will be replace by security call during integration
+
+How to Build for Linux:
+Follow below steps to execute CA Client / server in different systems
+Step 1: Build Libcoap library
+Make File Location @connectivity\lib\libcoap-4.1.1
+Step 2: Build CA library
+Make File Location @connectivity\build\linux
+Step 3: Samples
+Make File Location @connectivity\samples\linux
+
+Execution:
+linux$ export LD_LIBRARY_PATH=../../build/out/
+linux$ ./out/sample_main
+
+
+Follow below sequence to test
+
+Client Option: c
+Server Option: s
+
+Client Option: f (provide a/light)
+Server Option: h (will pick from queue and send response)
+Client Option: h (to pick server response)
+
+Client Option: r (provide “ServerIP:5383/a/request”)
+Server Option: h (will pick from queue and send response)
+Client Option: h (to pick server response)
+
+Server Option: a
+Client Option: h (to pick server response)
+
+Server Option: b (provide ServerIP:5383/a/notify)
+Client Option: h (to pick server response)
+
+Client: Server side: n for network selection (WIFI enabled by default)
+
+
+How to Build for Linux/DTLS:
+sudo ./sample.sh WITH_DTLS @@connectivity\samples\linux
*/
typedef void (*CANetworkChangeCallback)(CALocalConnectivity_t *info, CANetworkStatus_t status);
+/**
+ * @brief This will be used during the recive of network requests and response.
+ * @see SendUnitcastData(), SendMulticastData()
+ */
+typedef void (*CABLEClientDataReceivedCallback)(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength);
+
+/**
+ * @brief This will be used during the recive of network requests and response.
+ * @see SendUnitcastData(), SendMulticastData()
+ */
+typedef void (*CABLEServerDataReceivedCallback)(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength);
#ifdef __cplusplus
} /* extern "C" */
#endif
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 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.
+*
+******************************************************************/
+#ifndef _CA_ADAPTER_NET_DTLS_H
+#define _CA_ADAPTER_NET_DTLS_H
+
+#include "dtls.h"
+#include "uarraylist.h"
+#include "umutex.h"
+#include "caadapterutils.h"
+
+extern void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo);
+
+typedef void (*CAPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength, const CABool_t isSecured);
+
+/**
+ *@struct stCADtlsContext_t
+ * @brief Data structure for holding the tinyDTLS interface
+ * related info.
+ */
+typedef struct stCADtlsContext
+{
+ u_arraylist_t *cacheList; /**< pdu's are cached until DTLS session is formed */
+ struct dtls_context_t *dtlsContext; /**< pointer to tinyDTLS context */
+ struct stPacketInfo
+ *packetInfo; /**< used by callback during decryption to hold address/length */
+ dtls_handler_t callbacks; /**< pointer to callbacks needed by tinyDTLS */
+ CAPacketReceivedCallback gPacketReceivedCallback;
+} stCADtlsContext_t;
+
+/**
+ *@struct stPacketInfo_t
+ * @brief Data structure for holding the decrypted data address
+ * and length provided by tinyDTLS callback interface.
+ */
+typedef struct stPacketInfo
+{
+ uint8_t *dataAddress;
+ uint16_t dataLen;
+} stPacketInfo_t;
+
+/**
+ * @enum eDtlsRet_t
+ * @brief tinyDTLS library error codes.
+ *
+ */
+typedef enum
+{
+ DTLS_OK = 0,
+ DTLS_FAIL,
+ DTLS_SESSION_INITIATED,
+ DTLS_HS_MSG
+} eDtlsRet_t;
+
+/**
+ * @struct stGattServiceInfo_t
+ * @brief structure to have address information.
+ *
+ */
+typedef struct
+{
+ socklen_t size; /**< size of addr */
+ union
+ {
+ struct sockaddr sa;
+ struct sockaddr_storage st;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } addr;
+ uint8_t ifindex;
+} stCADtlsAddrInfo_t;
+
+/**
+ * @struct stCACacheMessage_t
+ * @brief structure to holds the information of cachemessage and address info.
+ *
+ */
+typedef struct CACacheMessage_t
+{
+ void *data;
+ uint32_t dataLen;
+ stCADtlsAddrInfo_t *destSession;
+} stCACacheMessage_t;
+
+void CADTLSSetPacketReceiveCallback(CAPacketReceivedCallback callback);
+
+/**
+ * @fn CAAdapterNetDtlsInit
+ * @brief initialize tinyDTLS library and other necessary intialization.
+ *
+ * @return 0 on success otherwise a positive error value.
+ * @retval CA_STATUS_OK Successful
+ * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval CA_STATUS_FAILED Operation failed
+ *
+ */
+CAResult_t CAAdapterNetDtlsInit();
+
+/**
+ * @fn CAAdapterNetDtlsDeInit
+ * @brief de-inits tinyDTLS library and free the allocated memory.
+ *
+ * @return void
+ *
+ */
+void CAAdapterNetDtlsDeInit();
+
+/**
+ * @fn CAAdapterNetDtlsEncrypt
+ * @brief Performs DTLS encryption of the CoAP PDU. If a
+ * DTLS session does not exist yet with the @dst,
+ * a DTLS handshake will be started. In case where
+ * a new DTLS handshake is started, pdu info is
+ * cached to be send when session setup is finished.
+ *
+ * @param[in] remoteAddress address to which data will be sent.
+ * @param[in] port port to which data will be sent.
+ * @param[in] data length of data.
+ * @param[in] dataLen length of given data
+ * @param[out] decdata output variable to store the starting address
+ * of decrypted plaintext.
+ * @param[out] cacheFlag utput variable to indicate if pdu
+ * is cached and inform the caller to
+ * NOT free the memory holding pdu.
+ * @return 0 on success otherwise a positive error value.
+ * @retval CA_STATUS_OK Successful
+ * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval CA_STATUS_FAILED Operation failed
+ *
+ */
+
+CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress,
+ const uint32_t port,
+ const void *data,
+ uint32_t dataLen,
+ uint8_t *cacheFlag);
+
+/**
+ * @fn CAAdapterNetDtlsDecrypt
+ * @brief Performs DTLS decryption of the data received on
+ * secure port. This method performs in-place decryption
+ * of the cipher-text buffer. If a DTLS handshake message
+ * is received or decryption failure happens, this method
+ * returns -1. If a valid application PDU is decrypted, it
+ * returns the length of the decrypted pdu.
+ *
+ * @return 0 on success otherwise a positive error value.
+ * @retval CA_STATUS_OK Successful
+ * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval CA_STATUS_FAILED Operation failed
+ *
+ */
+CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress,
+ const uint32_t port,
+ uint8_t *data,
+ uint32_t dataLen);
+
+#endif //_CA_ADAPTER_NET_DTLS_H
+
* @fn CAAdapterCreateLocalEndpoint
* @brief Create CALocalConnectivity_t instance.
*/
-CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type,
- const char *address,const char *interfaceName);
+CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type,
+ const char *address);
/**
* @fn CAAdapterCopyLocalEndpoint
* @fn CAAdapterCreateRemoteEndpoint
* @brief Allocate CARemoteEndpoint_t instance.
*/
-CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type,
- const char *address,const char *resourceUri);
+CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type,
+ const char *address, const char *resourceUri);
/**
* @fn CAAdapterCopyRemoteEndpoint
* @brief Create CARemoteEndpoint_t duplicate instance.
*/
-CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remoteEndpoint);
+CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(
+ const CARemoteEndpoint_t *remoteEndpoint);
/**
* @fn CAAdapterFreeRemoteEndpoint
**/
#include "cacommon.h"
#include "caadapterinterface.h"
+#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
+#endif //ARDUINO
#ifdef __cplusplus
extern "C"
* not enabled
* @retval #CA_STATUS_FAILED Operation failed
*/
+#ifdef ARDUINO
+CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback reqRespCallback,
+ CANetworkChangeCallback netCallback);
+#else
CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
CANetworkPacketReceivedCallback reqRespCallback,
CANetworkChangeCallback netCallback,
u_thread_pool_t handle);
+#endif //#ifdef ARDUINO
+
/**
* @fn CAStartEDR
* @return Number of bytes sent on the network. 0 indicates failed to send data.
*
*/
-uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength);
+uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength);
/**
* @fn CASendEDRMulticastData
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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 caedradapter_singlethread.h
- * @brief This file contains the APIs for single threaded EDR adapters.
- */
-#ifndef __CA_EDRADAPTER_SINGLETHREAD_H_
-#define __CA_EDRADAPTER_SINGLETHREAD_H_
-
-/**
- * BT Interface AP
- **/
-#include "cacommon.h"
-#include "caadapterinterface.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#ifndef BLUETOOTH_ADAPTER_TAG
-#define BLUETOOTH_ADAPTER_TAG "CA_EDR"
-#endif //BLUETOOTH_ADAPTER_TAG
-
-#define OIC_BT_SERVICE_ID "12341234-1C25-481F-9DFB-59193D238280"
-
-/**
- * @brief Initialize EDR connectivity interface.
- * @param registerCallback [IN] To register EDR interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers
- * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback reqRespCallback,
- CANetworkChangeCallback netCallback);
-/**
- * @brief Starting EDR connectivity adapters .As its peer to peer it doesnot require to start any servers
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEDR();
-
-/**
- * @brief Starting listening server for receiving multicast search requests
- * Transport Specific Behavior:
- * EDR Starts RFCOMM Server with prefixed UUID as per specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEDRListeningServer();
-
-/**
- * @brief for starting discovery servers for receiving multicast advertisements
- * Transport Specific Behavior:
- * EDR Starts RFCOMM server with prefixed UUID as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEDRDiscoveryServer();
-
-/**
- * @brief Sends data to the endpoint using the adapter connectivity.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
-
-/**
- * @brief Sends Multicast data to the endpoint using the EDR connectivity.
- * Note: length must be > 0.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendEDRMulticastData(void *data, uint32_t dataLen);
-
-/**
- * @brief Starts notification server on EDR adapters.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEDRNotifyServer();
-
-/**
- * @brief Send notification information.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendEDRNotification(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
-
-/**
- * @brief Get EDR Connectivity network information
- * @param info [OUT] Local connectivity information structures
- * @param size [OUT] Number of local connectivity structures.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
-
-/**
- * @brief Read Synchronous API callback.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAReadEDRData();
-
-/**
- * @brief Stopping the adapters and close socket connections
- * EDR Stops all RFCOMM servers and close sockets.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStopEDR();
-
-/**
- * @brief Terminate the EDR connectivity adapter.
- * Configuration information will be deleted from further use
- */
-void CATerminateEDR();
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif //__CA_EDRADAPTER_H_
#include "cacommon.h"
#include "caadapterinterface.h"
+#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
+#endif //ARDUINO
#ifdef __cplusplus
extern "C"
* @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
+#ifdef ARDUINO
CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback networkPacketCallback,
- CANetworkChangeCallback netCallback, u_thread_pool_t handle);
+ CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback);
+#else
+CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback networkPacketCallback,
+ CANetworkChangeCallback netCallback, u_thread_pool_t handle);
+#endif
/**
* @brief Start Ethernet Interface adapter.
* @return - The number of bytes sent on the network. Return value equal to zero indicates error.
*/
uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
+ uint32_t dataLen);
/**
* @brief Sends Multicast data to the endpoint using the Ethernet connectivity.
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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 caethernetadapter_singlethread.h
- * @brief This file contains the APIs for Single threaded Ethernet Adapter.
- */
-#ifndef __CA_ETHERNET_ADAPTER_SINGLETHREAD_H__
-#define __CA_ETHERNET_ADAPTER_SINGLETHREAD_H__
-
-#include "cacommon.h"
-#include "caadapterinterface.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief API to initialize Ethernet Interface.
- * @param registerCallback [IN] To register Ethernet interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers
- * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback);
-
-/**
- * @brief Start Ethernet Interface adapter.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEthernet();
-
-/**
- * @brief Starting listening server for receiving multicast search requests
- * Transport Specific Behavior:
- * Ethernet Starts Multicast Server on all available IPs and prefixed port number and as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEthernetListeningServer();
-
-/**
- * @brief for starting discovery servers for receiving multicast advertisements
- * Transport Specific Behavior:
- * Ethernet Starts Start multicast server on all available IPs and prefixed port number as per OIC Specification
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEthernetDiscoveryServer();
-
-/**
- * @brief Sends data to the endpoint using the adapter connectivity.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
-
-/**
- * @brief Sends Multicast data to the endpoint using the Ethernet connectivity.
- * Note: length must be > 0.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLen);
-
-/**
- * @brief Starts notification server on Ethernet adapters.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEthernetNotifyRecvServers();
-
-/**
- * @brief Send notification information.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendEthernetNotification(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
-/**
- * @brief Get Ethernet Connectivity network information
- * @param info [OUT] Local connectivity information structures
- * @param size [OUT] Number of local connectivity structures.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
-
-/**
- * @brief Read Synchronous API callback.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAReadEthernetData();
-
-/**
- * @brief Stopping the adapters and close socket connections
- * Ethernet Stops all multicast and unicast servers and close sockets.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStopEthernet();
-
-/**
- * @brief Terminate the Ethernet connectivity adapter.
- * Configuration information will be deleted from further use
- */
-void CATerminateEthernet();
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif//#ifndef __CA_ETHERNET_ADAPTER_H__
#include <stdbool.h>
#include "cacommon.h"
-#include "uthreadpool.h"
+#ifndef ARDUINO
+#include "uthreadpool.h" /* for thread pool */
+#endif //ARDUINO
#ifdef __cplusplus
extern "C"
* @param[in] port Port number on which data is received.
* @param[in] data Data received from remote OIC device.
* @param[in] dataLength Length of data in bytes.
+ * @param[in] secure Indicates the data is secure or not.
*
* @pre Callback must be registered using CAEthernetSetPacketReceiveCallback()
*/
typedef void (*CAEthernetPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
- const void *data, const uint32_t dataLength);
+ const void *data, const uint32_t dataLength);
/**
* @fn CAEthernetExceptionCallback
/**
* @fn CAEthernetInitializeServer
+ * @brief API to initialize Wifi server
* @brief API to initialize Ethernet server
*
* @param[in] threadPool Thread pool for managing Unicast/Multicast server threads.
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Initialization failed
*/
+#ifndef ARDUINO
CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool);
-#ifdef ARDUINO
+#else
/**
* @fn CAEthernetInitializeServer
* @brief API to initialize Ethernet server
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
- const int16_t multicastPort, int32_t *serverFD);
+ const int16_t multicastPort, int32_t *serverFD);
+#ifdef ARDUINO
+/**
+ * @fn CAEthernetStartUnicastServer
+ * @brief API to start unicast server for specified local address and port
+ *
+ * @param[in] localAddress Local adapter address to which server to be binded.
+ * @param[in][out] port Port number on which server to be running.
+ * Port number on which server actually started will be returned.
+ * @param[in] forceStart Indicate whether to start server forcesfully on specified port or not.
+ * @param[in] secured true if the secure server to be started, otherwise false.
+ * @param[out] serverFD Unicast server socket FD.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, int32_t *serverFD);
+#else
/**
* @fn CAEthernetStartUnicastServer
* @brief API to start unicast server for specified local address and port
* @param[in][out] port Port number on which server to be running.
* Port number on which server actually started will be returned.
* @param[in] forceStart Indicate whether to start server forcesfully on specified port or not.
+ * @param[in] secured true if the secure server to be started, otherwise false.
* @param[out] serverFD Unicast server socket FD.
*
* @return #CA_STATUS_OK on success otherwise proper error code.
* @retval #CA_STATUS_FAILED Operation failed
*/
CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
- const bool forceStart, int32_t *serverFD);
+ const bool forceStart, const bool secured, int32_t *serverFD);
+#endif //ARDUINO
/**
* @fn CAEthernetStopMulticastServer
CAResult_t CAEthernetStopUnicastServer();
/**
+ * @fn CAEthernetStopSecureUnicastServer
+ * @brief API to stop secured unicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopSecureUnicastServer();
+
+#ifdef ARDUINO
+/**
* @fn CAEthernetGetUnicastServerInfo
* @brief API to get running unicast server information.
* @remarks @ipAddress must be freed using free().
*
+ * @param[in] secure true if the secure server information needed, otherwise false.
* @param[in] ipAddress IP address on which server is binded and running.
* @param[out] port Port number on which server is running
* @param[out] serverFD Server socket fd.
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Operation failed
*/
+
CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+#else
+
+/**
+ * @fn CAEthernetGetUnicastServerInfo
+ * @brief API to get running unicast server information.
+ * @remarks @ipAddress must be freed using free().
+ *
+ * @param[in] secure true if the secure server information needed, otherwise false.
+ * @param[in] ipAddress IP address on which server is binded and running.
+ * @param[out] port Port number on which server is running
+ * @param[out] serverFD Server socket fd.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetGetUnicastServerInfo(const bool secure, char **ipAddress, int16_t *port,
+ int32_t *serverFD);
+
+#endif // ARDUINO
+
/**
* @fn CAEthernetSetPacketReceiveCallback
* @brief API to set callback for receiving data packets from peer devices.
void CAEthernetSetUnicastSocket(const int32_t socketFD);
/**
+ * @fn CAEthernetSetUnicastPort
+ * @brief API to set port description for sending unicast UDP data
+ *
+ * @param[in] port Port descriptor used for sending UDP data.
+ *
+ */
+void CAEthernetSetUnicastPort(const int32_t port);
+
+/**
+ * @fn CAEthernetSetSecureUnicastSocket
+ * @brief API to set socket description for sending secured (encrypted) unicast UDP data
+ *
+ * @param[in] socketFD Socket descriptor used for sending secured (encrypted) UDP data.
+ *
+ */
+void CAEthernetSetSecureUnicastSocket(const int32_t socketFD);
+
+#ifdef ARDUINO
+/**
* @fn CAEthernetSendUnicastData
* @brief API to send unicast UDP data
*
* @param[in] data Data to be send.
* @param[in] dataLength Length of data in bytes
* @param[in] isMulticast whether data needs to be sent to multicast ip
- * @param[out] sentLength Number of bytes actually sent
+ * @param[in] isSecure Indicate the whether data needs to be send on secure channel.
+ * @isSecure will be ignored when @isMulticast is true.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+
+uint32_t CAEthernetSendData(const char *remoteAddress, const int16_t port,
+ const char *buf, const uint32_t bufLen, bool isMulticast);
+
+#else
+/**
+ * @fn CAEthernetSendUnicastData
+ * @brief API to send unicast UDP data
+ *
+ * @param[in] remoteAddress IP address to which data needs to be send.
+ * @param[in] port Port to which data needs to be send.
+ * @param[in] data Data to be send.
+ * @param[in] dataLength Length of data in bytes
+ * @param[in] isMulticast whether data needs to be sent to multicast ip
+ * @param[in] isSecure Indicate the whether data needs to be send on secure channel.
+ * @isSecure will be ignored when @isMulticast is true.
*
* @return #CA_STATUS_OK on success otherwise proper error code.
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_FAILED Operation failed
*/
uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
- const void *data, const uint32_t dataLength, bool isMulticast);
+ const void *data, const uint32_t dataLength,
+ CABool_t isMulticast, CABool_t isSecure);
+
+#endif //ARDUINO
/**
* @fn CAEthernetConnectionStateChangeCallback
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Initialization failed
*/
+#ifndef ARDUINO
CAResult_t CAEthernetInitializeNetworkMonitor(const u_thread_pool_t threadPool);
-#ifdef ARDUINO
+#else
/**
* @fn CAEthernetInitializeServer
* @brief API to initialize Ethernet server
* @param length [IN] length of the data that needs to be sent
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CASendUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t length);
+CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t length);
/**
* @brief Sends multicast data to all endpoints in the network.
* @file cainterfacecontroller_singlethread.h
* @brief This file contains the APIs for the interface controller
*/
+
#ifndef __CA_INTERFACE_CONTROLLER_SINGLETHREAD_H_
#define __CA_INTERFACE_CONTROLLER_SINGLETHREAD_H_
{
#endif
+/**
+ * @brief Initializes different adapters based on the compilation flags.
+ * @param handle [IN] thread pool handle created by message handler for different adapters.
+ * @return none
+ */
void CAInitializeAdapters();
+/**
+ * @brief Set the received packets callback for message handler
+ * @param callback [IN] message handler callback to receive packets from different adapters.
+ * @return none
+ */
void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback);
+/**
+ * @brief Set the network status changed callback for message handler
+ * @param callback [IN] message handler network status callback to receive network changes.
+ * @return none
+ */
void CASetNetworkChangeCallback(CANetworkChangeCallback callback);
+/**
+ * @brief Starting different connectivity adapters based on the network selection.
+ * @param connectivity [IN] interested network for starting
+ * @return none
+ */
void CAStartAdapter(CAConnectivityType_t connectivity);
+/**
+ * @brief Stopping different connectivity adapters based on the network un-selection.
+ * @param callback [IN] un selected network for stopping the packets transfer
+ * @return none
+ */
void CAStopAdapter(CAConnectivityType_t connectivity);
+/**
+ * @brief Get network information such as ipaddress and mac information
+ * @param info [OUT] connectivity information such as ipaddress and mac information
+ * @param size [OUT] number of connectivity information structures
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size);
+/**
+ * @brief Sends unicast data to the remote endpoint
+ * @param endpoint [IN] endpoint information where the data has to be sent
+ * @param data [IN] data that needs to be sent
+ * @param length [IN] length of the data that needs to be sent
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t length);
+/**
+ * @brief Sends multicast data to all endpoints in the network.
+ * @param data [IN] data that needs to be sent
+ * @param length [IN] length of the data that needs to be sent
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CASendMulticastData(void *data, uint32_t length);
+/**
+ * @brief Start listening servers to receive search requests from clients
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CAStartListeningServerAdapters();
+/**
+ * @brief Start discovery servers to receive advertisements from server
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CAStartDiscoveryServerAdapters();
+/**
+ * @brief Terminates the adapters which are initialized during the initialization
+ * @return none
+ */
void CATerminateAdapters();
+/**
+ * @brief Checks for available data and reads it
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CAReadData();
#ifdef __cplusplus
#include "cacommon.h"
#include "caadapterinterface.h"
-#include "uthreadpool.h"
+#ifndef ARDUINO
+#include "uthreadpool.h" /* for thread pool */
+#endif //ARDUINO
/**
* BLE Interface APIs.
#endif
/**
- * @brief Initialize LE connectivity interface.
+ * @Structure CABLEData
+ * @brief Stores the information of the Data to be sent from the queues.
+ * This structure will be pushed to the sender/receiver queue for processing.
+ */
+typedef struct
+{
+ CARemoteEndpoint_t
+ *remoteEndpoint; /**< Remote endpoint contains the inforamtion of remote device */
+ void *data; /**< Data to be transmitted over LE tranport */
+ uint32_t dataLen; /**< Length of the data being transmitted */
+} CABLEData;
+
+/** @brief Initialize LE connectivity interface.
* @param registerCallback [IN] To register LE interfaces to Connectivity Abstraction Layer
* @param reqRespCallback [IN] sending responses and discovery messages from unicast , \
* multicast servers
* @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-
+#ifdef ARDUINO
+CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback reqRespCallback,
+ CANetworkChangeCallback netCallback);
+#else
CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
CANetworkPacketReceivedCallback reqRespCallback,
CANetworkChangeCallback netCallback,
u_thread_pool_t handle);
+#endif //#ifdef ARDUINO
+
/**
* @brief Starting LE connectivity adapters . \
* As its peer to peer it doesnot require to start any servers
* @brief Sends data to the endpoint using the adapter connectivity.
* Note: length must be > 0.
* @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \
- * and connectivity type) to which the unicast data has to be sent.
+ * and connectivity type) to which the unicast data has to be sent.
* @param data [IN] Data which required to be sent.
* @param dataLen [IN] Size of data to be sent.
* @return - The number of bytes sent on the network. Return value equal to zero indicates error.
*/
-uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
+uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t dataLen);
/**
* @brief Sends Multicast data to the endpoint using the LE connectivity.
* @brief Send notification information.
* Note: length must be > 0.
* @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri \
- * and connectivity type) to which the unicast data has to be sent.
+ * and connectivity type) to which the unicast data has to be sent.
* @param data [IN] Data which required to be sent.
* @param dataLen [IN] Size of data to be sent.
* @return - The number of bytes sent on the network. Return value equal to zero indicates error.
*/
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
+uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t dataLen);
/**
* @brief Get LE Connectivity network information
*/
void CATerminateLE();
+CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength);
+
+CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength);
+
+void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback);
+
+CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
+ void *data, uint32_t dataLen);
+
+CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
+ void *data, uint32_t dataLen);
+
+void CABLEClientSendDataThread(void *threadData);
+
+void CABLEClientDataReceiverHandler(void *threadData);
+
+void CATerminateBleQueues();
+
+CAResult_t CAInitBleClientReceiverQueue();
+
+CAResult_t CAInitBleServerReceiverQueue();
+
+void CAInitBleQueues();
+
+void CATerminateBleQueues();
+
+CAResult_t CAInitBleServerQueues();
+
+CAResult_t CAInitBleClientQueues();
+
+CAResult_t CAInitBleServerSenderQueue();
+
+CAResult_t CAInitBleClientSenderQueue();
+
+
+
+/**
+ * @fn CABLEDataReceiverHandler
+ * @brief This function handles data from recv message queue.
+ */
+void CABLEServerDataReceiverHandler(void *context);
+
+/**
+ * @fn CABLESendDataThread
+ * @brief This function handles data from sender message queue.
+ */
+void CABLEServerSendDataThread(void *threadData);
+
+/**
+* @fn CACreateBLEData
+* @brief This function will create the Data required to send it in the queue.
+*
+* @param[in] remoteEndpoint Remote endpoint information of the server.
+* @param[in] data Data to be transmitted from LE.
+* @param[in] length of the Data being transmitted.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*
+*/
+CABLEData *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength);
+
+/**
+* @fn CAFreeBLEData
+* @brief Used to free the BLE information stored in the sender/receiver queues.
+*
+* @param[in] bleData Structure contains the information of a particular data segment.
+*
+* @return none.
+*/
+void CAFreeBLEData(CABLEData *bleData);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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 caleadapter_singlethread.h
- * @brief This file contains the APIs for LE adapters to be implemented
- */
-#ifndef _CA_LEADAPTER_SINGLETHREAD_H_
-#define _CA_LEADAPTER_SINGLETHREAD_H_
-
-#include "cacommon.h"
-#include "caadapterinterface.h"
-
-/**
- * BLE Interface APIs.
- */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief Initialize LE connectivity interface.
- * @param registerCallback [IN] To register LE interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers
- * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback);
-
-/**
- * @brief Starting LE connectivity adapters .As its peer to peer it doesnot require to start any servers
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartLE();
-
-/**
- * @brief Starting listening server for receiving multicast search requests
- * Transport Specific Behavior:
- * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartLEListeningServer();
-
-/**
- * @brief for starting discovery servers for receiving multicast advertisements
- * Transport Specific Behavior:
- * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartLEDiscoveryServer();
-
-/**
- * @brief Sends data to the endpoint using the adapter connectivity.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
-
-/**
- * @brief Sends Multicast data to the endpoint using the LE connectivity.
- * Note: length must be > 0.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendLEMulticastData(void *data, uint32_t dataLen);
-
-/**
- * @brief Starts notification server on EDR adapters.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartLENotifyServer();
-
-/**
- * @brief Send notification information.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
-
-/**
- * @brief Get LE Connectivity network information
- * @param info [OUT] Local connectivity information structures
- * @param size [OUT] Number of local connectivity structures.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
-
-/**
- * @brief Read Synchronous API callback.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAReadLEData();
-
-/**
- * @brief Stopping the adapters and close socket connections
- * LE Stops all GATT servers and close sockets.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStopLE();
-
-/**
- * @brief Terminate the LE connectivity adapter.
- * Configuration information will be deleted from further use
- */
-void CATerminateLE();
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif //#ifndef _CA_LEADAPTER_H_
{
#endif
-typedef void (*CAPacketReceiveCallback)(const char* address, const char* data);
+typedef void (*CAPacketReceiveCallback)(const char *address, const char *data);
void CALEInitialize(u_thread_pool_t handle);
void CALETerminate();
-int32_t CALESendUnicastMessage(const char* address, const char* data, uint32_t dataLen);
+int32_t CALESendUnicastMessage(const char *address, const char *data, uint32_t dataLen);
-int32_t CALESendMulticastMessage(const char* data, uint32_t dataLen);
+int32_t CALESendMulticastMessage(const char *data, uint32_t dataLen);
-int32_t CALEStartUnicastServer(const char* address);
+int32_t CALEStartUnicastServer(const char *address);
int32_t CALEStartMulticastServer();
void CALESetCallback(CAPacketReceiveCallback callback);
-void CALEGetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size);
+void CALEGetInterfaceInfo(CALocalConnectivity_t **info, uint32_t *size);
-void CAGetLocalAddress(char* address);
+void CAGetLocalAddress(char *address);
-int32_t CALESendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen);
+int32_t CALESendUnicastMessageImpl(const char *address, const char *data, uint32_t dataLen);
-int32_t CALESendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen);
+int32_t CALESendMulticastMessageImpl(JNIEnv *env, const char *data, uint32_t dataLen);
/**
* BT Common Method : JNI
void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback);
-jobject CANativeGetUUIDObject(JNIEnv *env, const char* uuid);
+jobject CANativeGetUUIDObject(JNIEnv *env, const char *uuid);
void CANativeLEStopScan();
void CANativeLEStopScanImpl(JNIEnv *env, jobject callback);
void CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context, jboolean autoconnect,
- jobject callback);
+ jobject callback);
void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt);
void CANativeAddScanDeviceToList(JNIEnv *env, jobject device);
-jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress);
+jboolean CANativeIsDeviceInList(JNIEnv *env, const char *remoteAddress);
void CANativeRemoveAllDevices(JNIEnv *env);
void CANativeAddGattobjToList(JNIEnv *env, jobject gatt);
-jboolean CANativeIsGattObjInList(JNIEnv *env, const char* remoteAddress);
+jboolean CANativeIsGattObjInList(JNIEnv *env, const char *remoteAddress);
void CANativeRemoveAllGattObjsList(JNIEnv *env);
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 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 caleinterface.h
+ * @brief This file provides APIs for BLE modules
+ */
+
+#ifndef _CA_LE_INTERFACE_
+#define _CA_LE_INTERFACE_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @ENUM TRANSFER_TYPE
+ * @brief Provide info about different mode of data transfer
+ *
+ * This enum is used to differentiate between unicast and multicast data transfer.
+ */
+typedef enum
+{
+ MULTICAST, /**< When this enum is selected, data will be updated to all OIC servers. */
+ UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */
+} TRANSFER_TYPE;
+
+/**
+* @fn CAStartBleGattServer
+* @brief Used to start Gatt Server thread for service creation and advertise ble service.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAStartBleGattServer();
+
+/**
+* @fn CAStopBleGattServer
+* @brief Used to terminate BLE Gatt Service.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAStopBleGattServer();
+
+/**
+* @fn CASetBLEReqRespServerCallback
+* @brief used to store upper layer callback locally which will be used to send the data
+* to application
+* @param[in] CANetworkPacketReceivedCallback - upper layer callback function
+* to pass the data to CA layer.
+* @return void
+*/
+void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback);
+
+/**
+* @fn CAUpdateCharacteristicsInGattServer
+* @brief Used to update characteristics(Read/Write) value that we want to send to particular client.
+* Both unicast and multicast will use the same api. In mulicast, we will be sending in loop to all clients.
+*
+* @param[in] charValue - data that we want to send to client(unicast)/clients(multicast)
+* @param[in] charValueLen - length of the data.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, const uint32_t charValueLen);
+
+/**
+* @fn CAStartBLEGattClient
+* @brief Used to start CAStartBleGattClientThread for initializing Gatt Client
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAStartBLEGattClient();
+
+/**
+* @fn CAStopBLEGattClient
+* @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient function.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+void CAStopBLEGattClient();
+
+/**
+* @fn CATerminateBLEGattClient
+* @brief Used to unset all the callbacks and stop service discovery
+*
+* @return void
+*/
+void CATerminateBLEGattClient();
+
+/**
+* @fn CAUpdateCharacteristicsToGattServer
+* @brief Sets the value of characteristic and update the value to GATTServer(unicast).
+*
+* @param[in] remoteAddress The address of the remote device
+* @param[in] data The value of characteristic (byte array)
+* @param[in] dataLen The length of value
+* @param[in] TRANSFER_TYPE (UNICAST/MULTICAST)
+* @param[in] position The unique index of each ble server. Used for multicast feature.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
+*/
+CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
+ const int32_t dataLen, TRANSFER_TYPE type, const int32_t position);
+
+/**
+ * @fn CAUpdateCharacteristicsToAllGattServers
+ * @brief Sets the value of characteristic and update the value to All registered GATTServer -> Multicast
+ *
+ * @param[in] data The value of characteristic (byte array)
+ * @param[in] dataLen The length of value
+ *
+ * @return 0 on success otherwise a positive error value.
+ * @retval CA_STATUS_OK Successful
+ * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+ * @retval CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, const int32_t dataLen);
+
+/**
+ * @fn CASetBLEReqRespClientCallback
+ * @brief used to store upper layer callback locally which will be used to send the data to application
+ *
+ * @param[in] CANetworkPacketReceivedCallback - upper layer callback function to pass the data to CA layer.
+ *
+ * @return void
+ */
+void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_LE_INTERFACE_
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint,
- const CARequestInfo_t *request);
+ const CARequestInfo_t *request);
/**
* @brief Detaches control from the caller for sending multicast request
* @param request [IN] request that needs to be sent
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t* object,
- const CARequestInfo_t* request);
+CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t *object,
+ const CARequestInfo_t *request);
/**
* @brief Detaches control from the caller for sending response
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint,
- const CAResponseInfo_t *response);
+ const CAResponseInfo_t *response);
/**
* @brief Detaches control from the caller for sending request
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
- const CAHeaderOption_t* options, uint8_t numOptions);
+ const CAHeaderOption_t *options, uint8_t numOptions);
/**
* @brief Setting the request and response callbacks for network packets
* @param RespHandler [IN] callback for receiving the response
* @return void
*/
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler,
- CAResponseCallback RespHandler);
+void CASetRequestResponseCallbacks(CARequestCallback ReqHandler,
+ CAResponseCallback RespHandler);
/**
* @brief Initialize the message handler by starting thread pool and initializing the send and reive queue
* limitations under the License.
*
******************************************************************/
+
+/**
+ * @file camessagehandler_singlethread.h
+ * @brief This file contains message functionality.
+ */
+
#ifndef __CA_MESSAGE_HANDLER_H_
#define __CA_MESSAGE_HANDLER_H_
#include <stdint.h>
#include "cacommon.h"
#include "cainterface.h"
+#include "caretransmission_singlethread.h"
#ifdef __cplusplus
extern "C"
{
#endif
+/**
+ * @brief Function pointer for message handler callback
+ */
typedef void (*CAMessageHandlerCallback)(CAToken_t token, CAResult_t res);
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request);
+/**
+ * @brief Detaches control from the caller for sending unicast request
+ * @param endpoint [IN] endpoint information where the data has to be sent
+ * @param request [IN] request that needs to be sent
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object,
+ const CARequestInfo_t *request);
+
+/**
+ * @brief Detaches control from the caller for sending response
+ * @param endpoint [IN] endpoint information where the data has to be sent
+ * @param response [IN] request that needs to be sent
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
const CAResponseInfo_t *response);
-CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token, const CAHeaderOption_t *options,
- uint8_t numOptions);
+/**
+ * @brief Detaches control from the caller for sending request
+ * @param resourceUri [IN] resource uri that needs to be sent in the request
+ * @param token [IN] token information of the request
+ * @param options [IN] header options that need to be append in the request
+ * @param numOptions [IN] number of options be appended
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
+ const CAHeaderOption_t *options, uint8_t numOptions);
+
+/**
+ * @brief Setting the message callback
+ * @param callback [IN] callback will be called after data is processed
+ * @return void
+ */
void CASetMessageHandlerCallback(CAMessageHandlerCallback callback);
+/**
+ * @brief Setting the request and response callbacks for network packets
+ * @param ReqHandler [IN] callback for receiving the requests
+ * @param RespHandler [IN] callback for receiving the response
+ * @return void
+ */
void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+/**
+ * @brief Initialize the message handler by starting thread pool and initializing the send and reive queue
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
CAResult_t CAInitializeMessageHandler();
+/**
+ * @brief Terminate the message handler by stopping the thread pool and destroying the queues
+ * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
void CATerminateMessageHandler();
+/**
+ * @brief Handler for receiving request and response callback in singled thread model
+ */
void CAHandleRequestResponseCallbacks();
#ifdef __cplusplus
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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.
- *
- ******************************************************************/
-
-#ifndef _CA_MESSAGE_QUEUE_H_
-#define _CA_MESSAGE_QUEUE_H_
-
-#include "umutex.h"
-#include "cacommon.h"
-#include "uqueue.h"
-
-/**
- @brief Adapter message information
- */
-typedef struct CAAdapterMessage_t
-{
- CARemoteEndpoint_t *remoteEndpoint;
- void *data;
- uint32_t dataLen;
-} CAAdapterMessage_t;
-
-/**
- @brief Adapter message queue
- */
-typedef struct
-{
- u_mutex queueMutex;
- u_queue_t *queue;
-} CAAdapterMessageQueue_t;
-
-/**
- * @brief API to initialize Message queue.
- * @param queueHandle will be set on successfull initialization of message queue.
- * This param to be passed in all subsequent calls to queue handling api's.
- * @return Error Code
- */
-CAResult_t CAAdapterInitializeMessageQueue(CAAdapterMessageQueue_t **queueHandle);
-
-/**
- * @brief API to terminate Message queue.
- * This api will delete entire message queue and will take care of freeing all memory.
- * queueHandle will become invalid after this api call.
- * @param queueHandle handle of queue obtained via CAAdapterInitializeMessageQueue()
- */
-void CAAdapterTerminateMessageQueue(CAAdapterMessageQueue_t *queueHandle);
-
-/**
- * @brief API to add Message to queue.
- * This api will duplicate all passed arguments and add entry to end of message queue.
- * @param queueHandle handle of queue obtained via CAAdapterInitializeMessageQueue()
- * @param remoteEndpoint remoteEndpoint from which data is received or is supposed to be sent.
- * Would be NULL for outgoing multicast data.
- * @param data Data that is received or supposed to be sent.
- * @param dataLen Data length.
- * @return Error Code
- */
-CAResult_t CAAdapterEnqueueMessage(CAAdapterMessageQueue_t *queueHandle,
- const CARemoteEndpoint_t *remoteEndpoint,
- void *data, uint32_t dataLen);
-
-/**
- * @brief API to get oldest message and remove it from the queue
- * @param queueHandle handle of queue obtained via CAAdapterInitializeMessageQueue()
- * @param message oldest message in queue. To be freed by caller using CAAdapterFreeMessage() api.
- * @return Error Code
- */
-CAResult_t CAAdapterDequeueMessage(CAAdapterMessageQueue_t *queueHandle,
- CAAdapterMessage_t **message);
-
-/**
- * @brief API to help caller free the message obtained via CAAdapterDequeueMessage() api.
- * @param message to be freed.
- */
-void CAAdapterFreeMessage(CAAdapterMessage_t *message);
-
-#endif //#ifndef _CA_MESSAGE_QUEUE_H_
-
-
#include "cacommon.h"
#include "logger.h"
+/**
+ * @var MAX_DATA_LENGTH_SUPPORTED
+ * @brief From the adapter level, this is the maximum data length is supported
+ * for the data transmission.
+ */
#define MAX_DATA_LENGTH_SUPPORTED 4095
+
+/**
+ * @var NUMBER_OF_BITS_TO_IDENTIFY_DATA
+ * @brief The number of bits allocated to represent data length in header.
+ */
#define NUMBER_OF_BITS_TO_IDENTIFY_DATA 12
+
+/**
+ * @var NUMBER_OF_BITS_IN_CA_HEADER
+ * @brief The length of the header in bits.
+ */
#define NUMBER_OF_BITS_IN_CA_HEADER 15
+
+/**
+ * @var CA_HEADER_LENGTH
+ * @brief The length of the header in bytes.
+ */
#define CA_HEADER_LENGTH 2
#ifdef __TIZEN__
+/**
+ * @var PLATFORM_IDENTIFIER_BIT
+ * @brief Reserved bit to differentiating the platform. Currently not in use.
+ */
#define PLATFORM_IDENTIFIER_BIT 1
+
+/**
+ * @var CA_SUPPORTED_BLE_MTU_SIZE
+ * @brief The MTU supported from Tizen platform for LE adapter.
+ */
#define CA_SUPPORTED_BLE_MTU_SIZE 200
#else // #endif __TIZEN__
+
+/**
+ * @var PLATFORM_IDENTIFIER_BIT
+ * @brief Reserved bit to differentiating the platform. Currently not in use.
+ */
#define PLATFORM_IDENTIFIER_BIT 0
-#define CA_SUPPORTED_BLE_MTU_SIZE 198
+
+/**
+ * @var CA_SUPPORTED_BLE_MTU_SIZE
+ * @brief The MTU supported from Arduino platform for LE adapter.
+ */
+#define CA_SUPPORTED_BLE_MTU_SIZE 200
#endif //#endif __ARDUINO__
+/**
+ * @var HEADER_VERSION
+ * @brief Current Header version.
+ */
#define HEADER_VERSION 1
#ifdef __cplusplus
{
#endif
+/*****************************************************************
+ * @file The CA Header format *
+ * @brief CA Header will be difined by 2 bytes of Header. *
+ * First two bits : Header version *
+ * Third bit nad fourth bit: Reserved and will be set as Zero. *
+ * 5th to 16th bit : 12 bits to provide the length of the data in bits. *
+ * *
+ *****************************************************************/
+
+
/**
* @fn printBinaryFormat
-* @brief
+* @brief This function prints the binary format of one byte of data
+* This functoin is added as debug utility and can be used to check the
+* bits set in header while framing/parsing.
*
-* @return
+* @param[in] data Pointer to the charcter data which needs to be printed.
+*
+* @return 0 on failure and 1 on success.
*/
-void printBinaryFormat(char* data);
-
-
-/**
- * @file The CA Header format
- * @brief CA Header will be difined by 2 bytes of Header.
- * First two bits : Header version
- * Third bit: Reserved and will be set as Zero.
- * Fourth bit : PLATFORM_IDENTIFIER_BIT
- * 5th to 16th bit : 12 bits to provide the length of the data in bits.
- */
+void printBinaryFormat(char *data);
/**
* @fn CAGenerateHeader
-* @brief
+* @brief This function is used to generate the CA specific header to maintain the fragmentation
+* logic. The header sturcture explained above will be formed and returned to the caller.
*
-* @return
+* @param[in] data Pointer to the charcter data which needs to be printed.
+* @param[in] length The total legth of the data which ll be represed from 5th -16th bits
+* in the header.
+*
+* @return 0 on success otherwise a positive error value.
+* @retval CA_STATUS_OK Successful
+* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
+* @retval CA_STATUS_FAILED Operation failed
*/
-CAResult_t CAGenerateHeader(char* header, uint32_t length);
+CAResult_t CAGenerateHeader(char *header, uint32_t length);
/**
* @fn CAParseHeader
-* @brief
+* @brief This function is used to parse the header in the receiver end. This function will
+* provide the information of the total length of the data which has been fragmented.
+*
+* @param[in] header Pointer to the charcter data which contains the header information.
+* Note that pointer should point to two bytes of data header
+* which needs to be parsed.
*
-* @return
*/
-uint32_t CAParseHeader(const char* header);
+uint32_t CAParseHeader(const char *header);
/**
* @fn CAFragmentData
-* @brief
+* @brief This function is used to fragment the data in to the supported MTU and return the
+* data segment.
+* @param[in] data Pointer to the Complete data which needs to be fragmented.
+* @param[in] TotalLen Total length of the data sent from the CA layer. This will be
+* decremented everytime when we call this function for the subsequent
+* time withthe MTU size.
+* @param[in] Offset Initially this value will be zero. Later this value will be represented
+* as the amount of data which has already been fragmented.
*
-* @return
-*/
-uint32_t CAFragmentData(const char* data, char** dataSegment, uint32_t TotalLen,
+* @param[out] dataSegment Memory will be allocated and will be returned to the called
+* with the data. Caller needs to free the memory.
uint32_t offset);
-
-/**
-* @fn CADeFragmentData
-* @brief
*
-* @return
+* @return -1 On error condition.
+* @retval Returns the length of the data which has been fragmented and sent to the upper layer.
*/
-uint32_t CADeFragmentData(const char* datasegment, char** data, uint32_t TotalLen,
- uint32_t offset);
+uint32_t CAFragmentData(const char *data, char **dataSegment, uint32_t TotalLen, uint32_t offset);
#ifdef __cplusplus
} /* extern "C" */
* @param outUri [OUT] uri received in the received pdu
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,
- char *outUri);
+uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,
+ char *outUri);
/**
* @brief extracts response information from received pdu.
* @return 0 or 1 ( CAResult_t error codes in cacommon.h)
*/
uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,
- char *outUri);
+ char *outUri);
/**
* @brief creates pdu from the request information
- * @param code [IN] request or response code
- * @param options [IN] options for the request and response
- * @param outUri [IN] information to create pdu
+ * @param code [IN] request or response code
+ * @param options [IN] options for the request and response
+ * @param outUri [IN] information to create pdu
* @return coap_pdu_t
*/
-coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options,
- const CAInfo_t info);
+coap_pdu_t *CACreatePDUforRequest(const code_t code, coap_list_t *options,
+ const CAInfo_t info);
/**
* @brief creates pdu from the request information and paylod
- * @param code [IN] request or response code alloted
- * @param options [IN] options for the request and response backpacked
- * @param payload [IN] payload for the request or response consumed
- * @param outUri [IN] information to create pdu
+ * @param code [IN] request or response code alloted
+ * @param options [IN] options for the request and response backpacked
+ * @param payload [IN] payload for the request or response consumed
+ * @param outUri [IN] information to create pdu
* @return coap_pdu_t
*/
coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *optlist,
- const char* payload, const CAInfo_t info);
+ const char *payload, const CAInfo_t info);
/**
* @brief parse the URI and creates the options
- * @param uriInfo [IN] uri information
- * @param options [IN] options information
+ * @param uriInfo [IN] uri information
+ * @param options [IN] options information
* @return None
*/
void CAParseURI(const char *uriInfo, coap_list_t **options);
/**
* @brief create option list from header information in the info
- * @param code [IN] uri information
- * @param info [IN] options information
- * @param optlist [IN] options information
+ * @param code [IN] uri information
+ * @param info [IN] options information
+ * @param optlist [IN] options information
* @return None
*/
void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist);
/**
* @brief creates option node from key lenght and data
- * @param key [IN] key for the that needs to be sent
- * @param length [IN] length of the data that needs to be sent
- * @param data [IN] data that needs to be sent
+ * @param key [IN] key for the that needs to be sent
+ * @param length [IN] length of the data that needs to be sent
+ * @param data [IN] data that needs to be sent
* @return created list
*/
-coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length,
- const uint8_t *data);
+coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length,
+ const uint8_t *data);
/**
* @brief order the inserted options
- * @param a [IN] option 1 for insertion
- * @param b [IN] option 2 for insertion
+ * @param a [IN] option 1 for insertion
+ * @param b [IN] option 2 for insertion
* @return 0 or 1
*/
int CAOrderOpts(void *a, void *b);
/**
* @brief number of options count
- * @param opt_iter [IN] option iteration for count
+ * @param opt_iter [IN] option iteration for count
* @return number of options
*/
uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter);
/**
* @brief gets option data
- * @param data [IN] data that is received
- * @param length [IN] length of the data
- * @param result [IN] result of the operation
- * @param buflen [IN] buffer length of the result
- * @param encode_always [IN] encoded data
+ * @param data [IN] data that is received
+ * @param length [IN] length of the data
+ * @param result [IN] result of the operation
+ * @param buflen [IN] buffer length of the result
+ * @param encode_always [IN] encoded data
* @return 0 or 1
*/
uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result, uint32_t buflen,
- uint32_t encode_always);
+ uint32_t encode_always);
/**
* @brief extracts request information from received pdu.
* @param pdu [IN] received pdu
- * @param outCode [OUT] code of the received pdu
- * @param outInfo [OUT] request info structure made from received pdu
- * @param outUri [OUT] uri received in the received pdu
+ * @param outCode [OUT] code of the received pdu
+ * @param outInfo [OUT] request info structure made from received pdu
+ * @param outUri [OUT] uri received in the received pdu
* @return None
*/
-void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,
- char *outUri);
+void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,
+ char *outUri);
/**
* @brief create pdu fromn received data
- * @param data [IN] received data
- * @param length [IN] length of the data received
- * @param outCode [IN] code received
+ * @param data [IN] received data
+ * @param length [IN] length of the data received
+ * @param outCode [IN] code received
* @return None
*/
coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode);
/**
* @brief generates the token
- * @param token [OUT] generated token
+ * @param token [OUT] generated token
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
/**
* @brief destroys the token
- * @param token [IN] generated token
+ * @param token [IN] generated token
* @return none
*/
void CADestroyTokenInternal(CAToken_t token);
/**
* @brief destroy the ca info structure
- * @param info [IN] info structure created from received packet
+ * @param info [IN] info structure created from received packet
* @return none
*/
void CADeinitialize(CAInfo_t *info);
+/**
+ * @brief gets message type from PDU binary data
+ * @param pdu [IN] pdu data
+ * @param size [IN] size of pdu data
+ * @return message type
+ */
+CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void* pdu, uint32_t size);
+
+/**
+ * @brief gets message ID PDU binary data
+ * @param pdu [IN] pdu data
+ * @param size [IN] size of pdu data
+ * @return message ID
+ */
+uint16_t CAGetMessageIdFromPduBinaryData(const void* pdu, uint32_t size);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif
/**Thread function to be invoked**/
-typedef void (*CAThreadTask)(void* threadData);
+typedef void (*CAThreadTask)(void *threadData);
typedef struct
{
/** Variable to inform the thread to stop **/
CABool_t isStop;
/** Que on which the thread is operating. **/
- u_queue_t* dataQueue;
+ u_queue_t *dataQueue;
} CAQueueingThread_t;
/**
* @param task [IN] function to be called for reach data
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t* thread, u_thread_pool_t handle,
- CAThreadTask task);
+CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t *thread, u_thread_pool_t handle,
+ CAThreadTask task);
/**
* @brief Starting the queueing thread
* @param thread [IN] thread data that needs to be started
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CAQueueingThreadStart(CAQueueingThread_t* thread);
+CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread);
/**
* @brief Add queueing thread data for new thread
* @param size [IN] length of the data
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CAQueueingThreadAddData(CAQueueingThread_t* thread, void* data, uint32_t size);
+CAResult_t CAQueueingThreadAddData(CAQueueingThread_t *thread, void *data, uint32_t size);
/**
* @brief Stopping the queueing thread
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CAQueueingThreadStop(CAQueueingThread_t* thread);
+CAResult_t CAQueueingThreadStop(CAQueueingThread_t *thread);
/**
* @brief Terminating the queing thread
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
-CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t* thread);
+CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t *thread);
#ifdef __cplusplus
} /* extern "C" */
* @param endpoint [IN] endpoint information where the data has to be sent
* @return remote endpoint created
*/
-CARemoteEndpoint_t* CACloneRemoteEndpoint(const CARemoteEndpoint_t* endpoint);
+CARemoteEndpoint_t *CACloneRemoteEndpoint(const CARemoteEndpoint_t *endpoint);
/**
* @brief Creates a new remote endpoint from the input uri
* @param uri [IN] absolute uri information to create remote endpoint
* @return remote endpoint created
*/
-CARemoteEndpoint_t* CACreateRemoteEndpointUriInternal(const CAURI_t uri);
+CARemoteEndpoint_t *CACreateRemoteEndpointUriInternal(const CAURI_t uri);
/**
* @brief Creates a new remote endpoint from the input and other information
* @param type [IN] connectivity type of the endpoint
* @return remote endpoint created
*/
-CARemoteEndpoint_t* CACreateRemoteEndpointInternal(const CAURI_t resourceUri,
+CARemoteEndpoint_t *CACreateRemoteEndpointInternal(const CAURI_t resourceUri,
const CAAddress_t addr, const CAConnectivityType_t type);
/**
* @param endpoint [IN] endpoint information where the data has to be sent
* @return none
*/
-void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t* rep);
+void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t *rep);
/**
* @brief Creates a new request information
* @param rep [IN] request information that needs to be duplicated
* @return remote endpoint created
*/
-CARequestInfo_t* CACloneRequestInfo(const CARequestInfo_t* request);
+CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *request);
/**
* @brief Destroy the request information
* @param rep [IN] request information that needs to be destroyed
* @return none
*/
-void CADestroyRequestInfoInternal(CARequestInfo_t* request);
+void CADestroyRequestInfoInternal(CARequestInfo_t *request);
/**
* @brief Creates a new response information
* @param rep [IN] response information that needs to be duplicated
* @return remote endpoint created
*/
-CAResponseInfo_t* CACloneResponseInfo(const CAResponseInfo_t* response);
+CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *response);
/**
* @brief Destroy the response information
* @param rep [IN] response information that needs to be destroyed
* @return
*/
-void CADestroyResponseInfoInternal(CAResponseInfo_t* response);
+void CADestroyResponseInfoInternal(CAResponseInfo_t *response);
#ifdef __cplusplus
} /* extern "C" */
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 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 caretransmission.h
+ * @brief
+ */
+#ifndef __CA_RETRANSMISSION_H_
+#define __CA_RETRANSMISSION_H_
+
+#include <stdint.h>
+
+#include "uthreadpool.h"
+#include "umutex.h"
+#include "uarraylist.h"
+#include "cacommon.h"
+
+/** CA_ETHERNET, CA_WIFI **/
+#define DEFAULT_RETRANSMISSION_TYPE ((1<<0)|(1<<1))
+
+/** default retransmission trying count is 4. **/
+#define DEFAULT_RETRANSMISSION_COUNT 4
+
+/** check period is 1 sec. **/
+#define RETRANSMISSION_CHECK_PERIOD 1000000
+
+/** retransmission data send method type**/
+typedef CAResult_t (*CADataSendMethod_t)(const CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t length);
+
+typedef struct
+{
+ /** retransmission support connectivity type **/
+ CAConnectivityType_t supportType;
+ /** retransmission trying count **/
+ uint8_t tryingCount;
+
+} CARetransmissionConfig_t;
+
+typedef struct
+{
+ /** Thread pool of the thread started **/
+ u_thread_pool_t threadPool;
+ /** mutex for synchrnoization **/
+ u_mutex threadMutex;
+ /** conditional mutex for synchrnoization **/
+ u_cond threadCond;
+ /** send method for retransmission data **/
+ CADataSendMethod_t dataSendMethod;
+ /** retransmission configure data **/
+ CARetransmissionConfig_t config;
+ /** Variable to inform the thread to stop **/
+ CABool_t isStop;
+ /** array list on which the thread is operating. **/
+ u_arraylist_t* dataList;
+} CARetransmission_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+CAResult_t CARetransmissionInitialize(CARetransmission_t* context, u_thread_pool_t handle,
+ CADataSendMethod_t retransmissionSendMethod, CARetransmissionConfig_t* config);
+
+CAResult_t CARetransmissionStart(CARetransmission_t* context);
+
+CAResult_t CARetransmissionSentData(CARetransmission_t* context, const CARemoteEndpoint_t* endpoint,
+ const void* pdu, uint32_t size);
+
+CAResult_t CARetransmissionReceivedData(CARetransmission_t* context,
+ const CARemoteEndpoint_t* endpoint, const void* pdu, uint32_t size);
+
+CAResult_t CARetransmissionStop(CARetransmission_t* context);
+
+CAResult_t CARetransmissionDestroy(CARetransmission_t* context);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif // __CA_RETRANSMISSION_H_
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 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 caretransmission.h
+ * @brief
+ */
+#ifndef __CA_RETRANSMISSION_H_
+#define __CA_RETRANSMISSION_H_
+
+#include <stdint.h>
+
+#include "uarraylist.h"
+#include "cacommon.h"
+
+/** CA_ETHERNET, CA_WIFI **/
+#define DEFAULT_RETRANSMISSION_TYPE ((1<<0)|(1<<1))
+
+/** default retransmission trying count is 4. **/
+#define DEFAULT_RETRANSMISSION_COUNT 4
+
+/** check period is 1 sec. **/
+#define RETRANSMISSION_CHECK_PERIOD 1000000
+
+/** retransmission data send method type**/
+typedef CAResult_t (*CADataSendMethod_t)(const CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t length);
+
+typedef struct
+{
+ /** retransmission support connectivity type **/
+ CAConnectivityType_t supportType;
+ /** retransmission trying count **/
+ uint8_t tryingCount;
+
+} CARetransmissionConfig_t;
+
+typedef struct
+{
+ /** send method for retransmission data **/
+ CADataSendMethod_t dataSendMethod;
+ /** retransmission configure data **/
+ CARetransmissionConfig_t config;
+ /** Variable to inform the thread to stop **/
+ CABool_t isStop;
+ /** array list on which the thread is operating. **/
+ u_arraylist_t* dataList;
+} CARetransmission_t;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+CAResult_t CARetransmissionInitialize(CARetransmission_t* context,
+ CADataSendMethod_t retransmissionSendMethod,
+ CARetransmissionConfig_t* config);
+
+CAResult_t CARetransmissionSentData(CARetransmission_t* context,
+ const CARemoteEndpoint_t* endpoint,
+ const void* pdu, uint32_t size);
+
+CAResult_t CARetransmissionReceivedData(CARetransmission_t* context,
+ const CARemoteEndpoint_t* endpoint, const void* pdu, uint32_t size);
+
+CAResult_t CARetransmissionStop(CARetransmission_t* context);
+
+CAResult_t CARetransmissionDestroy(CARetransmission_t* context);
+
+void CACheckRetransmissionList();
+
+void CARetransmissionBaseRoutine(void *threadValue);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif // __CA_RETRANSMISSION_H_
#include "cacommon.h"
#include "caadapterinterface.h"
+#ifndef ARDUINO
#include "uthreadpool.h" /* for thread pool */
+#endif //ARDUINO
#ifdef __cplusplus
extern "C"
* @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
* @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
*/
+#ifdef ARDUINO
+CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback networkPacketCallback,
+ CANetworkChangeCallback netCallback);
+#else
CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
CANetworkPacketReceivedCallback networkPacketCallback,
CANetworkChangeCallback netCallback, u_thread_pool_t handle);
+#endif
/**
* @brief Start WiFi Interface adapter.
* @param dataLen [IN] Size of data to be sent.
* @return - The number of bytes sent on the network. Return value equal to zero indicates error.
*/
-uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen);
+uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t dataLen);
/**
* @brief Sends Multicast data to the endpoint using the WIFI connectivity.
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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 cawifiadapter.h
- * @brief This file contains the APIs for WiFi Adapter.
- */
-#ifndef __CA_WIFI_ADAPTER_H__
-#define __CA_WIFI_ADAPTER_H__
-
-#include "cacommon.h"
-#include "caadapterinterface.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief API to initialize WiFi Interface.
- * @param registerCallback [IN] To register WIFI interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback [IN] sending responses and discovery messages from unicast , multicast servers
- * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback networkPacketCallback, CANetworkChangeCallback netCallback);
-
-/**
- * @brief Start WiFi Interface adapter.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartWIFI();
-
-/**
- * @brief Starting listening server for receiving multicast search requests
- * Transport Specific Behavior:
- * WIFI Starts Multicast Server on all available IPs and prefixed port number and as per OIC Specification.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartWIFIListeningServer();
-
-/**
- * @brief for starting discovery servers for receiving multicast advertisements
- * Transport Specific Behavior:
- * WIFI Starts Start multicast server on all available IPs and prefixed port number as per OIC Specification
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartWIFIDiscoveryServer();
-
-/**
- * @brief Sends data to the endpoint using the adapter connectivity.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
-
-/**
- * @brief Sends Multicast data to the endpoint using the WIFI connectivity.
- * Note: length must be > 0.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLen);
-
-/**
- * @brief Starts notification server on WIFI adapters.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartWIFINotifyRecvServers();
-
-/**
- * @brief Send notification information.
- * Note: length must be > 0.
- * @param endpoint [IN] Remote Endpoint information (like ipaddress , port, reference uri and connectivity type) to
- * which the unicast data has to be sent.
- * @param data [IN] Data which required to be sent.
- * @param dataLen [IN] Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendWIFINotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
-/**
- * @brief Get WIFI Connectivity network information
- * @param info [OUT] Local connectivity information structures
- * @param size [OUT] Number of local connectivity structures.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size);
-
-/**
- * @brief Read Synchronous API callback.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAReadWIFIData();
-
-/**
- * @brief Stopping the adapters and close socket connections
- * WIFI Stops all multicast and unicast servers and close sockets.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStopWIFI();
-
-/**
- * @brief Terminate the WIFI connectivity adapter.
- * Configuration information will be deleted from further use
- */
-void CATerminateWIfI();
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif // #ifndef __CA_WIFI_ADAPTER_H__
#include <stdbool.h>
#include "cacommon.h"
+#ifndef ARDUINO
#include "uthreadpool.h"
+#endif //ARDUINO
#ifdef __cplusplus
extern "C"
* @param[in] port Port number on which data is received.
* @param[in] data Data received from remote OIC device.
* @param[in] dataLength Length of data in bytes.
+ * @param[in] secure Indicates the data is secure or not.
*
* @pre Callback must be registered using CAWiFiSetPacketReceiveCallback()
*/
+#ifndef ARDUINO
+typedef void (*CAWiFiPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength, const CABool_t isSecure);
+
+#else
typedef void (*CAWiFiPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
const void *data, const uint32_t dataLength);
+#endif //ARDUINO
/**
* @fn CAWiFiExceptionCallback
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Initialization failed
*/
-CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool);
-
#ifdef ARDUINO
-/**
- * @fn CAWiFiInitializeServer
- * @brief API to initialize Wifi server
- *
- * @return #CA_STATUS_OK on success otherwise proper error code.
- * @retval #CA_STATUS_OK Successful
- * @retval #CA_STATUS_FAILED Initialization failed
- */
+
CAResult_t CAWiFiInitializeServer(void);
+
+#else
+
+CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool);
+
#endif //ARDUINO
/**
* @param[in][out] port Port number on which server to be running.
* Port number on which server actually started will be returned.
* @param[in] forceStart Indicate whether to start server forcesfully on specified port or not.
+ * @param[in] secured true if the secure server to be started, otherwise false.
* @param[out] serverFD Unicast server socket FD.
*
* @return #CA_STATUS_OK on success otherwise proper error code.
* @retval #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
* @retval #CA_STATUS_FAILED Operation failed
*/
+
+#ifdef ARDUINO
CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
const bool forceStart, int32_t *serverFD);
+#else
+
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, const CABool_t isSecured, int32_t *serverFD);
+#endif //ARDUINO
/**
* @fn CAWiFiStopMulticastServer
*/
CAResult_t CAWiFiStopUnicastServer();
+#ifdef __WITH_DTLS__
+/**
+ * @fn CAWiFiStopSecureUnicastServer
+ * @brief API to stop secured unicast server.
+ *
+ * @return #CA_STATUS_OK on success otherwise proper error code.
+ * @retval #CA_STATUS_OK Successful
+ * @retval #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopSecureUnicastServer();
+#endif
+
/**
* @fn CAWiFiGetUnicastServerInfo
* @brief API to get running unicast server information.
* @remarks @ipAddress must be freed using free().
*
+ * @param[in] secure true if the secure server information needed, otherwise false.
* @param[in] ipAddress IP address on which server is binded and running.
* @param[out] port Port number on which server is running
* @param[out] serverFD Server socket fd.
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Operation failed
*/
+
+#ifdef ARDUINO
+
CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+#else
+
+CAResult_t CAWiFiGetUnicastServerInfo(const CABool_t isSecured, char **ipAddress, int16_t *port,
+ int32_t *serverFD);
+
+#endif // ARDUINO
+
/**
* @fn CAWiFiSetPacketReceiveCallback
* @brief API to set callback for receiving data packets from peer devices.
*/
void CAWiFiSetUnicastSocket(const int32_t socketFD);
+#ifdef __WITH_DTLS__
+/**
+ * @fn CAWiFiSetSecureUnicastSocket
+ * @brief API to set socket description for sending secured (encrypted) unicast UDP data
+ *
+ * @param[in] socketFD Socket descriptor used for sending secured (encrypted) UDP data.
+ *
+ */
+void CAWiFiSetSecureUnicastSocket(const int32_t socketFD);
+#endif
+
/**
* @fn CAWiFiSendUnicastData
* @brief API to send unicast UDP data
* @param[in] data Data to be send.
* @param[in] dataLength Length of data in bytes
* @param[in] isMulticast whether data needs to be sent to multicast ip
- * @param[out] sentLength Number of bytes actually sent
+ * @param[in] isSecure Indicate the whether data needs to be send on secure channel.
+ * @isSecure will be ignored when @isMulticast is true.
*
* @return #CA_STATUS_OK on success otherwise proper error code.
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Operation failed
*/
+
+#ifdef ARDUINO
+
uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
const void *data, const uint32_t dataLength, bool isMulticast);
+#else
+
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength,
+ CABool_t isMulticast, CABool_t isSecured);
+
+#endif //ARDUINO
+
/**
* @fn CAWiFiConnectionStateChangeCallback
* @brief Callback to be notified when wifi adapter connection state changes.
* @retval #CA_STATUS_INVALID_PARAM Invalid input data
* @retval #CA_STATUS_FAILED Initialization failed
*/
+
+#ifndef ARDUINO
+
CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool);
+#else
+
+CAResult_t CAWiFiInitializeNetworkMonitor(void);
+
+#endif //ARDUINO
+
#ifdef ARDUINO
/**
* @fn CAWiFiInitializeServer
}
#endif
-#endif //_CA_WIFI_INTERFACE_
\ No newline at end of file
+#endif //_CA_WIFI_INTERFACE_
* Signature: (Landroid/bluetooth/BluetoothAdapter/LeScanCallback;)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeScanCallback
- (JNIEnv *, jobject, jobject);
+(JNIEnv *, jobject, jobject);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGattCallback;)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattCallback
- (JNIEnv *, jobject, jobject);
+(JNIEnv *, jobject, jobject);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothDevice;I[B)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeScanCallback
- (JNIEnv *, jobject, jobject, jint, jbyteArray);
+(JNIEnv *, jobject, jobject, jint, jbyteArray);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;II)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattConnectionStateChangeCallback
- (JNIEnv *, jobject, jobject, jint, jint);
+(JNIEnv *, jobject, jobject, jint, jint);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;I)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServicesDiscoveredCallback
- (JNIEnv *, jobject, jobject, jint);
+(JNIEnv *, jobject, jobject, jint);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicReadCallback
- (JNIEnv *, jobject, jobject, jobject, jstring, jint);
+(JNIEnv *, jobject, jobject, jobject, jstring, jint);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicWriteCallback
- (JNIEnv *, jobject, jobject, jobject, jstring, jint);
+(JNIEnv *, jobject, jobject, jobject, jstring, jint);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicChangedCallback
- (JNIEnv *, jobject, jobject, jobject, jstring);
+(JNIEnv *, jobject, jobject, jobject, jstring);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorReadCallback
- (JNIEnv *, jobject, jobject, jobject, jint);
+(JNIEnv *, jobject, jobject, jobject, jint);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorWriteCallback
- (JNIEnv *, jobject, jobject, jobject, jint);
+(JNIEnv *, jobject, jobject, jobject, jint);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;I)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReliableWriteCompletedCallback
- (JNIEnv *, jobject, jobject, jint);
+(JNIEnv *, jobject, jobject, jint);
/*
* Class: com_iotivity_jar_CALeInterface
* Signature: (Landroid/bluetooth/BluetoothGatt;II)V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReadRemoteRssiCallback
- (JNIEnv *, jobject, jobject, jint, jint);
+(JNIEnv *, jobject, jobject, jint, jint);
#ifdef __cplusplus
}
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateEnabled
- (JNIEnv *, jclass);
+(JNIEnv *, jclass);
/*
* Class: com_iotivity_jar_CAWiFiInterface
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateDisabled
- (JNIEnv *, jclass);
+(JNIEnv *, jclass);
#ifdef __cplusplus
}
--- /dev/null
+--- Ethernet.cpp 2013-05-17 14:22:15.000000000 -0400
++++ Ethernet.cpp 2014-08-26 11:14:00.083713733 -0400
+@@ -7,13 +7,12 @@
+ 0, 0, 0, 0 };
+ uint16_t EthernetClass::_server_port[MAX_SOCK_NUM] = {
+ 0, 0, 0, 0 };
++static DhcpClass s_dhcp;
+
+ int EthernetClass::begin(uint8_t *mac_address)
+ {
+- static DhcpClass s_dhcp;
+ _dhcp = &s_dhcp;
+
+-
+ // Initialise the basic info
+ W5100.init();
+ W5100.setMACAddress(mac_address);
--- /dev/null
+--- /usr/share/arduino/libraries/Ethernet/utility/socket.cpp 2014-06-13 15:35:45.257740458 -0700
++++ /oc/usr/share/arduino/libraries/Ethernet/utility/socket.cpp 2014-08-10 17:20:30.273142691 -0700
+@@ -248,6 +248,7 @@
+ {
+ uint8_t head[8];
+ uint16_t data_len=0;
++ uint16_t data_copied=0;
+ uint16_t ptr=0;
+
+ if ( len > 0 )
+@@ -268,10 +269,6 @@
+ data_len = head[6];
+ data_len = (data_len << 8) + head[7];
+
+- W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy.
+- ptr += data_len;
+-
+- W5100.writeSnRX_RD(s, ptr);
+ break;
+
+ case SnMR::IPRAW :
+@@ -285,10 +282,6 @@
+ data_len = head[4];
+ data_len = (data_len << 8) + head[5];
+
+- W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy.
+- ptr += data_len;
+-
+- W5100.writeSnRX_RD(s, ptr);
+ break;
+
+ case SnMR::MACRAW:
+@@ -297,17 +290,22 @@
+ data_len = head[0];
+ data_len = (data_len<<8) + head[1] - 2;
+
+- W5100.read_data(s,(uint8_t*) ptr,buf,data_len);
+- ptr += data_len;
+- W5100.writeSnRX_RD(s, ptr);
+ break;
+
+ default :
+ break;
+ }
++
++ if (data_len > 0)
++ {
++ data_copied = (data_len <= len) ? data_len : len;// only copy the len bytes, rest of is discarded.
++ W5100.read_data(s, (uint8_t *)ptr, buf, data_copied); // data copy.
++ ptr += data_len;
++ W5100.writeSnRX_RD(s, ptr);
++ }
+ W5100.execCmdSn(s, Sock_RECV);
+ }
+- return data_len;
++ return data_copied;
+ }
+
+
case 3:
return CA_LE;
}
+ return CA_ETHERNET;
}
void setup()
{
return;
}
endpoint->connectivityType = getConnectivityType();
+
+ memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+ printf("\n=============================================\n");
+ printf("0:CON, 1:NON\n");
+ printf("select message type : ");
+
+ getData(buf, sizeof(buf), &len);
+
+ int32_t msg_type = (CAMessageType_t) (buf[0] == '0' || buf[0] == '1') ? buf[0] - '0' : 0;
+ CAMessageType_t msgType; // = (CAMessageType_t) (buf[0] == '0' || buf[0] == '1') ? buf[0] - '0' : 0;
+ if(msg_type == 0)
+ msgType = CA_MSG_CONFIRM;
+ else if(msg_type == 1)
+ msgType = CA_MSG_NONCONFIRM;
+ else if(msg_type == 2)
+ msgType = CA_MSG_ACKNOWLEDGE;
+ else if(msg_type == 3)
+ msgType = CA_MSG_RESET;
+
+
// create token
CAToken_t token = NULL;
res = CAGenerateToken(&token);
CAInfo_t requestData;
memset(&requestData, 0, sizeof(CAInfo_t));
requestData.token = token;
- requestData.payload = "Json Payload";
+ requestData.payload = (CAPayload_t)"Json Payload";
+
+ requestData.type = msgType;
CARequestInfo_t requestInfo;
memset(&requestInfo, 0, sizeof(CARequestInfo_t));
endpoint->connectivityType = getConnectivityType();
CAInfo_t respondeData;
memset(&respondeData, 0, sizeof(CAInfo_t));
- respondeData.token = "token";
- respondeData.payload = "Notification Data";
+ respondeData.token = (CAToken_t)"token";
+ respondeData.payload = (CAPayload_t)"Notification Data";
CAResponseInfo_t responseInfo;
memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
CAInfo_t responseData;
memset(&responseData, 0, sizeof(CAInfo_t));
responseData.token = request_token;
- responseData.payload = "response payload";
+ responseData.payload = (CAPayload_t)"response payload";
CAResponseInfo_t responseInfo;
memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
CAInfo_t requestData;
memset(&requestData, 0, sizeof(CAInfo_t));
requestData.token = token;
- requestData.payload = "Json Payload";
+ requestData.payload = (CAPayload_t)"Json Payload";
CARequestInfo_t requestInfo;
memset(&requestInfo, 0, sizeof(CARequestInfo_t));
#include "Arduino.h"
#include "caadapterinterface.h"
#include "cacommon.h"
-#include "caleadapter_singlethread.h"
+#include "caleadapter.h"
#include <TimedAction.h>
#include <logger.h>
switch (Serial.read())
{
case 's':
- {
- Serial.println("sending data");
- if ( ble_connected() )
- {
- Serial.println("Sending Data");
- gConnectivityHandlers->sendData(&remoteEndpoint[1], coapData, strlen(coapData));
- Serial.println("Sent Data");
- }
- }
- break;
- }
+ {
+ Serial.println("sending data");
+ if ( ble_connected() )
+ {
+ Serial.println("Sending Data");
+ gConnectivityHandlers->sendData(&remoteEndpoint[1], coapData, strlen(coapData));
+ Serial.println("Sent Data");
+ }
+ }
+ break;
+ }
}
gConnectivityHandlers->readData();
}
#include "Arduino.h"
-#include "cawifiadapter_singlethread.h"
+#include "cawifiadapter.h"
#include <logger.h>
#include "caadapterinterface.h"
memset((void *)remoteEndpoint[i].addressInfo.IP.ipAddress, 0, sizeof(remoteIPAddress) + 1);
strncpy((char *)remoteEndpoint[i].addressInfo.IP.ipAddress, remoteIPAddress,
strlen(remoteIPAddress));
- remoteEndpoint[i].addressInfo.IP.port = 5283; /* Send the corresponding port here */
+ remoteEndpoint[i].addressInfo.IP.port = 5683; /* Send the corresponding port here */
}
remoteMulticastEndpoint.connectivityType = CA_WIFI;
uint32_t size = 0;
tempConnectivityHandlers->handler.GetnetInfo(&localWifiEndpoint, &size);
OIC_LOG(DEBUG, MOD_NAME, "tempConnectivityHandlers ->NetInfoCallback");
- localWifiEndpoint->addressInfo.IP.port = 5283;
- OIC_LOG(DEBUG, MOD_NAME, "LocalWiFiEndPoint Port is 5283");
+ localWifiEndpoint->addressInfo.IP.port = 5683;
+ OIC_LOG(DEBUG, MOD_NAME, "LocalWiFiEndPoint Port is 5683");
OIC_LOG(DEBUG, MOD_NAME, "Local Address = ");
OIC_LOG(DEBUG, MOD_NAME, localWifiEndpoint->addressInfo.IP.ipAddress);
tempConnectivityHandlers->handler.startAdapter();
strncpy(readIpAddress, (Serial.readStringUntil('\n')).c_str(), 20);
strncpy((char *)remoteEndpoint[0].addressInfo.IP.ipAddress, readIpAddress,
strlen(readIpAddress));
- remoteEndpoint[0].addressInfo.IP.port = 5283;
+ remoteEndpoint[0].addressInfo.IP.port = 5683;
ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
if (NULL == tempConnectivityHandlers)
#4 execute sample.sh in "connectivity/samples/linux/" folder
ex. $./sample.sh (This will make a clean build and execute application)
+#4 execute sample.sh in if you want to build with DTLS
+ ex. $./sample.sh WITH_DTLS (This will make a clean build and execute application)
+
+
cd ../../build/linux
make clean
+if echo $1 | grep -q -i "WITH_DTLS"
+then
+make DTLS=1
+else
make
+fi
cd ../../samples/linux
make clean
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#include <unistd.h>
#include "cacommon.h"
#include "cainterface.h"
+
#define MAX_BUF_LEN 1024
#define MAX_OPT_LEN 16
#define TRUE 1
#define FALSE 0
+/**
+ * @def RS_IDENTITY
+ * @brief
+ */
+#define IDENTITY ("1111111111111111")
+
+/**
+ * @def RS_CLIENT_PSK
+ * @brief
+ */
+#define RS_CLIENT_PSK ("AAAAAAAAAAAAAAAA")
+
+
+int gReceived;
+CABool_t gLocalUnicastPort;
+CABool_t gLocalSecurePort;
+
char get_menu();
void process();
void find_fixed_resource();
void get_network_info();
-void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
-void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
-void send_request_tmp(CARemoteEndpoint_t* endpoint, CAToken_t token);
-int received = FALSE;
+void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
+void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token);
+void get_resource_uri(char *URI, char *resourceURI, int length);
+int get_secure_information(CAPayload_t payLoad);
static CAToken_t gLastRequestToken = NULL;
+static const char *gSecureInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
+ "\"if\":[\"oc.mi.def\"],\"obs\":1,\"sec\":1,\"port\":%d}}]}";
+static const char *gNormalInfoData = "{\"oc\":[{\"href\":\"%s\",\"prop\":{\"rt\":[\"core.led\"],"
+ "\"if\":[\"oc.mi.def\"],\"obs\":1}}]}";
+
+
+static CADtlsPskCredsBlob_t *pskCredsBlob = NULL;
+
+
+void clearDtlsCredentialInfo()
+{
+ printf("clearDtlsCredentialInfo IN\n");
+ if (pskCredsBlob)
+ {
+ // Initialize sensitive data to zeroes before freeing.
+ memset(pskCredsBlob->creds, 0, sizeof(CADtlsPskCreds_t)*(pskCredsBlob->num));
+ free(pskCredsBlob->creds);
+
+ memset(pskCredsBlob, 0, sizeof(CADtlsPskCredsBlob_t));
+ free(pskCredsBlob);
+ pskCredsBlob = NULL;
+ }
+ printf("clearDtlsCredentialInfo OUT\n");
+}
+
+// Internal API. Invoked by OC stack to retrieve credentials from this module
+void CAGetDtlsPskCredentials(CADtlsPskCredsBlob_t **credInfo)
+{
+ printf("CAGetDtlsPskCredentials IN\n");
+
+ *credInfo = pskCredsBlob;
+
+ printf("CAGetDtlsPskCredentials OUT\n");
+}
+
+int32_t SetCredentials()
+{
+ printf("SetCredentials IN\n");
+ pskCredsBlob = (CADtlsPskCredsBlob_t *)malloc(sizeof(CADtlsPskCredsBlob_t));
+
+ memset(pskCredsBlob, 0x0, sizeof(CADtlsPskCredsBlob_t));
+ memcpy(pskCredsBlob->rsIdentity, IDENTITY, DTLS_PSK_ID_LEN);
+
+ pskCredsBlob->num = 1;
+
+ pskCredsBlob->creds = (CADtlsPskCreds_t *)malloc(sizeof(CADtlsPskCreds_t) *(pskCredsBlob->num));
+
+ memcpy(pskCredsBlob->creds[0].clientIdentity, IDENTITY, DTLS_PSK_ID_LEN);
+ memcpy(pskCredsBlob->creds[0].rsClientPsk, RS_CLIENT_PSK, DTLS_PSK_PSK_LEN);
+
+ printf("SetCredentials OUT\n");
+ return 1;
+}
int main()
{
printf("\t\tsample main\n");
printf("=============================================\n");
+ /*
+ * Read DTLS PSK credentials from persistent storage and
+ * set in the OC stack.
+ */
+ if (SetCredentials() == 0)
+ {
+ printf("SetCredentials failed\n");
+ return 0;
+ }
+
CAResult_t res = CAInitialize();
if (res != CA_STATUS_OK)
{
process();
CATerminate();
+ clearDtlsCredentialInfo();
return 0;
}
case 'Y':
while (1)
{
- received = FALSE;
+ gReceived = 0;
find_fixed_resource();
- while (received == FALSE)
+ while (gReceived == 0)
{
sleep(1);
handle_request_response();
}
+
+
void start_listening_server()
{
printf("start listening server!!\n");
{ 0, };
strcpy(buf, "a/light");
-
-
// create token
CAToken_t token = NULL;
CAResult_t res = CAGenerateToken(&token);
// delete token
/*
- if (token != NULL)
- {
- CADestroyToken(token);
- }
- */
+ if (token != NULL)
+ {
+ CADestroyToken(token);
+ }
+ */
printf("=============================================\n");
}
// delete token
/*
- if (token != NULL)
- {
- CADestroyToken(token);
- }
- */
+ if (token != NULL)
+ {
+ CADestroyToken(token);
+ }
+ */
printf("=============================================\n");
}
void send_request()
{
- char buf[MAX_BUF_LEN];
-
- memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
-
- printf("\n=============================================\n");
- printf("10.11.12.13:4545/resource_uri ( for IP )\n");
- printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
- printf("uri : ");
+ char secureRequest[2] = {0};
+ printf("Do you want to send secure request ?.... enter (0/1): ");
+ gets(secureRequest);
+ if ('1' == secureRequest[0])
+ {
+ printf("Enter the URI like below....\n");
+ printf("coaps://10.11.12.13:4545/resource_uri ( for IP secure)\n");
+ }
+ else
+ {
+ printf("Enter the URI like below....\n");
+ printf("coap://10.11.12.13:4545/resource_uri ( for IP )\n");
+ printf("coap://10:11:12:13:45:45/resource_uri ( for BT )\n");
+ }
- gets(buf);
+ char uri[MAX_BUF_LEN] = {'\0'};
+ gets(uri);
// create remote endpoint
- CARemoteEndpoint_t* endpoint = NULL;
- CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint);
-
- if (res != CA_STATUS_OK)
+ CARemoteEndpoint_t *endpoint = NULL;
+ if (CA_STATUS_OK != CACreateRemoteEndpoint(uri, &endpoint)
+ || !endpoint)
{
- printf("create remote endpoint error!!\n");
+ printf("Failed to create remote endpoint!\n");
CADestroyRemoteEndpoint(endpoint);
return;
}
+ char buf[MAX_BUF_LEN];
+ memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+ printf("\n=============================================\n");
+ printf("0:CON, 1:NON\n");
+ printf("select message type : ");
+
+ gets(buf);
+
+ CAMessageType_t msgType = (buf[0] == '0' || buf[0] == '1') ? buf[0] - '0' : 0;
+
// create token
CAToken_t token = NULL;
- res = CAGenerateToken(&token);
-
- if (res != CA_STATUS_OK)
+ if (CA_STATUS_OK != CAGenerateToken(&token))
{
printf("token generate error!!\n");
token = NULL;
printf("generated token %s\n", (token != NULL) ? token : "");
+ // extract relative resourceuri from give uri
+ char resourceURI[15] = {0};
+
+ printf("URI : %s\n", uri);
+ get_resource_uri(uri, resourceURI, 14);
+
+ // create request data
CAInfo_t requestData;
memset(&requestData, 0, sizeof(CAInfo_t));
requestData.token = token;
- requestData.payload = "Temp Json Payload";
- requestData.type = CA_MSG_NONCONFIRM;
+ if ('1' == secureRequest[0])
+ {
+ int length = strlen(gSecureInfoData) + strlen(resourceURI) + 1;
+ requestData.payload = (CAPayload_t) malloc(length);
+ sprintf(requestData.payload, gSecureInfoData, resourceURI, gLocalSecurePort);
+ }
+ else
+ {
+ int length = strlen(gNormalInfoData) + strlen(resourceURI) + 1;
+ requestData.payload = (CAPayload_t) malloc(length);
+ sprintf(requestData.payload, gNormalInfoData, resourceURI);
+ }
+ requestData.type = msgType;
CARequestInfo_t requestInfo;
memset(&requestInfo, 0, sizeof(CARequestInfo_t));
}
// destroy remote endpoint
- if (endpoint != NULL)
- {
- CADestroyRemoteEndpoint(endpoint);
- }
-
+ CADestroyRemoteEndpoint(endpoint);
printf("=============================================\n");
}
gets(buf);
// create remote endpoint
- CARemoteEndpoint_t* endpoint = NULL;
+ CARemoteEndpoint_t *endpoint = NULL;
CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint);
if (res != CA_STATUS_OK)
}
- CAGroupEndpoint_t* group = NULL;
- group = (CAGroupEndpoint_t*)malloc(sizeof(CAGroupEndpoint_t));
+ CAGroupEndpoint_t *group = NULL;
+ group = (CAGroupEndpoint_t *)malloc(sizeof(CAGroupEndpoint_t));
group->connectivityType = endpoint->connectivityType;
group->resourceUri = endpoint->resourceUri;
-
+
// create token
CAToken_t token = NULL;
printf("Option Num : ");
scanf("%d", &optionNum);
CAHeaderOption_t *headerOpt;
- headerOpt = (CAHeaderOption_t*) malloc(sizeof(CAHeaderOption_t) * optionNum);
+ headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum);
if (NULL == headerOpt)
{
printf("Memory allocation failed!\n");
// delete token
/*
- if (token != NULL)
- {
- CADestroyToken(token);
- }
- */
+ if (token != NULL)
+ {
+ CADestroyToken(token);
+ }
+ */
free(headerOpt);
gets(buf);
// create remote endpoint
- CARemoteEndpoint_t* endpoint = NULL;
+ CARemoteEndpoint_t *endpoint = NULL;
CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint);
if (res != CA_STATUS_OK)
{
int index;
- CALocalConnectivity_t* tempInfo;
+ CALocalConnectivity_t *tempInfo;
uint32_t tempSize = 0;
- tempInfo = (CALocalConnectivity_t*) malloc(sizeof(CALocalConnectivity_t));
+ tempInfo = (CALocalConnectivity_t *) malloc(sizeof(CALocalConnectivity_t));
- CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
+ CAGetNetworkInformation(&tempInfo, &tempSize);
if (!tempSize)
{
printf("network not connected\n");
return;
}
- printf("network info total size is %d\n", tempSize);
+ printf("################## Network Information #######################\n");
+ printf("network info total size is %d\n\n", tempSize);
for (index = 0; index < tempSize; index++)
{
if (tempInfo == NULL)
break;
}
- printf("type : %d, address : %s\n",
- tempInfo->type,
- tempInfo->addressInfo.IP.ipAddress);
+ printf("Type: %d\n", tempInfo->type);
+ printf("Address: %s\n", tempInfo->addressInfo.IP.ipAddress);
+ printf("Port: %d\n", tempInfo->addressInfo.IP.port);
+ printf("Secured: %d\n\n", tempInfo->isSecured);
+
+ if (CA_TRUE == tempInfo->isSecured)
+ {
+ gLocalSecurePort = tempInfo->addressInfo.IP.port;
+ }
+ else
+ {
+ gLocalUnicastPort = tempInfo->addressInfo.IP.port;
+ }
+
tempInfo++;
}
+ //free(tempInfo);
+ printf("##############################################################");
}
-void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo)
+void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
{
- /*
- printf("[CALLBACK] request_handler, uri : %s, data : %s\n",
- (object != NULL) ? object->resourceUri : "",
- (requestInfo != NULL) ? requestInfo->info.payload : "");
- */
- printf("[CALLBACK] request_handler, uri: %s, data: %s, token: %s \n",
- (object != NULL) ? object->resourceUri : "",
- (requestInfo != NULL) ? requestInfo->info.payload : "",
- (requestInfo->info.token != NULL) ? requestInfo->info.token : "");
-
- if (gLastRequestToken != NULL && requestInfo->info.token != NULL
- && (strcmp((char*)gLastRequestToken, requestInfo->info.token) == 0))
+ if (!object)
{
- printf("token is same. received request of it's own. skip.. \n");
+ printf("Remote endpoint is NULL!");
+ return;
+ }
+ if (!requestInfo)
+ {
+ printf("Request info is NULL!");
return;
}
- printf("[CALLBACK] request_handler, address : %s port:%d \n",
- (object != NULL) ? object->addressInfo.IP.ipAddress : "",
- (object != NULL) ? object->addressInfo.IP.port : 0);
+ printf("##########received request from remote device #############\n");
+ printf("Uri: %s\n", object->resourceUri);
+ printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
+ object->addressInfo.IP.port, object->isSecured);
+
+ printf("Data: %s\n", requestInfo->info.payload);
+
+ if (gLastRequestToken != NULL && requestInfo->info.token != NULL
+ && (strcmp((char *)gLastRequestToken, requestInfo->info.token) == 0))
+ {
+ printf("token is same. received request of it's own. skip.. \n");
+ return;
+ }
if (requestInfo->info.options)
{
uint32_t i;
for (i = 0; i < len; i++)
{
- printf("[CALLBACK] request_handler, option ID : %d\n",
- requestInfo->info.options[i].optionID);
- printf("[CALLBACK] request_handler, options data length : %d\n",
- requestInfo->info.options[i].optionLength);
- printf("[CALLBACK] request_handler, options data : %s\n",
- requestInfo->info.options[i].optionData);
+ printf("Option %d\n", i + 1);
+ printf("ID : %d\n", requestInfo->info.options[i].optionID);
+ printf("Data[%d]: %s\n", requestInfo->info.options[i].optionLength,
+ requestInfo->info.options[i].optionData);
}
}
+ printf("############################################################\n");
- printf("send response with URI\n");
- send_response(object, (requestInfo != NULL) ? requestInfo->info.token : "");
+ //Check if this has secure communication information
+ if (requestInfo->info.payload)
+ {
+ int securePort = get_secure_information(requestInfo->info.payload);
+ if (0 < securePort) //Set the remote endpoint secure details and send response
+ {
+ printf("This is secure resource...\n");
+ char *uri = NULL;
+ int length = 0;
+
+ length = 8; //length of "coaps://"
+ length += strlen(object->addressInfo.IP.ipAddress) + 5; // length of "ipaddress:port"
+ length += strlen(object->resourceUri) + 1;
+
+ uri = calloc(1,sizeof(char)*length);
+ if (!uri)
+ {
+ printf("Failed to create new uri\n");
+ return;
+ }
+ sprintf(uri,"coaps://%s:%d/%s",object->addressInfo.IP.ipAddress,
+ securePort, object->resourceUri);
+
+ CARemoteEndpoint_t *endpoint = NULL;
+ if (CA_STATUS_OK != CACreateRemoteEndpoint(uri,&endpoint))
+ {
+ printf("Failed to create duplicate of remote endpoint!\n");
+ return;
+ }
+ endpoint->isSecured = CA_TRUE;
+ object = endpoint;
+ }
+ }
- received = TRUE;
+ printf("send response with URI\n");
+ send_response(object, (requestInfo != NULL) ? &requestInfo->info : NULL);
+ gReceived = 1;
}
-void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
+void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
{
-
- printf("[CALLBACK] response_handler, uri : %s, data : %s\n",
- (object != NULL) ? object->resourceUri : "",
- (responseInfo != NULL) ? responseInfo->info.payload : "");
-
- printf("[CALLBACK] response_handler, address : %s port :%d\n",
- (object != NULL) ? object->addressInfo.IP.ipAddress : "",
- (object != NULL) ? object->addressInfo.IP.port : 0);
+ printf("##########Received response from remote device #############\n");
+ printf("Uri: %s\n", object->resourceUri);
+ printf("Remote Address: %s Port: %d secured:%d\n", object->addressInfo.IP.ipAddress,
+ object->addressInfo.IP.port, object->isSecured);
+ printf("Data: %s\n", responseInfo->info.payload);
if (responseInfo->info.options)
{
uint32_t i;
for (i = 0; i < len; i++)
{
- printf("[CALLBACK] response_handler, option ID : %d\n",
- responseInfo->info.options[i].optionID);
- printf("[CALLBACK] response_handler, options data length : %d\n",
- responseInfo->info.options[i].optionLength);
- printf("[CALLBACK] response_handler, options data : %s\n",
- responseInfo->info.options[i].optionData);
+ printf("Option %d\n", i + 1);
+ printf("ID : %d\n", responseInfo->info.options[i].optionID);
+ printf("Data[%d]: %s\n", responseInfo->info.options[i].optionLength,
+ responseInfo->info.options[i].optionData);
}
}
- received = TRUE;
+ printf("############################################################\n");
+ gReceived = 1;
- //printf("send request with URI\n");
- //send_request_tmp(object, (responseInfo != NULL) ? responseInfo->info.token : "");
+ //Check if this has secure communication information
+ if (responseInfo->info.payload)
+ {
+ int securePort = get_secure_information(responseInfo->info.payload);
+ if (0 < securePort) //Set the remote endpoint secure details and send response
+ {
+ printf("This is secure resource...\n");
+ }
+ }
}
-void send_response(CARemoteEndpoint_t* endpoint, CAToken_t request_token)
+void send_response(CARemoteEndpoint_t* endpoint, CAInfo_t* info)
{
-
- printf("\n=============================================\n");
+ printf("entering send_response\n");
CAInfo_t responseData;
- //responseData = (CAInfo*) malloc(sizeof(CAInfo));
memset(&responseData, 0, sizeof(CAInfo_t));
- responseData.token = request_token;
+ responseData.type =
+ (info != NULL) ?
+ ((info->type == CA_MSG_CONFIRM) ? CA_MSG_ACKNOWLEDGE : CA_MSG_NONCONFIRM) :
+ CA_MSG_NONCONFIRM;
+ responseData.messageId = (info != NULL) ? info->messageId : 0;
+ responseData.token = (info != NULL) ? info->token : "";
responseData.payload = "response payload";
CAResponseInfo_t responseInfo;
- //responseInfo = (CAResponseInfo*) malloc(sizeof(CAResponseInfo));
memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
responseInfo.result = 203;
responseInfo.info = responseData;
+ if (CA_TRUE == endpoint->isSecured)
+ printf("Sending response on secure communication\n");
+ else
+ printf("Sending response on non-secure communication\n");
+
// send request (connectivityType from remoteEndpoint of request Info)
CAResult_t res = CASendResponse(endpoint, &responseInfo);
if (res != CA_STATUS_OK)
}
printf("=============================================\n");
-
}
-void send_request_tmp(CARemoteEndpoint_t* endpoint, CAToken_t token)
+void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token)
{
printf("\n=============================================\n");
}
+int get_secure_information(CAPayload_t payLoad)
+{
+ printf("entering get_secure_information\n");
+
+ if (!payLoad)
+ {
+ printf("Payload is NULL\n");
+ return -1;
+ }
+
+ char *subString = NULL;
+ if (NULL == (subString = strstr(payLoad, "\"sec\":1")))
+ {
+ printf("This is not secure resource\n");
+ return -1;
+ }
+
+ if (NULL == (subString = strstr(payLoad, "\"port\":")))
+ {
+ printf("This secure resource does not have port information\n");
+ return -1;
+ }
+
+ char *startPos = strstr(subString, ":");
+ if (!startPos)
+ {
+ printf("Parsing failed !\n");
+ return -1;
+ }
+
+ char *endPos = strstr(startPos, "}");
+ if (!endPos)
+ {
+ printf("Parsing failed !\n");
+ return -1;
+ }
+
+ char portStr[4] = {0};
+ memcpy(portStr, startPos + 1, (endPos-1) - startPos);
+
+ printf("secured port is: %s\n", portStr);
+ return atoi(portStr);
+}
+
+void get_resource_uri(char *URI, char *resourceURI, int length)
+{
+ char *startPos = URI;
+ char *temp = NULL;
+ if (NULL != (temp = strstr(URI, "://")))
+ {
+ startPos = strchr(temp + 3, '/');
+ if (!startPos)
+ {
+ printf("Resource URI is missing\n");
+ return;
+ }
+ }
+
+ char *endPos = strchr(startPos, '?');
+ if (!endPos)
+ {
+ endPos = URI + strlen(URI);
+ }
+ endPos -= 1;
+
+ if (endPos - startPos <= length)
+ memcpy(resourceURI, startPos + 1, endPos - startPos);
+
+ printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
+}
gets(buf);
- // create token
+ // create token
CAToken_t token = NULL;
CAResult_t res = CAGenerateToken(&token);
if (res != CA_STATUS_OK)
scanf("%d", &optionNum);
CAHeaderOption_t *headerOpt;
- if(optionNum > 0)
+ if (optionNum > 0)
{
headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum);
if (NULL == headerOpt)
void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
{
- printf("[CALLBACK] request_handler, uri : %s, data : %s\n", (object != NULL) ? object->resourceUri : "",
- (requestInfo != NULL) ? requestInfo->info.payload : "");
+ printf("[CALLBACK] request_handler, uri : %s, data : %s\n",
+ (object != NULL) ? object->resourceUri : "",
+ (requestInfo != NULL) ? requestInfo->info.payload : "");
- printf("[CALLBACK] request_handler, address : %s\n", (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+ printf("[CALLBACK] request_handler, address : %s\n",
+ (object != NULL) ? object->addressInfo.IP.ipAddress : "");
- if(requestInfo->info.options)
+ if (requestInfo->info.options)
{
uint32_t len = requestInfo->info.numOptions;
uint32_t i;
- for(i = 0 ; i < len ; i++)
+ for (i = 0 ; i < len ; i++)
{
printf("[CALLBACK] request_handler, option ID : %d\n", requestInfo->info.options[i].optionID);
- printf("[CALLBACK] request_handler, options data length : %d\n", requestInfo->info.options[i].optionLength);
+ printf("[CALLBACK] request_handler, options data length : %d\n",
+ requestInfo->info.options[i].optionLength);
printf("[CALLBACK] request_handler, options data : %s\n", requestInfo->info.options[i].optionData );
}
}
}
-void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
+void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo)
{
- printf("[CALLBACK] response_handler, uri : %s, data : %s\n", (object != NULL) ? object->resourceUri : "",
- (responseInfo != NULL) ? responseInfo->info.payload : "");
+ printf("[CALLBACK] response_handler, uri : %s, data : %s\n",
+ (object != NULL) ? object->resourceUri : "",
+ (responseInfo != NULL) ? responseInfo->info.payload : "");
- printf("[CALLBACK] response_handler, address : %s\n", (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+ printf("[CALLBACK] response_handler, address : %s\n",
+ (object != NULL) ? object->addressInfo.IP.ipAddress : "");
- if(responseInfo->info.options)
+ if (responseInfo->info.options)
{
uint32_t len = responseInfo->info.numOptions;
uint32_t i;
- for(i = 0 ; i < len ; i++)
+ for (i = 0 ; i < len ; i++)
{
printf("[CALLBACK] response_handler, option ID : %d\n", responseInfo->info.options[i].optionID);
- printf("[CALLBACK] response_handler, options data length : %d\n", responseInfo->info.options[i].optionLength);
- printf("[CALLBACK] response_handler, options data : %s\n", responseInfo->info.options[i].optionData );
+ printf("[CALLBACK] response_handler, options data length : %d\n",
+ responseInfo->info.options[i].optionLength);
+ printf("[CALLBACK] response_handler, options data : %s\n",
+ responseInfo->info.options[i].optionData );
}
}
#define MOD_NAME "TizenSample"
/**
- * Enable/disable one or more of the following macros to enable/disable
+ * Enable/disable one or more of the following macros to enable/disable
* functionality of that particular adapter type in the interfacesample.
*/
-//#define WIFI_ADAPTER_TEST
-#define BT_ADAPTER_TEST
+#define WIFI_ADAPTER_TEST
+//#define BT_ADAPTER_TEST
//#define BLE_ADAPTER_TEST
#if defined(WIFI_ADAPTER_TEST)
static u_thread_pool_t gLEThreadPool = NULL;
#endif
-static GMainLoop *mainloop;
-static GIOChannel *channel;
-static guint g_test_io_watch_id;
-static GError *g_err_Sample;
+static GMainLoop *mainloop = NULL;
+static GIOChannel *channel = NULL;
+static guint g_test_io_watch_id = 0;
+static GError *g_err_Sample = NULL;
static CALocalConnectivity_t *localWifiEndpoint = NULL;
//Hardcoded coap data for Test
#ifdef BLE_ADAPTER_TEST
if (CA_LE == type && NULL == gLEThreadPool)
{
- if (CA_STATUS_OK != u_thread_pool_init(3, &gLEThreadPool))
+ if (CA_STATUS_OK != u_thread_pool_init(5, &gLEThreadPool))
{
printf("Failed to create thread pool for BT adapter!\n");
return;
}
endpoint.connectivityType = CA_WIFI;
strncpy(endpoint.addressInfo.IP.ipAddress, remoteIPAddress, CA_IPADDR_SIZE);
- endpoint.addressInfo.IP.port = 5283; /* Send the corresponding port here */
+ endpoint.addressInfo.IP.port = 5683; /* Send the corresponding port here */
int sdatalen = tempConnectivityHandlers->handler.sendData(&endpoint, coapData,
strlen(coapData));
}
endpoint.connectivityType = CA_LE;
- strncpy(endpoint.addressInfo.BT.btMacAddress, deviceaddress, CA_MACADDR_SIZE - 1);
- endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
+ strncpy(endpoint.addressInfo.LE.leMacAddress, deviceaddress, CA_MACADDR_SIZE - 1);
+ endpoint.addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0';
endpoint.resourceUri = strdup(uuid);
tempConnectivityHandlers->handler.sendData(&endpoint, coapData, strlen(coapData));
printf( "Terminating BT Adapter thread pool");
u_thread_pool_free(gBTThreadPool);
+ gBTThreadPool = NULL;
}
#endif //BT_ADAPTER_TEST
// Freeing threadpool for wifi communication adapter
printf( "Terminating WIFI Adapter thread pool");
u_thread_pool_free(gWiFiThreadPool);
+ gWiFiThreadPool = NULL;
//Terminate the Wifi communication adapter
CATerminateWIfI();
printf( "Terminating BLE Adapter thread pool");
u_thread_pool_free(gLEThreadPool);
+ gLEThreadPool = NULL;
printf("testTerminateBLEInterface OUT\n");
}
#define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS"
-CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type, const char *address,
- const char *interfaceName)
+CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type,
+ const char *address)
{
CALocalConnectivity_t *info = (CALocalConnectivity_t *)
OICMalloc(sizeof(CALocalConnectivity_t));
strncpy(info->addressInfo.IP.ipAddress, connectivity->addressInfo.IP.ipAddress,
CA_IPADDR_SIZE - 1);
info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0';
+ info->addressInfo.IP.port = connectivity->addressInfo.IP.port;
}
+ info->isSecured = connectivity->isSecured;
return info;
}
}
}
-CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type, const char *address,
- const char *resourceUri)
+CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type,
+ const char *address,
+ const char *resourceUri)
{
CARemoteEndpoint_t *info = (CARemoteEndpoint_t *)
OICMalloc(sizeof(CARemoteEndpoint_t));
info->resourceUri = OICStrdup(remoteEndpoint->resourceUri);
}
+ info->isSecured = remoteEndpoint->isSecured;
return info;
}
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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.
- *
- ******************************************************************/
-
-#include "camessagequeue.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "logger.h"
-#include "caadapterutils.h"
-#include "oic_malloc.h"
-
-#define TAG "CAAdapterUtil"
-
-CAResult_t CAAdapterInitializeMessageQueue(CAAdapterMessageQueue_t **queueHandle)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- VERIFY_NON_NULL(queueHandle, TAG, "Invalid queue handle container");
-
- CAAdapterMessageQueue_t *queuePtr = (CAAdapterMessageQueue_t *)
- OICMalloc(sizeof(CAAdapterMessageQueue_t));
- if (!queuePtr)
- {
- OIC_LOG_V(ERROR, TAG, "Out of memory!");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- memset((void *) queuePtr, 0, sizeof(CAAdapterMessageQueue_t));
- // Initialize mutex utility
- u_mutex_init();
- queuePtr->queueMutex = u_mutex_new();
- if (NULL == queuePtr->queueMutex)
- {
- OICFree(queuePtr);
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- queuePtr->queue = u_queue_create();
- if (NULL == queuePtr->queue)
- {
- u_mutex_free(queuePtr->queueMutex);
- OICFree(queuePtr);
- return CA_MEMORY_ALLOC_FAILED;
- }
- *queueHandle = queuePtr;
-
- OIC_LOG(DEBUG, TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CAAdapterFreeMessage(CAAdapterMessage_t *message)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- VERIFY_NON_NULL_VOID(message, TAG, "Invalid message");
-
- if (message->remoteEndpoint)
- {
- CAAdapterFreeRemoteEndpoint(message->remoteEndpoint);
- }
-
- if (message->data)
- {
- OICFree(message->data);
- }
- OICFree(message);
- OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-void CAAdapterTerminateMessageQueue(CAAdapterMessageQueue_t *queueHandle)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- VERIFY_NON_NULL_VOID(queueHandle, TAG, "Invalid queue handle");
- VERIFY_NON_NULL_VOID(queueHandle->queue, TAG, "Invalid queue");
- VERIFY_NON_NULL_VOID(queueHandle->queueMutex, TAG, "Invalid queue mutex");
-
- u_mutex_lock(queueHandle->queueMutex);
- u_queue_message_t *messagePtr = NULL;
- while ((messagePtr = u_queue_get_element(queueHandle->queue)))
- {
- CAAdapterFreeMessage((CAAdapterMessage_t *)messagePtr->msg);
- OICFree(messagePtr);
- }
-
- u_mutex_unlock(queueHandle->queueMutex);
- u_mutex_free(queueHandle->queueMutex);
- queueHandle->queueMutex = NULL;
- OICFree(queueHandle);
-
- OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAAdapterEnqueueMessage(CAAdapterMessageQueue_t *queueHandle,
- const CARemoteEndpoint_t *remoteEndpoint,
- void *data, uint32_t dataLen)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- VERIFY_NON_NULL(queueHandle, TAG, "Invalid queue handle");
- VERIFY_NON_NULL(queueHandle->queue, TAG, "Invalid queue");
- VERIFY_NON_NULL(queueHandle->queueMutex, TAG, "Invalid queue mutex");
- VERIFY_NON_NULL(data, TAG, "Invalid data");
-
- CAAdapterMessage_t *adapterMessage = (CAAdapterMessage_t *)
- OICMalloc(sizeof(CAAdapterMessage_t));
- if (!adapterMessage)
- {
- OIC_LOG_V(ERROR, TAG, "Out of memory!");
- return CA_MEMORY_ALLOC_FAILED;
- }
- memset((void *) adapterMessage, 0, sizeof(CAAdapterMessage_t));
-
- // Copy data
- adapterMessage->data = (void *)OICMalloc(dataLen);
- if (adapterMessage->data == NULL)
- {
- OIC_LOG_V(ERROR, TAG, "Out of memory!!!");
- CAAdapterFreeMessage(adapterMessage);
- return CA_MEMORY_ALLOC_FAILED;
- }
- memcpy(adapterMessage->data, data, dataLen);
- adapterMessage->dataLen = dataLen;
-
- // Copy remote endpoint info
- adapterMessage->remoteEndpoint = NULL;
- if (remoteEndpoint)
- {
- adapterMessage->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
- if (NULL == adapterMessage->remoteEndpoint)
- {
- OIC_LOG_V(ERROR, TAG, "Out of memory.!!");
- CAAdapterFreeMessage(adapterMessage);
- return CA_MEMORY_ALLOC_FAILED;
- }
- }
-
- //Insert at end of queue
- u_queue_message_t *queueMessage = (u_queue_message_t *)OICMalloc(sizeof(u_queue_message_t));
- if (!queueMessage)
- {
- OIC_LOG_V(ERROR, TAG, "Out of memory.!!");
- CAAdapterFreeMessage(adapterMessage);
- return CA_MEMORY_ALLOC_FAILED;
- }
- queueMessage->msg = (void *)adapterMessage;
- queueMessage->size = sizeof(CAAdapterMessage_t);
-
- u_mutex_lock(queueHandle->queueMutex);
- CAResult_t ret = u_queue_add_element(queueHandle->queue, queueMessage);
- if (ret != CA_STATUS_OK)
- {
- CAAdapterFreeMessage(adapterMessage);
- OICFree(queueMessage);
- }
- u_mutex_unlock(queueHandle->queueMutex);
- OIC_LOG(DEBUG, TAG, "OUT");
- return ret;
-}
-
-CAResult_t CAAdapterDequeueMessage(CAAdapterMessageQueue_t *queueHandle,
- CAAdapterMessage_t **message)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- VERIFY_NON_NULL(queueHandle, TAG, "Invalid queue handle");
- VERIFY_NON_NULL(queueHandle->queue, TAG, "Invalid queue");
- VERIFY_NON_NULL(queueHandle->queueMutex, TAG, "Invalid queue mutex");
- VERIFY_NON_NULL(message, TAG, "Invalid message handle");
-
- CAResult_t ret = CA_STATUS_FAILED;
- u_mutex_lock(queueHandle->queueMutex);
- u_queue_message_t *messagePtr = u_queue_get_element(queueHandle->queue);
- if (messagePtr)
- {
- ret = CA_STATUS_OK;
- *message = (CAAdapterMessage_t *)messagePtr->msg;
- OICFree(messagePtr);
- }
- u_mutex_unlock(queueHandle->queueMutex);
-
- OIC_LOG(DEBUG, TAG, "OUT");
- return ret;
-}
-
if (CA_STATUS_OK != result )
{
OIC_LOG(ERROR, CA_MSG_PARSER_TAG, "Generate header failed");
+ OICFree(header);
return -1;
}
}
-uint32_t CADeFragmentData(const char *datasegment, char **data, uint32_t TotalLen, uint32_t offset)
-{
- OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "IN");
-
- VERIFY_NON_NULL(*data, NULL, "Param data is NULL");
-
- uint32_t length = 0;
-
- memcpy(*data + offset, datasegment, strlen(datasegment));
-
- length = TotalLen - offset;
-
- if ( length < 0)
- {
- length = 0;
- }
-
- OIC_LOG(DEBUG, CA_MSG_PARSER_TAG, "OUT");
-
- return length;
-
-}
-
-
-
static u_thread_pool_t gThreadPoolHandle = NULL;
CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
- u_thread_pool_t handle)
+ CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
+ u_thread_pool_t handle)
{
OIC_LOG_V(DEBUG, TAG, "CAInitializeEDR");
return CA_STATUS_OK;
}
-uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen)
+uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
{
OIC_LOG_V(DEBUG, TAG, "CASendEDRUnicastData");
return 0;
}
-uint32_t CASendEDRMulticastData(void* data, uint32_t dataLen)
+uint32_t CASendEDRMulticastData(void *data, uint32_t dataLen)
{
OIC_LOG_V(DEBUG, TAG, "CASendEDRMulticastData");
return 0;
}
-CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size)
+CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
{
OIC_LOG_V(DEBUG, TAG, "CAGetEDRInterfaceInformation");
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
- int addressLen = 0;
+ bt_error_e err = BT_ERROR_NONE;
+ int32_t addressLen = 0;
VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "Service UUID is null");
return CA_STATUS_INVALID_PARAM;
}
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
if (BT_ERROR_NONE != (err = bt_socket_disconnect_rfcomm(clientID)))
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
}
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
}
CAResult_t CACreateAndAddToDeviceList(BTDeviceList **deviceList, const char *deviceAddress,
- const char *uuid, BTDevice **device)
+ const char *uuid, BTDevice **device)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
if (NULL == (*device)->serviceUUID)
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG,
- "[createBTDevice] Out of memory (service uuid)!");
+ "[createBTDevice] Out of memory (service uuid)!");
OICFree((*device)->remoteAddress);
OICFree(*device);
{
BTDataList *curNode = *dataList;
*dataList = (*dataList)->next;
-
+
CADestroyBTData(curNode->data);
OICFree(curNode);
}
*
*/
CAResult_t CACreateAndAddToDeviceList(BTDeviceList **deviceList, const char *deviceAddress,
- const char *uuid, BTDevice **device);
+ const char *uuid, BTDevice **device);
/**
* @fn CAAddBTDeviceToList
return CA_STATUS_INVALID_PARAM;
}
- int dataLen = 0;
+ int32_t dataLen = 0;
dataLen = bt_socket_send_data(serverFD, (const char *)data, dataLength);
if (dataLen == -1)
{
#include "cabtdevicelist.h"
#include "cabtutils.h"
#include "caadapterutils.h"
-#include "camessagequeue.h"
+#include "caqueueingthread.h"
#include "camsgparser.h"
/**
} CABTNetworkEvent;
/**
- * @struct CABTMessage
+ * @struct CABTData
* @brief Structure to maintain the information of data in message queue.
*/
typedef struct
{
- void *data;
- int32_t dataLength;
CARemoteEndpoint_t *remoteEndpoint;
-} CABTMessage;
-
+ void *data;
+ uint32_t dataLen;
+} CABTData;
/**
* @var gNetworkPacketReceivedCallback
* @brief Maintains the callback to be notified on receival of network packets from other
static u_thread_pool_t gBTThreadPool = NULL;
/**
- * @var gSendDataQueue
- * @brief Queue to maintain data to be send to remote Bluetooth devices.
- */
-static CAAdapterMessageQueue_t *gSendDataQueue = NULL;
-
-/**
- * @var gReceiverDataQueue
- * @brief Queue to maintain data received from remote Bluetooth devices.
- */
-static CAAdapterMessageQueue_t *gReceiverDataQueue = NULL;
-
-/**
- * @var gSendDataMutex
- * @brief Mutex to synchronize access to data send queue.
+ * @var isHeaderAvailable
+ * @brief to differentiate btw header and data packet.
*/
-static u_mutex gSendDataMutex = NULL;
+static CABool_t isHeaderAvailable = false;
/**
- * @var gReceiverDataMutex
- * @brief Mutex to synchronize access to data recv queue.
+ * @var gSendQueueHandle
+ * @brief Queue handle for Send Data
*/
-static u_mutex gReceiverDataMutex = NULL;
+static CAQueueingThread_t *gSendQueueHandle = NULL;
/**
- * @var gSendDataCond
- * @brief Condition used for notifying handler the presence of data in send queue.
+ * @var gRecvQueueHandle
+ * @brief Queue handle for Receive Data
*/
-static u_cond gSendDataCond = NULL;
+static CAQueueingThread_t *gRecvQueueHandle = NULL;
/**
- * @var gReceiverDataCond
- * @brief Condition used for notifying handler the presence of data in recv queue.
+ * @var gAdapterState
+ * @brief Storing Adapter state information
*/
-static u_cond gReceiverDataCond = NULL;
+static CABool_t gAdapterState = TRUE;
/**
- * @var gDataSendHandlerState
- * @brief Stop condition of sendhandler.
+ * @var gServerId
+ * @brief Storing RfcommserverUUID
*/
-static bool gDataSendHandlerState = false;
+static int32_t gServerId = -1;
/**
- * @var gDataReceiverHandlerState
- * @brief Stop condition of redvhandler.
+ * @var gServerState
+ * @brief Storing Rfcommserver state information
*/
-static bool gDataReceiverHandlerState = false;
+static CABool_t gServerState = FALSE;
/**
- * @var isHeaderAvailable
- * @brief to differentiate btw header and data packet.
- */
-static CABool_t isHeaderAvailable = false;
-/**
* @fn CABTAdapterStateChangeCallback
* @brief This callback is registered to receive bluetooth adapter state changes.
*/
* @brief This callback is registered to receive bluetooth RFCOMM connection state changes.
*/
static void CABTSocketConnectionStateCallback(int result,
- bt_socket_connection_state_e connectionState,
+ bt_socket_connection_state_e state,
bt_socket_connection_s *connection, void *userData);
/**
* scan is initiated.
*/
static void CABTDeviceDiscoveryCallback(int result,
- bt_adapter_device_discovery_state_e discoveryState,
+ bt_adapter_device_discovery_state_e state,
bt_adapter_device_discovery_info_s *discoveryInfo,
void *userData);
* @brief This callback is registered to recieve all the services remote bluetooth device supports
* when service search initiated.
*/
-static void CABTServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo, void *userData);
+static void CABTServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo,
+ void *userData);
/**
* @fn CABTManagerInitializeQueues
- * @brief This function creates and initialize send message queue.
+ * @brief This function creates and initialize message queues.
*/
static CAResult_t CABTManagerInitializeQueues(void);
/**
+ * @fn CABTManagerInitializeSendHandler
+ * @brief This function creates and initialize send message queue.
+ */
+CAResult_t CABTManagerInitializeSendHandler(void);
+
+/**
+ * @fn CABTManagerInitializeQueues
+ * @brief This function creates and initialize receive message queue.
+ */
+CAResult_t CABTManagerInitializeReceiveHandler(void);
+/**
* @fn CABTManagerTerminateQueues
* @brief This function terminates the send message queue.
*/
* @brief This function sends data to specified remote bluetooth device.
*/
static CAResult_t CABTManagerSendUnicastData(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength);
+ void *data, uint32_t dataLength, uint32_t *sentLength);
/**
* @fn CABTManagerSendMulticastData
* @brief This function sends data to all bluetooth devices running OIC service.
*/
static CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data,
- uint32_t dataLength, uint32_t *sentLength);
+ uint32_t dataLength, uint32_t *sentLength);
/**
* @fn CABTGetAdapterEnableState
*/
static void CABTManagerDisconnectAll(void);
+/**
+ * @fn CACreateBTData
+ * @brief creating CABTData
+ */
+static CABTData *CACreateBTData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength);
+
+/**
+ * @fn CABTManagerDisconnectAll
+ * @brief freeing CABTData
+ */
+static void CAFreeBTData(CABTData *btData);
+
+
CAResult_t CABTManagerInitialize(u_thread_pool_t threadPool)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ int32_t err = BT_ERROR_NONE;
//Initialize Bluetooth service
if (BT_ERROR_NONE != (err = bt_initialize()))
return CA_STATUS_FAILED;
}
- //Initialize Send/Receive data message queues
- if (CA_STATUS_OK != CABTManagerInitializeQueues())
- {
- //Deinitialize the Bluetooth stack
- bt_deinitialize();
- return CA_STATUS_FAILED;
- }
-
//Create and initialize the mutex
CABTManagerInitializeMutex();
gBTThreadPool = threadPool;
}
- //Get Bluetooth adapter state
- bool adapterState = false;
- if (CA_STATUS_OK != CABTGetAdapterEnableState(&adapterState))
+ //Initialize Send/Receive data message queues
+ if (CA_STATUS_OK != CABTManagerInitializeQueues())
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get adatper enable state");
-
//Deinitialize the Bluetooth stack
bt_deinitialize();
return CA_STATUS_FAILED;
}
- if (false == adapterState)
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
-
- bt_adapter_set_state_changed_cb(CABTAdapterStateChangeCallback, NULL);
- return CA_ADAPTER_NOT_ENABLED;
- }
+ bt_adapter_set_state_changed_cb(CABTAdapterStateChangeCallback, NULL);
//Notity to upper layer
- CABTNotifyNetworkStauts(CA_INTERFACE_UP);
+ // CABTNotifyNetworkStauts(CA_INTERFACE_UP);
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
if (false == adapterState)
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
- return CA_ADAPTER_NOT_ENABLED;
+ gAdapterState = FALSE;
+ return CA_STATUS_OK;
}
//Register for discovery and rfcomm socket connection callbacks
//Start device discovery
CABTStartDeviceDiscovery();
- //Start data send and receive handlers
- if (!gDataSendHandlerState)
+ // Start send queue thread
+ if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
{
- gDataSendHandlerState = true;
- if (CA_STATUS_OK != u_thread_pool_add_task(gBTThreadPool, CABTManagerDataSendHandler, NULL))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to start data send handler!");
-
- gDataSendHandlerState = false;
- return CA_STATUS_FAILED;
- }
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Start Send Data Thread");
+ CABTManagerStop();
+ return CA_STATUS_FAILED;
}
-
- gDataReceiverHandlerState = true;
- if (CA_STATUS_OK != u_thread_pool_add_task(gBTThreadPool, CABTManagerDataReceiverHandler, NULL))
+ // Start receive queue thread
+ if (CA_STATUS_OK != CAQueueingThreadStart(gRecvQueueHandle))
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to start data send handler!");
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Start Receive Data Thread");
+ CABTManagerStop();
return CA_STATUS_FAILED;
}
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- //Stop data send and receive handlers
- if (gSendDataMutex && gSendDataCond && gDataSendHandlerState)
- {
- u_mutex_lock(gSendDataMutex);
- gDataSendHandlerState = false;
- u_cond_signal(gSendDataCond);
- u_mutex_unlock(gSendDataMutex);
- }
-
- //Stop data send and receive handlers
- if (gReceiverDataMutex && gReceiverDataCond && gDataReceiverHandlerState)
- {
- u_mutex_lock(gReceiverDataMutex);
- gDataReceiverHandlerState = CA_FALSE;
- u_cond_signal(gReceiverDataCond);
- u_mutex_unlock(gReceiverDataMutex);
- }
-
//Stop service search
CABTStopServiceSearch();
-
+
//Stop the device discovery process
CABTStopDeviceDiscovery();
-
+
+ //Stop send queue thread
+ CAQueueingThreadStop(gSendQueueHandle);
+
+ //Stop receive queue thread
+ CAQueueingThreadStop(gRecvQueueHandle);
+
//reset bluetooth adapter callbacks
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Resetting the callbacks");
bt_adapter_unset_device_discovery_state_changed_cb();
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
-void CABTManagerSetPacketReceivedCallback(CANetworkPacketReceivedCallback packetReceivedCallback)
+void CABTManagerSetPacketReceivedCallback(
+ CANetworkPacketReceivedCallback packetReceivedCallback)
{
gNetworkPacketReceivedCallback = packetReceivedCallback;
}
-void CABTManagerSetNetworkChangeCallback(CANetworkChangeCallback networkChangeCallback)
+void CABTManagerSetNetworkChangeCallback(
+ CANetworkChangeCallback networkChangeCallback)
{
gNetworkChangeCallback = networkChangeCallback;
}
-CAResult_t CABTManagerPushDataToReceiverQueue(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength)
+CAResult_t CABTManagerPushDataToReceiverQueue(const char *remoteAddress,
+ const char *serviceUUID, void *data, uint32_t dataLength, uint32_t *sentLength)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+ if (FALSE == gAdapterState)
+ {
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ *sentLength = 0;
+ return CA_STATUS_OK;
+ }
//Input validation
VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "service UUID is null");
VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
return CA_STATUS_FAILED;
}
- if (CA_STATUS_OK != CAAdapterEnqueueMessage(gReceiverDataQueue, remoteEndpoint, data, dataLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add message to queue !");
+ CABTData *btData = CACreateBTData(remoteEndpoint, data, dataLength);
+ //Add message to data queue
- CAAdapterFreeRemoteEndpoint(remoteEndpoint);
- return CA_STATUS_FAILED;
- }
+ CAQueueingThreadAddData(gRecvQueueHandle, btData, sizeof(btData));
*sentLength = dataLength;
- //Signal message handler for processing data for sending
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Signalling message send handler");
- u_mutex_lock(gReceiverDataMutex);
- u_cond_signal(gReceiverDataCond);
- u_mutex_unlock(gReceiverDataMutex);
-
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- if (!gDataSendHandlerState)
+ if (FALSE == gAdapterState)
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Send handler is not running!");
- return CA_STATUS_FAILED;
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ *sentLength = 0;
+ return CA_STATUS_OK;
}
-
//Input validation
VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "service UUID is null");
VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
VERIFY_NON_NULL(sentLength, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null");
- //Add message to data queue
CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
serviceUUID);
if (NULL == remoteEndpoint)
return CA_STATUS_FAILED;
}
- if (CA_STATUS_OK != CAAdapterEnqueueMessage(gSendDataQueue, remoteEndpoint, data, dataLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add message to queue !");
+ CABTData *btData = CACreateBTData(remoteEndpoint, data, dataLength);
+ //Add message to data queue
- CAAdapterFreeRemoteEndpoint(remoteEndpoint);
- return CA_STATUS_FAILED;
- }
+ CAQueueingThreadAddData(gSendQueueHandle, btData, sizeof(btData));
- CAAdapterFreeRemoteEndpoint(remoteEndpoint);
*sentLength = dataLength;
//Signal message handler for processing data for sending
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Signalling message send handler");
- u_mutex_lock(gSendDataMutex);
- u_cond_signal(gSendDataCond);
- u_mutex_unlock(gSendDataMutex);
-
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
-CAResult_t CABTManagerStartServer(const char *serviceUUID, int32_t *serverID)
+CAResult_t CABTManagerStartServer(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- return CABTServerStart(serviceUUID, serverID);
+ if (FALSE == gAdapterState)
+ {
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!");
+ //Setting gServerState for starting Rfcommserver when adapter starts
+ gServerState = TRUE;
+ return CA_STATUS_OK;
+ }
+
+ if (-1 < gServerId)
+ {
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Server is already in running state.");
+ return CA_STATUS_OK;
+ }
+ return CABTServerStart(OIC_BT_SERVICE_ID, &gServerId);
}
-CAResult_t CABTManagerStopServer(const int32_t serverID)
+CAResult_t CABTManagerStopServer(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- return CABTServerStop(serverID);
+ if (-1 == gServerId)
+ {
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "No Server is in running state.");
+ return CA_STATUS_OK;
+ }
+
+ if (CA_STATUS_OK != CABTServerStop(gServerId))
+ {
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to close server socket!");
+ return CA_STATUS_FAILED;
+ }
+
+ gServerId = -1;
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
}
CAResult_t CABTManagerGetInterface(CALocalConnectivity_t **info)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ int32_t err = BT_ERROR_NONE;
char *localAddress = NULL;
//Input validation
}
//Create network info
- *info = CAAdapterCreateLocalEndpoint(CA_EDR, localAddress, NULL);
+ *info = CAAdapterCreateLocalEndpoint(CA_EDR, localAddress);
if (NULL == *info)
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create LocalConnectivity instance!");
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- if (NULL == gSendDataQueue)
- {
- if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gSendDataQueue))
- {
- return CA_STATUS_FAILED;
- }
- }
-
- if (NULL == gReceiverDataQueue)
+ if (CA_STATUS_OK == CABTManagerInitializeSendHandler()
+ && CA_STATUS_OK == CABTManagerInitializeReceiveHandler())
{
- if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gReceiverDataQueue))
- {
- return CA_STATUS_FAILED;
- }
+ OIC_LOG(DEBUG, BLUETOOTH_ADAPTER_TAG, "Queue is initialized!");
+ return CA_STATUS_OK;
}
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
+ return CA_STATUS_FAILED;
}
-void CABTManagerTerminateQueues(void)
+CAResult_t CABTManagerInitializeSendHandler(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- if (gSendDataQueue)
+ // Check if the message queue is already initialized
+ if (gSendQueueHandle)
{
- CAAdapterTerminateMessageQueue(gSendDataQueue);
- gSendDataQueue = NULL;
+ OIC_LOG(DEBUG, BLUETOOTH_ADAPTER_TAG, "Already queue is initialized!");
+ return CA_STATUS_OK;
}
- if (gReceiverDataQueue)
+ gSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gSendQueueHandle)
{
- CAAdapterTerminateMessageQueue(gReceiverDataQueue);
- gReceiverDataQueue = NULL;
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
+ return CA_MEMORY_ALLOC_FAILED;
}
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gBTThreadPool,
+ CABTManagerDataSendHandler))
+ {
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Initialize send queue thread");
+ return CA_STATUS_FAILED;
+ }
+ return CA_STATUS_OK;
}
-void CABTManagerInitializeMutex(void)
+CAResult_t CABTManagerInitializeReceiveHandler(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
- u_mutex_init();
-
- if (!gBTDeviceListMutex)
+ // Check if the message queue is already initialized
+ if (gRecvQueueHandle)
{
- gBTDeviceListMutex = u_mutex_new();
+ OIC_LOG(DEBUG, BLUETOOTH_ADAPTER_TAG, "Already queue is initialized!");
+ return CA_STATUS_OK;
}
- if (!gSendDataMutex)
+ gRecvQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gRecvQueueHandle)
{
- gSendDataMutex = u_mutex_new();
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
+ return CA_MEMORY_ALLOC_FAILED;
}
- if (!gReceiverDataMutex)
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gRecvQueueHandle, gBTThreadPool,
+ CABTManagerDataReceiverHandler))
{
- gReceiverDataMutex = u_mutex_new();
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to Initialize send queue thread");
+ return CA_STATUS_FAILED;
}
- if (!gSendDataCond)
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CABTManagerTerminateQueues(void)
+{
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+
+ if (gSendQueueHandle)
{
- gSendDataCond = u_cond_new();
+ CAQueueingThreadDestroy(gSendQueueHandle);
+ gSendQueueHandle = NULL;
}
-
- if (!gReceiverDataCond)
+ if (gRecvQueueHandle)
{
- gReceiverDataCond = u_cond_new();
+ CAQueueingThreadDestroy(gRecvQueueHandle);
+ gRecvQueueHandle = NULL;
}
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
-void CABTManagerTerminateMutex(void)
+void CABTManagerInitializeMutex(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- if (gBTDeviceListMutex)
- {
- u_mutex_free(gBTDeviceListMutex);
- gBTDeviceListMutex = NULL;
- }
+ u_mutex_init();
- if (gSendDataMutex)
+ if (!gBTDeviceListMutex)
{
- u_mutex_free(gSendDataMutex);
- gSendDataMutex = NULL;
+ gBTDeviceListMutex = u_mutex_new();
}
- if (gReceiverDataMutex)
- {
- u_mutex_free(gReceiverDataMutex);
- gReceiverDataMutex = NULL;
- }
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+}
- if (gSendDataCond)
- {
- u_cond_free(gSendDataCond);
- gSendDataCond = NULL;
- }
+void CABTManagerTerminateMutex(void)
+{
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- if (gReceiverDataCond)
+ if (gBTDeviceListMutex)
{
- u_cond_free(gReceiverDataCond);
- gReceiverDataCond = NULL;
+ u_mutex_free(gBTDeviceListMutex);
+ gBTDeviceListMutex = NULL;
}
-
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- u_mutex_lock(gReceiverDataMutex);
- CAAdapterMessage_t *message = NULL;
+ CABTData *message = (CABTData *) context;
+ if (message == NULL)
+ {
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get message!");
+ return;
+ }
const char *remoteAddress = NULL;
const char *serviceUUID = NULL;
- uint32_t recvDataLen = 0;
- uint32_t totalDataLen = 0;
- char *dataSegment = NULL;
- char *defragData = NULL;
- CARemoteEndpoint_t *remoteEndpoint = NULL;
+ static uint32_t recvDataLen = 0;
+ static uint32_t totalDataLen = 0;
+ static char *defragData = NULL;
+ static CARemoteEndpoint_t *remoteEndpoint = NULL;
- while (gDataReceiverHandlerState)
+ if (!isHeaderAvailable)
{
+ char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, " waiting for the data");
-
- u_cond_wait(gReceiverDataCond, gReceiverDataMutex);
-
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "wait unlocked");
-
- //Extract the message from queue and send to remote bluetooth device
- while (CA_STATUS_OK == CAAdapterDequeueMessage(gReceiverDataQueue, &message))
+ if (NULL == header)
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "checking for DE Fragmentation");
-
- if (!isHeaderAvailable)
- {
- char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
- memcpy(header, message->data, CA_HEADER_LENGTH);
- totalDataLen = CAParseHeader(header);
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
- defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
- OICFree(header);
-
- remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
- serviceUUID = message->remoteEndpoint->resourceUri;
-
- remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
- serviceUUID);
-
- memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
- message->dataLen - CA_HEADER_LENGTH);
- recvDataLen += message->dataLen - CA_HEADER_LENGTH;
- isHeaderAvailable = true;
- }
- else
- {
- memcpy(defragData + recvDataLen, message->data, message->dataLen);
- recvDataLen += message->dataLen ;
- }
- CAAdapterFreeMessage(message);
- if (totalDataLen == recvDataLen)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Sending data up !");
- gNetworkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
- OICFree(remoteEndpoint);
- OICFree(defragData);
- recvDataLen = 0;
- totalDataLen = 0;
- isHeaderAvailable = false;
- }
-
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (header)!");
+ return CA_MEMORY_ALLOC_FAILED;
}
-
- if (false == gDataReceiverHandlerState)
+ memcpy(header, (char *)message->data, CA_HEADER_LENGTH);
+ totalDataLen = CAParseHeader(header);
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Total data to be accumulated [%d] bytes",
+ totalDataLen);
+ defragData = NULL;
+ if (totalDataLen == 0)
{
- break;
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, " totalDataLen is zero");
+ OICFree(header);
+ return;
}
+ defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+ OICFree(header);
+ remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
+ serviceUUID = message->remoteEndpoint->resourceUri;
+ remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ serviceUUID);
+
+ memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
+ message->dataLen - CA_HEADER_LENGTH);
+ recvDataLen += message->dataLen - CA_HEADER_LENGTH;
+ isHeaderAvailable = true;
+ }
+ else
+ {
+ memcpy(defragData + recvDataLen, message->data, message->dataLen);
+ recvDataLen += message->dataLen ;
+ }
+ CAFreeBTData(message);
+ if (totalDataLen == recvDataLen)
+ {
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Sending data up !");
+ gNetworkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
+ recvDataLen = 0;
+ totalDataLen = 0;
+ remoteEndpoint = NULL;
+ isHeaderAvailable = false;
}
- u_mutex_unlock(gReceiverDataMutex);
+
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- u_mutex_lock(gSendDataMutex);
- while (gDataSendHandlerState)
+ CABTData *message = (CABTData *) context;
+ if (message == NULL)
{
- CAAdapterMessage_t *message = NULL;
- const char *remoteAddress = NULL;
- const char *serviceUUID = NULL;
- uint32_t sentLength = 0;
- int headerAdded = 0;
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get message!");
+ return;
+ }
+ const char *remoteAddress = NULL;
+ const char *serviceUUID = NULL;
+ uint32_t sentLength = 0;
+ int32_t headerAdded = 0;
- //Extract the message from queue and send to remote bluetooth device
- while (CA_STATUS_OK == CAAdapterDequeueMessage(gSendDataQueue, &message))
+ remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
+ serviceUUID = message->remoteEndpoint->resourceUri;
+
+ char *dataSegment = NULL;
+ uint32_t offset = 0, ret = 1;
+ int32_t datalen = message->dataLen;
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "checking for fragmentation and the dataLen is %d",
+ datalen);
+ while ( 1)
+ {
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "fragmenting the data DataLen [%d] Offset [%d]",
+ datalen, offset);
+ ret = CAFragmentData((char *)message->data, &dataSegment, datalen, offset);
+ if (0 == ret)
{
- remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
- serviceUUID = message->remoteEndpoint->resourceUri;
-
- char *dataSegment = NULL;
- uint32_t offset = 0, ret = 1;
- int datalen = message->dataLen;
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "checking for fragmentation and the dataLen is %d",
- datalen);
- while ( 1)
+ break;
+ }
+ if (NULL == dataSegment)
+ {
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to allocated memory fo dataSegment.");
+ break;
+ }
+ if (strlen(remoteAddress)) //Unicast data
+ {
+ if (CA_STATUS_OK != CABTManagerSendUnicastData(remoteAddress, serviceUUID,
+ dataSegment, ret, &sentLength))
{
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "fragmenting the data DataLen [%d] Offset [%d]", datalen,
- offset);
- ret = CAFragmentData(message->data, &dataSegment, datalen, offset);
- sleep(1);
- if (0 == ret)
- {
- break;
- }
- if (strlen(remoteAddress)) //Unicast data
- {
- if (CA_STATUS_OK != CABTManagerSendUnicastData(remoteAddress, serviceUUID,
- dataSegment, ret, &sentLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send unicast data !");
- }
- }
- else
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "sending multicast data");
- if (CA_STATUS_OK != CABTManagerSendMulticastData(serviceUUID, dataSegment,
- ret, &sentLength))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send multicast data !");
- }
- }
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "freeing dataSegment");
-
- OICFree(dataSegment);
- dataSegment = NULL;
- offset += ret;
- if (headerAdded == 0)
- {
- datalen -= offset - CA_HEADER_LENGTH;
- offset = offset - CA_HEADER_LENGTH;
- headerAdded = 1;
- }
- else
- {
- datalen -= ret;
- }
-
- if (datalen < 0)
- {
- datalen += ret ;
- }
- if (datalen == message->dataLen)
- {
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "All data has been fragmented and sent");
- break;
- }
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send unicast data !");
+ }
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "sending multicast data");
+ if (CA_STATUS_OK != CABTManagerSendMulticastData(serviceUUID, dataSegment,
+ ret, &sentLength))
+ {
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send multicast data !");
}
- //Free message
- CAAdapterFreeMessage(message);
}
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "freeing dataSegment");
- //Wait for the data to be send
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Waitiing for data");
- u_cond_wait(gSendDataCond, gSendDataMutex);
- OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Got the signal that data is pending");
+ OICFree(dataSegment);
+ dataSegment = NULL;
+ offset += ret;
+ if (headerAdded == 0)
+ {
+ datalen -= offset - CA_HEADER_LENGTH;
+ offset = offset - CA_HEADER_LENGTH;
+ headerAdded = 1;
+ }
+ else
+ {
+ datalen -= ret;
+ }
- if (false == gDataSendHandlerState)
+ if (datalen < 0)
+ {
+ datalen += ret ;
+ }
+ if (datalen == message->dataLen)
{
+ OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "All data has been fragmented and sent");
break;
}
}
+ //Free message
+ CAFreeBTData(message);
- u_mutex_unlock(gSendDataMutex);
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
{
//Adding to pending list
if (CA_STATUS_OK != CAAddBTDataToList(&device->pendingDataList, data,
- dataLength))
+ dataLength))
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add data to pending list!");
return CA_STATUS_OK;
}
-CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data, uint32_t dataLength,
- uint32_t *sentLength)
+CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data,
+ uint32_t dataLength, uint32_t *sentLength)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "There is no device!");
break;
}
-
+
if (-1 == device->socketFD)
{
//Check if the device service search is finished
//Adding to pendding list
if (CA_STATUS_OK != CAAddBTDataToList(&device->pendingDataList, data,
- dataLength))
+ dataLength))
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add data to pending list !");
continue;
//Input validation
VERIFY_NON_NULL(state, BLUETOOTH_ADAPTER_TAG, "state holder is NULL!");
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
bt_adapter_state_e adapterState;
//Get Bluetooth adapter state
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
bool isDiscoveryStarted = false;
//Check the device discovery state
return CA_STATUS_FAILED;
}
}
-
+
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
bool isDiscoveryStarted = false;
//Check the device discovery state
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Stopping the device search process");
if (BT_ERROR_NONE != (err = bt_adapter_stop_device_discovery()))
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to stop device discovery!, error num [%x]",
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to stop discovery!, error num [%x]",
err);
}
}
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
//Input validation
VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null");
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
//Stop ongoing service search
if (BT_ERROR_NONE != (err = bt_device_cancel_service_search()))
return CA_STATUS_OK;
}
-void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState, void *userData)
+void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState,
+ void *userData)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
if (BT_ADAPTER_ENABLED == adapterState)
{
+ // checking for adapter state. If not started then start.
+ if (FALSE == gAdapterState)
+ {
+ CABTManagerStart();
+ gAdapterState = TRUE;
+ //starting RFcommserver
+ if (gServerState == TRUE)
+ {
+ CABTManagerStartServer();
+ gServerState == FALSE;
+ }
+ }
//Notity to upper layer
CABTNotifyNetworkStauts(CA_INTERFACE_UP);
}
{
//Notity to upper layer
CABTNotifyNetworkStauts(CA_INTERFACE_DOWN);
+ gAdapterState = FALSE;
}
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
-void CABTSocketConnectionStateCallback(int result, bt_socket_connection_state_e connectionState,
+void CABTSocketConnectionStateCallback(int result, bt_socket_connection_state_e state,
bt_socket_connection_s *connection, void *userData)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
return;
}
- switch (connectionState)
+ switch (state)
{
case BT_SOCKET_CONNECTED:
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
-void CABTDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e discoveryState,
+void CABTDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e state,
bt_adapter_device_discovery_info_s *discoveryInfo, void *userData)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
return;
}
- switch (discoveryState)
+ switch (state)
{
case BT_ADAPTER_DEVICE_DISCOVERY_STARTED:
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Device discovered [%s]!",
discoveryInfo->remote_name);
if (true == CABTIsServiceSupported((const char **)discoveryInfo->service_uuid,
- discoveryInfo->service_count,
- OIC_BT_SERVICE_ID))
+ discoveryInfo->service_count,
+ OIC_BT_SERVICE_ID))
{
//Check if the deivce is already in the list
u_mutex_lock(gBTDeviceListMutex);
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
-void CABTServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo, void *userData)
+void CABTServiceSearchedCallback(int32_t result, bt_device_sdp_info_s *sdpInfo, void *userData)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
}
if (true == CABTIsServiceSupported((const char **)sdpInfo->service_uuid,
- sdpInfo->service_count, OIC_BT_SERVICE_ID))
+ sdpInfo->service_count, OIC_BT_SERVICE_ID))
{
device->serviceSearched = 1;
if (CA_STATUS_OK != CABTClientConnect(sdpInfo->remote_address, OIC_BT_SERVICE_ID))
void CABTManagerDisconnectAll(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
-
+
u_mutex_lock(gBTDeviceListMutex);
-
+
BTDeviceList *cur = gBTDeviceList;
while (cur != NULL)
{
{
if (CA_STATUS_OK != CABTClientDisconnect(device->socketFD))
{
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to disconnect the client connection address:%s",device->remoteAddress);
+ OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to disconnect with client :%s",
+ device->remoteAddress);
}
device->socketFD = -1;
}
}
-
+
u_mutex_unlock(gBTDeviceListMutex);
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
+CABTData *CACreateBTData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength)
+{
+ CABTData *btData = (CABTData *) OICMalloc(sizeof(CABTData));
+ if (!btData)
+ {
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
+ return NULL;
+ }
+
+ btData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
+ btData->data = (void *)OICMalloc(dataLength);
+ if (NULL == btData->data)
+ {
+ OIC_LOG(ERROR, BLUETOOTH_ADAPTER_TAG, "Memory allocation failed!");
+ CAFreeBTData(btData);
+ return NULL;
+ }
+ memcpy(btData->data, data, dataLength);
+ btData->dataLen = dataLength;
+
+ return btData;
+}
+void CAFreeBTData(CABTData *btData)
+{
+ if (!btData)
+ return;
+
+ CAAdapterFreeRemoteEndpoint(btData->remoteEndpoint);
+ OICFree(btData->data);
+ OICFree(btData);
+}
* @brief Start RFCOMM server for given service UUID.
*
* @param[in] serviceUUID The UUID of service with which RFCOMM server needs to be started
- * @param[out] serverID The ID for the server which started
*
* @return #CA_STATUS_OK on success otherwise proper error code.
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_FAILED Operation failed
*
*/
-CAResult_t CABTManagerStartServer(const char *serviceUUID, int32_t *serverID);
+CAResult_t CABTManagerStartServer(void);
/**
* @fn CABTManagerStopServer
* @brief Stop RFCOMM server
*
- * @param[in] serverID The ID of server which needs to be stopped
- *
* @return #CA_STATUS_OK on success otherwise proper error code.
* @retval #CA_STATUS_OK Successful
* @retval #CA_STATUS_FAILED Operation failed
*
* @see CABTManagerStartServer()
*/
-CAResult_t CABTManagerStopServer(const int32_t serverID);
+CAResult_t CABTManagerStopServer(void);
/**
* @fn CABTManagerGetInterface
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
bool isRunning = false;
- int socketFD;
+ int32_t socketFD;
VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "Service UUID is null");
VERIFY_NON_NULL(serverFD, BLUETOOTH_ADAPTER_TAG, "Server fd holder is null");
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- int err = BT_ERROR_NONE;
+ bt_error_e err = BT_ERROR_NONE;
if (BT_ERROR_NONE != (err = bt_socket_destroy_rfcomm(serverFD)))
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed close server socket!, error num [%x]",
#include <bluetooth.h>
bool CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount,
- const char *matchService)
+ const char *matchService)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
*
*/
bool CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount,
- const char *matchService);
+ const char *matchService);
#ifdef __cplusplus
} /* extern "C" */
#include "caadapterutils.h"
#include "logger.h"
-static int32_t gDiscoveryServerID = -1;
-static int32_t gListeningServerID = -1;
-static int32_t gNotificationServerID = -1;
-
-static CAResult_t CAStartServer(const char *serviceUUID, int32_t *serverID);
+static CAResult_t CAStartServer(void);
CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
CANetworkPacketReceivedCallback packetReceivedCallback,
//Input validation
VERIFY_NON_NULL(registerCallback, BLUETOOTH_ADAPTER_TAG,
- "register callback is NULL");
+ "register callback is NULL");
VERIFY_NON_NULL(packetReceivedCallback, BLUETOOTH_ADAPTER_TAG,
- "data receive callback is NULL");
+ "data receive callback is NULL");
VERIFY_NON_NULL(networkStateChangeCallback, BLUETOOTH_ADAPTER_TAG,
- "network state change callback is NULL");
+ "network state change callback is NULL");
VERIFY_NON_NULL(handle, BLUETOOTH_ADAPTER_TAG, "Thread pool hanlde is NULL");
//Register the callbacks with BT Manager
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- return CAStartServer(OIC_BT_SERVICE_ID, &gListeningServerID);
+ return CAStartServer();
}
CAResult_t CAStartEDRDiscoveryServer(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- return CAStartServer(OIC_BT_SERVICE_ID, &gDiscoveryServerID);
+ return CAStartServer();
}
uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength)
+ uint32_t dataLength)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
const char *serviceUUID = OIC_BT_SERVICE_ID;
const char *address = remoteEndpoint->addressInfo.BT.btMacAddress;
if (CA_STATUS_OK != (err = CABTManagerSendData(address, serviceUUID, data,
- dataLength, &sentLength)))
+ dataLength, &sentLength)))
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Send unicast data failed!, error num [%d]", err);
return 0;
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
- //Stop the Discovery server
- if (-1 < gDiscoveryServerID)
- {
- CABTManagerStopServer(gDiscoveryServerID);
- }
-
- //Stop the Listening server
- if (-1 < gListeningServerID)
- {
- CABTManagerStopServer(gListeningServerID);
- }
-
- //Stop the Notification server
- if (-1 < gNotificationServerID)
- {
- CABTManagerStopServer(gNotificationServerID);
- }
+ CABTManagerStopServer();
//Stop the adapter
CABTManagerStop();
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
}
-CAResult_t CAStartServer(const char *serviceUUID, int32_t *serverID)
+CAResult_t CAStartServer(void)
{
OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
CAResult_t err = CA_STATUS_OK;
- //Input validation
- VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "Service UUID is NULL");
- VERIFY_NON_NULL(serverID, BLUETOOTH_ADAPTER_TAG, "Server ID is NULL");
- if (0 == strlen(serviceUUID))
- {
- OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Service UUID is empty!");
- return CA_STATUS_INVALID_PARAM;
- }
-
- if (CA_STATUS_OK != (err = CABTManagerStartServer(serviceUUID, serverID)))
+ if (CA_STATUS_OK != (err = CABTManagerStartServer()))
{
OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to start RFCOMM server!, error num [%d]",
err);
* limitations under the License.
*
******************************************************************/
-#include "caleadapter_singlethread.h"
+#include "caleadapter.h"
+
+#include <TimedAction.h>
+
+#include "caleinterface.h"
#include "caleserver.h"
#include "logger.h"
#include "caadapterutils.h"
+#include "camsgparser.h"
static CANetworkChangeCallback networkCallback = NULL;
+static bool gServerRunning = false;
#define BLE_ADDRESS "DB:F7:EB:B5:0F:07"
#define TAG "CALEADAPTER"
+#define COAP_MAX_PDU_SIZE 320
+
+static CANetworkPacketReceivedCallback gRespCallback;
+static char *gCoapBuffer = NULL;
+static int32_t dataLen = 0;
+static uint16_t packetDataLen = 0;
+
/**
* @brief API to store the networkcallback passed from top layer, register BLE network notification
* @param net_callback - network notification callback
- * @return - int
+ * @return - Error Code
*/
-int LERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
+CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
+
+/**
+ * @brief API to send received data to upper layer
+ * @param[in] data - data received from BLE characteristics
+ * @param[in] dataLen - received data Length
+ * @param[in] senderAdrs - sender Address.
+ * @param[in] senderPort - sender port
+ * @return - Error Code
+ */
+void CANotifyCallback(void *data, int32_t dataLen, char *senderAdrs, int32_t senderPort);
+
+/**
+ * @brief API to read the data from characteristics and invoke notifyCallback
+ * @return - void
+ */
+void CACheckData();
+
+static TimedAction gRcvAction = TimedAction(2000, CACheckData);
+
CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback)
+ CANetworkPacketReceivedCallback reqRespCallback,
+ CANetworkChangeCallback netCallback)
{
OIC_LOG(DEBUG, TAG, "IN");
if (NULL == registerCallback || NULL == reqRespCallback || NULL == netCallback)
return CA_STATUS_INVALID_PARAM;
}
- CASetBLEReqRescallback(reqRespCallback);
+ gRespCallback = reqRespCallback;
LERegisterNetworkNotifications(netCallback);
CAConnectivityHandler_t connHandler;
connHandler.startAdapter = NULL;
CAResult_t CAReadLEData()
{
- CAArduoinoCheckServerData();
+ CABleDoEvents();
+ gRcvAction.check();
+ return CA_STATUS_OK;
}
void CATerminateLE()
{
OIC_LOG(DEBUG, TAG, "IN");
- CASetBLEReqRescallback(NULL);
+ gRespCallback = NULL;
LERegisterNetworkNotifications(NULL);
+ gRcvAction.disable();
CAStopBleGattServer();
OIC_LOG(DEBUG, TAG, "OUT");
return;
{
OIC_LOG(DEBUG, TAG, "IN");
CAInitializeBle();
- CAArduoinoCheckServerData();
+ gRcvAction.enable();
+ CABleDoEvents();
+ gRcvAction.check();
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
return CA_STATUS_OK;
}
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
+uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t dataLen)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsInGattServer(const char *char_value,
+ const uint32_t value_length)
{
+ // Only 1 characteristic will be used for sending data from server
OIC_LOG(DEBUG, TAG, "IN");
+
+ char *header = NULL;
+ header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+ if (NULL == header)
+ {
+ OIC_LOG(DEBUG, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+
+ memset(header, 0, sizeof(char) * CA_HEADER_LENGTH);
+ CAResult_t result = CAGenerateHeader(header, value_length);
+
+ if (CA_STATUS_OK != result)
+ {
+ return CA_STATUS_FAILED;
+ }
+
+ int32_t index = 0;
+
+ if(!CAIsBleConnected())
+ {
+ OIC_LOG(DEBUG, TAG, "ble is not connected");
+ return CA_STATUS_FAILED;
+ }
+
+ CAWriteBleData((unsigned char *)header, CA_HEADER_LENGTH);
+ int32_t iter = value_length/CA_SUPPORTED_BLE_MTU_SIZE;
+
+ for (index = 0; index < iter; index++)
+ {
+ CAWriteBleData((unsigned char *)(char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ (unsigned char) CA_SUPPORTED_BLE_MTU_SIZE);
+ CABleDoEvents();
+ }
+
+ CAWriteBleData((unsigned char *)(char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
+ (unsigned char) value_length%CA_SUPPORTED_BLE_MTU_SIZE);
+ CABleDoEvents();
+ OIC_LOG(DEBUG, TAG, "ble_write_bytes had been done");
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
-uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data, uint32_t dataLen)
+uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLen)
{
OIC_LOG(DEBUG, TAG, "IN");
if (NULL == remoteEndpoint)
OIC_LOG(ERROR, TAG, "Invalid Input Parameter");
return CA_STATUS_INVALID_PARAM;
}
- char *tempPath = "a";
- CAUpdateCharacteristicsInGattServer(tempPath, (char *)data, dataLen);
+ CAUpdateCharacteristicsInGattServer((char *)data, dataLen);
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
OIC_LOG(ERROR, TAG, "Invalid Parameter");
return CA_STATUS_INVALID_PARAM;
}
- char *tempPath = "a";
- CAUpdateCharacteristicsInGattServer(tempPath, (char *)data, dataLen);
+ CAUpdateCharacteristicsInGattServer((char *)data, dataLen);
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
/**
* Create local endpoint using util function
*/
- (*info) = CAAdapterCreateLocalEndpoint(CA_LE, BLE_ADDRESS, "Le");
+ (*info) = CAAdapterCreateLocalEndpoint(CA_LE, BLE_ADDRESS);
if (NULL == (*info))
{
OIC_LOG(DEBUG, TAG, "Out of memory");
return CA_STATUS_OK;
}
-int LERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
+CAResult_t LERegisterNetworkNotifications(CANetworkChangeCallback netCallback)
{
OIC_LOG(DEBUG, TAG, "IN");
networkCallback = netCallback;
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
+
+CAResult_t CAStartBleGattServer()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ // Done at time of setup i.e. in initializeBle api
+ gServerRunning = true;
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAStopBleGattServer()
+{
+ // Not Supported
+ return CA_STATUS_OK;
+}
+
+void CANotifyCallback(void *data, int32_t dataLen, char *senderAdrs, int32_t senderPort)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ if (gRespCallback)
+ {
+
+ /* Cannot get Address as of now */
+ CARemoteEndpoint_t endPoint;
+ endPoint.resourceUri = ""; // will be filled by upper layer
+ endPoint.connectivityType = CA_LE;
+
+ gRespCallback(&endPoint, data, dataLen);
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CACheckData()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ CABleDoEvents();
+
+ if (CAIsBleDataAvailable())
+ {
+ // Allocate Memory for COAP Buffer and do ParseHeader
+ if (NULL == gCoapBuffer)
+ {
+ OIC_LOG(DEBUG, TAG, "IN");
+ gCoapBuffer = (char *)OICMalloc(COAP_MAX_PDU_SIZE);
+ if (NULL == gCoapBuffer)
+ {
+ OIC_LOG(DEBUG, TAG, "error");
+ return;
+ }
+ while (CAIsBleDataAvailable() && dataLen < 2)
+ {
+ gCoapBuffer[dataLen++] = CAReadBleData();
+ }
+
+ packetDataLen = CAParseHeader(gCoapBuffer);
+ OIC_LOG(DEBUG, TAG, "OUT");
+ memset(gCoapBuffer, 0, COAP_MAX_PDU_SIZE);
+ dataLen = 0;
+ }
+
+ OIC_LOG(DEBUG, TAG, "IN");
+ while (CAIsBleDataAvailable())
+ {
+ OIC_LOG(DEBUG, TAG, "Inside While loop");
+ gCoapBuffer[dataLen++] = CAReadBleData();
+ if (dataLen == packetDataLen)
+ {
+ OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
+ gCoapBuffer[dataLen] = '\0';
+ if (dataLen > 0)
+ {
+ OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", dataLen);
+ CANotifyCallback((void *)gCoapBuffer, dataLen, "", 0);
+ }
+ dataLen = 0;
+ OICFree(gCoapBuffer);
+ gCoapBuffer = NULL;
+ break;
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "No Data on BLE server");
+ }
+ return;
+}
+
+
#include "caleserver.h"
#include <logger.h>
#include "oic_malloc.h"
-#include <camsgparser.h>
-
-#define COAP_MAX_PDU_SIZE 320
-
-static CANetworkPacketReceivedCallback gRespCallback;
-static bool gServerRunning = false;
-static TimedAction gRcvAction = TimedAction(2000, CACheckData);
-static char *gCoapBuffer = NULL;
-static int32_t dataLen = 0;
-static uint16_t packetDataLen = 0;
+#include "caadapterutils.h"
#define TAG "CLS"
OIC_LOG(DEBUG, TAG, "BLE Name Set is completed");
ble_begin();
- gRcvAction.enable();
OIC_LOG(DEBUG, TAG, "OUT");
return CA_STATUS_OK;
}
-void CANotifyCallback(void *data, int32_t dataLen, char *senderAdrs, int32_t senderPort)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- if (gRespCallback)
- {
-
- /* Cannot get Address as of now */
- CARemoteEndpoint_t endPoint;
- endPoint.resourceUri = ""; // will be filled by upper layer
- endPoint.connectivityType = CA_LE;
-
- gRespCallback(&endPoint, data, dataLen);
- }
- OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-void CACheckData()
-{
- OIC_LOG(DEBUG, TAG, "IN");
- dataLen = 0;
- ble_do_events();
-
- if (ble_available())
- {
- // Allocate Memory for COAP Buffer and do ParseHeader
- if (NULL == gCoapBuffer)
- {
- OIC_LOG(DEBUG, TAG, "IN");
- gCoapBuffer = (char *)OICMalloc(COAP_MAX_PDU_SIZE);
- while (ble_available() && dataLen < 2)
- {
- gCoapBuffer[dataLen++] = (char)ble_read();
- }
-
- packetDataLen = CAParseHeader(gCoapBuffer);
- OIC_LOG(DEBUG, TAG, "OUT");
- memset(gCoapBuffer, 0, COAP_MAX_PDU_SIZE);
- dataLen = 0;
- }
-
- OIC_LOG(DEBUG, TAG, "IN");
- while (ble_available())
- {
- OIC_LOG(DEBUG, TAG, "Inside While loop");
- gCoapBuffer[dataLen++] = (char)ble_read();
- if (dataLen == packetDataLen)
- {
- OIC_LOG(DEBUG, TAG, "Read Comp BLE Pckt");
- gCoapBuffer[dataLen] = '\0';
- if (dataLen > 0)
- {
- OIC_LOG_V(DEBUG, TAG, "recv dataLen=%d", dataLen);
- CANotifyCallback((void *)gCoapBuffer, dataLen, "", 0);
- }
- OICFree(gCoapBuffer);
- gCoapBuffer = NULL;
- break;
- }
- }
- OIC_LOG(DEBUG, TAG, "OUT");
- }
- else
- {
- OIC_LOG(DEBUG, TAG, "No Data on BLE server");
- }
-}
-
-void CAArduoinoCheckServerData()
-{
- ble_do_events();
- gRcvAction.check();
-}
-
-void CASetBLEReqRescallback(CANetworkPacketReceivedCallback callback)
-{
- OIC_LOG(DEBUG, TAG, "IN");
- gRespCallback = callback;
- OIC_LOG(DEBUG, TAG, "OUT");
-}
-
-CAResult_t CAStartBleGattServer()
-{
- OIC_LOG(DEBUG, TAG, "IN");
- // Done at time of setup i.e. in initializeBle api
- gServerRunning = true;
- OIC_LOG(DEBUG, TAG, "OUT");
- return CA_STATUS_OK;
-}
-CAResult_t CAStopBleGattServer()
-{
- // Not Supported
- return CA_STATUS_OK;
-}
-
CAResult_t CAAddNewBleServiceInGattServer(const char *service_uuid)
{
// Not Supported - Done at compile time
return CA_STATUS_OK;
}
-CAResult_t CAAddNewCharacteristicsToGattServer(const char *svc_path, const char *char_uuid,
+CAResult_t CAAddNewCharacteristicsToGattServer(const char *svc_path,
+ const char *char_uuid,
const char *char_value,
int char_value_len,
int read)
return CA_STATUS_OK;
}
-CAResult_t CAUpdateCharacteristicsInGattServer(const char *char_path,
- const char *char_value, int value_length)
+unsigned char CAIsBleDataAvailable()
{
- // Only 1 characteristic will be used for sending data from server
- OIC_LOG(DEBUG, TAG, "IN");
+ return ble_available();
+}
- char *header = NULL;
- header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
- memset(header, 0, sizeof(char) * CA_HEADER_LENGTH);
- CAResult_t result = CAGenerateHeader(header, value_length);
- if (CA_STATUS_OK != result)
- {
- return CA_STATUS_FAILED;
- }
- int index = 0;
- if (ble_connected())
- {
- ble_write_bytes((unsigned char *)header, CA_HEADER_LENGTH);
- int iter = value_length/CA_SUPPORTED_BLE_MTU_SIZE;
-
- for (index = 0; index < iter; index++)
- {
- ble_write_bytes((unsigned char *)(char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
- (unsigned char) CA_SUPPORTED_BLE_MTU_SIZE);
- ble_do_events();
- }
-
- ble_write_bytes((unsigned char *)(char_value + (index * CA_SUPPORTED_BLE_MTU_SIZE)),
- (unsigned char) value_length%CA_SUPPORTED_BLE_MTU_SIZE);
- ble_do_events();
- OIC_LOG(DEBUG, TAG,
- "ble_write_bytes had been done");
- }
- else
- {
- OIC_LOG(DEBUG, TAG, "ble is not connected");
- return CA_STATUS_FAILED;
- }
- OIC_LOG(DEBUG, TAG, "OUT");
+unsigned char CAIsBleConnected()
+{
+ return ble_connected();
+}
+char CAReadBleData()
+{
+ return (char)ble_read();
+}
+
+CAResult_t CABleDoEvents()
+{
+ ble_do_events();
return CA_STATUS_OK;
}
+
+CAResult_t CAWriteBleData(unsigned char *data, uint8_t len)
+{
+ // Currently ble_write_bytes api returns void.
+ ble_write_bytes(data, len);
+ return CA_STATUS_OK;
+}
\ No newline at end of file
#include <boards.h>
#include <RBL_nRF8001.h>
#include <services.h>
-#include <TimedAction.h>
#include "cacommon.h"
#include "caadapterinterface.h"
void CANotifyCallback(void *data, int32_t dataLen, char *senderAdrs, int32_t senderPort);
/**
- * @brief API to read the data from characteristics and invoke notifyCallback
- * @return - void
- */
-void CACheckData();
-
-/**
- * @brief API to invoke CheckData at a regular interval of time.
- * @return - void
- */
-void CAArduoinoCheckServerData();
-
-/**
- * @brief API to set request response callback to upper layer.
- * @param[in] callback - upper layer callback function to pass the data received in the server.
- * @return - Error Code
- */
-void CASetBLEReqRescallback(CANetworkPacketReceivedCallback callback);
-
-/**
- * @brief API to start Ble Gatt server.
- * @return - Error Code
- */
-CAResult_t CAStartBleGattServer();
-
-/**
- * @brief API to stop Ble Gatt server.
- * @param[in] serverID - unique identifier for each server.
- * @return - Error Code
- */
-CAResult_t CAStopBleGattServer();
-
-/**
* @brief API to add new service in Gatt Server
* @param[in] service_uuid - unique identifier for each service.
* @return - Error Code
* @param[out] char_path characteristic path registered on the interface.
* @return - Error Code
*/
-CAResult_t CAAddNewCharacteristicsToGattServer(const char *svc_path, const char *char_uuid,
+CAResult_t CAAddNewCharacteristicsToGattServer(const char *svc_path,
+ const char *char_uuid,
const char *char_value,
int char_value_len,
int read);
/**
* @brief API to remove the characteristics.
- * @param[in] char_path characteristic path registered on the interface and unique identifier for added characteristics.
+ * @param[in] char_path characteristic path registered on the interface and unique
+ * identifier for added characteristics.
* @return - Error Code
*/
CAResult_t CARemoveCharacteristicsFromGattServer(const char *char_path);
/**
- * @brief API to update the characteristic value from server side.
- * @param[in] char_path characteristic path registered on the interface and unique identifier for added characteristics.
- * @param[in] char_value Gatt characteristic value.
- * @param[in] value_length Caracteristic value length.
+ * @brief API to check whether data is available in BLE shield
+ * @return - unsigned char
+ */
+unsigned char CAIsBleDataAvailable();
+
+/**
+ * @brief API to check whether client is connected with BLE Shield
+ * @return - unsigned char
+ */
+unsigned char CAIsBleConnected();
+
+/**
+ * @brief API to read data from BLE shield
+ * @return - char
+ */
+char CAReadBleData();
+
+/**
+ * @brief API to perform BLE events
* @return - Error Code
*/
-CAResult_t CAUpdateCharacteristicsInGattServer(const char *char_path, const char *char_value,
- int value_length);
+CAResult_t CABleDoEvents();
+
+/**
+ * @brief API used to send data to connected ble client
+ *
+ * @param[in] data - data to be sent
+ * @param[in] len - data length
+ *
+ * @return Error Code
+ */
+CAResult_t CAWriteBleData(unsigned char *data, uint8_t len);
#endif //#ifndef _BLE_ADAPTER_ARDUINO_H_
#include "BLEAdapterArduino.h"
#include "caadapterutils.h"
#endif //#ifdef __TIZEN__
+#include "caqueueingthread.h"
+#include "camsgparser.h"
+
+
#define CALEADAPTER_TAG "CA_BLE_ADAPTER"
static CANetworkChangeCallback gNetworkCallback = NULL;
static u_mutex gBleLocalAddressMutex = NULL;
+/**
+ * @var gBleClientThreadPool
+ * @brief reference to threadpool
+ */
+static u_thread_pool_t gBleAdapterThreadPool = NULL;
+
+/**
+ * @var gBleAdapterThreadPoolMutex
+ * @brief Mutex to synchronize the task to be pushed to thread pool.
+ */
+static u_mutex gBleAdapterThreadPoolMutex = NULL;
+
+/**
+ * @var gBLEClientSendQueueHandle
+ * @brief Queue to process the outgoing packets from GATTClient.
+ */
+static CAQueueingThread_t *gBLEClientSendQueueHandle = NULL;
+
+/**
+ * @var gCABleClientReceiverQueue
+ * @brief Queue to process the incoming packets to GATT Client.
+ */
+static CAQueueingThread_t *gCABleClientReceiverQueue = NULL;
+
+/**
+ * @var gBleClientSendDataMutex
+ * @brief Mutex to synchronize the queing of the data from SenderQueue.
+ */
+static u_mutex gBleClientSendDataMutex = NULL;
+
+
+/**
+ * @var gBleClientReceiveDataMutex
+ * @brief Mutex to synchronize the queing of the data from ReceiverQueue.
+ */
+static u_mutex gBleClientReceiveDataMutex = NULL;
+
+/**
+ * @var gDataReceiverHandlerState
+ * @brief Stop condition of redvhandler.
+ */
+static bool gDataReceiverHandlerState = false;
+
+/**
+ * @var isHeaderAvailable
+ * @brief to differentiate btw header and data packet.
+ */
+static CABool_t isHeaderAvailable = false;
+
+/**
+ * @var gNetworkPacketReceivedServerCallback
+ * @brief Maintains the callback to be notified on receival of network packets from other
+ * BLE devices
+ */
+static CANetworkPacketReceivedCallback gNetworkPacketReceivedServerCallback = NULL;
+
+/**
+ * @var gSendQueueHandle
+ * @brief Queue to process the outgoing packets from GATTServer.
+ */
+//static CAAdapterMessageQueue_t *gSendQueueHandle = NULL;
+
+static CAQueueingThread_t *gSendQueueHandle = NULL;
+
+/**
+ * @var gCABleServerReceiverQueue
+ * @brief Queue to process the incoming packets to GATTServer
+ */
+static CAQueueingThread_t *gCABleServerReceiverQueue = NULL;
+
+/**
+ * @var gBleServerSendDataMutex
+ * @brief Mutex to synchronize the queing of the data from SenderQueue.
+ */
+static u_mutex gBleServerSendDataMutex = NULL;
+
+/**
+ * @var gBleServerReceiveDataMutex
+ * @brief Mutex to synchronize the queing of the data from ReceiverQueue.
+ */
+static u_mutex gBleServerReceiveDataMutex = NULL;
+
+static u_mutex gBleAdapterReqRespCbMutex = NULL;
+
+static CANetworkPacketReceivedCallback gNetworkPacketReceivedCallback = NULL;
+/**
+ * @ENUM CALeServerStatus
+ * @brief status of BLE Server Status
+ *
+ * This ENUM provides information of LE Adapter Server status
+ */
+typedef enum
+{
+ CA_SERVER_NOTSTARTED = 0,
+ CA_LISTENING_SERVER,
+ CA_DISCOVERY_SERVER
+} CALeServerStatus;
+
+static CALeServerStatus gLeServerStatus = CA_SERVER_NOTSTARTED;
+
int32_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback);
#ifdef __TIZEN__
void CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state,
- void *user_data);
+ void *user_data);
CAResult_t CAInitBleAdapterMutex();
CAResult_t CATermiateBleAdapterMutex();
VERIFY_NON_NULL(netCallback, NULL, "NetworkChange Callback is null");
CAResult_t result = CAInitBleAdapterMutex();
-
if (CA_STATUS_OK != result)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleAdapterMutex failed!");
CASetBleServerThreadPoolHandle(handle);
CASetBleClientThreadPoolHandle(handle);
- CASetBLEReqRespServerCallback(reqRespCallback);
- CASetBLEReqRespClientCallback(reqRespCallback);
+ CASetBleAdapterThreadPoolHandle(handle);
+ CASetBLEReqRespServerCallback(CABLEServerReceivedData);
+ CASetBLEReqRespClientCallback(CABLEClientReceivedData);
+ CASetBLEReqRespAdapterCallback(reqRespCallback);
+
CALERegisterNetworkNotifications(netCallback);
CAConnectivityHandler_t connHandler;
}
u_mutex_unlock(gBleIsServerMutex);
+ CATerminateBleQueues();
+
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return;
}
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+ bt_error_e err = BT_ERROR_NONE;
+ bt_adapter_state_e adapterState;
+
+ CAResult_t result = CAInitBleServerQueues();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ return CA_STATUS_FAILED;
+ }
+
+ //Get Bluetooth adapter state
+ if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!, error num [%x]",
+ err);
+
+ return CA_STATUS_FAILED;
+ }
+
+ if (BT_ADAPTER_ENABLED != adapterState)
+ {
+ gLeServerStatus = CA_LISTENING_SERVER;
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Listen Server will be started once BT Adapter is enabled");
+ return CA_STATUS_OK;
+ }
+
CAStartBleGattServer();
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+ bt_error_e err = BT_ERROR_NONE;
+ bt_adapter_state_e adapterState;
+
+ CAResult_t result = CAInitBleClientQueues();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ return CA_STATUS_FAILED;
+ }
+
+ //Get Bluetooth adapter state
+ if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Bluetooth get state failed!, error num [%x]",
+ err);
+
+ return CA_STATUS_FAILED;
+ }
+
+ if (BT_ADAPTER_ENABLED != adapterState)
+ {
+ gLeServerStatus = CA_DISCOVERY_SERVER;
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Disc Server will be started once BT Adapter is enabled");
+ return CA_STATUS_OK;
+ }
+
CAStartBLEGattClient();
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
u_mutex_lock(gBleIsServerMutex);
if (CA_TRUE == gIsServer)
{
- result = CABleServerSenderQueueEnqueueMessage(endpoint, data, dataLen);
+ result = CABLEServerSendData(endpoint, data, dataLen);
if (CA_STATUS_OK != result)
{
OIC_LOG(ERROR, CALEADAPTER_TAG,
}
else
{
-
- result = CABleClientSenderQueueEnqueueMessage(endpoint, data, dataLen);
+ result = CABLEClientSendData(endpoint, data, dataLen);
if (CA_STATUS_OK != result)
{
OIC_LOG(ERROR, CALEADAPTER_TAG,
u_mutex_lock(gBleIsServerMutex);
if (CA_TRUE == gIsServer)
{
- result = CABleServerSenderQueueEnqueueMessage(NULL, data, dataLen);
+ result = CABLEServerSendData(NULL, data, dataLen);
if (CA_STATUS_OK != result)
{
OIC_LOG(ERROR, CALEADAPTER_TAG,
}
else
{
- result = CABleClientSenderQueueEnqueueMessage(NULL, data, dataLen);
+ result = CABLEClientSendData(NULL, data, dataLen);
if (CA_STATUS_OK != result)
{
OIC_LOG(ERROR, CALEADAPTER_TAG,
strncpy(localEndpoint.addressInfo.BT.btMacAddress, gLocalBLEAddress, strlen(gLocalBLEAddress));
u_mutex_unlock(gBleLocalAddressMutex);
+ // Start a GattServer/Client if gLeServerStatus is SET
+ if (CA_LISTENING_SERVER == gLeServerStatus)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartBleGattServer");
+ CAStartBleGattServer();
+ }
+ else if (CA_DISCOVERY_SERVER == gLeServerStatus)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartBleGattClient");
+ CAStartBLEGattClient();
+ }
+ gLeServerStatus = CA_SERVER_NOTSTARTED;
+
u_mutex_lock(gBleNetworkCbMutex);
if (NULL != gNetworkCallback)
{
OIC_LOG(ERROR, CALEADAPTER_TAG, "gNetworkCallback is NULL");
}
u_mutex_unlock(gBleNetworkCbMutex);
+
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
}
return CA_STATUS_FAILED;
}
}
+
+ if (NULL == gBleAdapterThreadPoolMutex)
+ {
+ gBleAdapterThreadPoolMutex = u_mutex_new();
+ if (NULL == gBleAdapterThreadPoolMutex)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ if (NULL == gBleClientSendDataMutex)
+ {
+ gBleClientSendDataMutex = u_mutex_new();
+ if (NULL == gBleClientSendDataMutex)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ if (NULL == gBleClientReceiveDataMutex)
+ {
+ gBleClientReceiveDataMutex = u_mutex_new();
+ if (NULL == gBleClientReceiveDataMutex)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ if (NULL == gBleServerSendDataMutex)
+ {
+ gBleServerSendDataMutex = u_mutex_new();
+ if (NULL == gBleServerSendDataMutex)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ if (NULL == gBleServerReceiveDataMutex)
+ {
+ gBleServerReceiveDataMutex = u_mutex_new();
+ if (NULL == gBleServerReceiveDataMutex)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
+ if (NULL == gBleAdapterReqRespCbMutex)
+ {
+ gBleAdapterReqRespCbMutex = u_mutex_new();
+ if (NULL == gBleAdapterReqRespCbMutex)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed");
+ return CA_STATUS_FAILED;
+ }
+ }
+
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
return CA_STATUS_OK;
}
CAResult_t CATermiateBleAdapterMutex()
{
OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
u_mutex_free(gBleIsServerMutex);
gBleIsServerMutex = NULL;
+
u_mutex_free(gBleNetworkCbMutex);
gBleNetworkCbMutex = NULL;
+
u_mutex_free(gBleLocalAddressMutex);
gBleLocalAddressMutex = NULL;
+
+ u_mutex_free(gBleAdapterThreadPoolMutex);
+ gBleAdapterThreadPoolMutex = NULL;
+
+ u_mutex_free(gBleClientSendDataMutex);
+ gBleClientSendDataMutex = NULL;
+
+ u_mutex_free(gBleClientReceiveDataMutex);
+ gBleClientReceiveDataMutex = NULL;
+
+ u_mutex_free(gBleServerSendDataMutex);
+ gBleServerSendDataMutex = NULL;
+
+ u_mutex_free(gBleServerReceiveDataMutex);
+ gBleServerReceiveDataMutex = NULL;
+
+ u_mutex_free(gBleAdapterReqRespCbMutex);
+ gBleAdapterReqRespCbMutex = NULL;
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAInitBleQueues()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ CAResult_t result = CAInitBleServerQueues();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ return;
+ }
+
+ result = CAInitBleClientQueues();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ return;
+ }
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return;
+
+}
+
+CAResult_t CAInitBleServerQueues()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ u_mutex_lock(gBleAdapterThreadPoolMutex);
+
+ CAResult_t result = CAInitBleServerSenderQueue();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+ return CA_STATUS_FAILED;
+ }
+
+ result = CAInitBleServerReceiverQueue();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+ return CA_STATUS_FAILED;
+ }
+
+ gDataReceiverHandlerState = true;
+
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAInitBleClientQueues()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ u_mutex_lock(gBleAdapterThreadPoolMutex);
+
+ CAResult_t result = CAInitBleClientSenderQueue();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+ return CA_STATUS_FAILED;
+ }
+
+ result = CAInitBleClientReceiverQueue();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientQueues failed");
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+ return CA_STATUS_FAILED;
+ }
+
+ gDataReceiverHandlerState = true;
+
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+
OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
return CA_STATUS_OK;
}
+
+CAResult_t CAInitBleServerSenderQueue()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+ // Check if the message queue is already initialized
+ if (gSendQueueHandle)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+ return CA_STATUS_OK;
+ }
+
+ // Create send message queue
+ gSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gSendQueueHandle)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gBleAdapterThreadPool,
+ CABLEServerSendDataThread))
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+ OICFree(gSendQueueHandle);
+ gSendQueueHandle = NULL;
+ return CA_STATUS_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "u_thread_pool_add_task failed ");
+ OICFree(gSendQueueHandle);
+ gSendQueueHandle = NULL;
+ return CA_STATUS_FAILED;
+ }
+
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+
+}
+
+CAResult_t CAInitBleClientSenderQueue()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ if (gBLEClientSendQueueHandle)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+ return CA_STATUS_OK;
+ }
+
+ // Create send message queue
+ gBLEClientSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gBLEClientSendQueueHandle)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gBLEClientSendQueueHandle, gBleAdapterThreadPool,
+ CABLEClientSendDataThread))
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+ OICFree(gBLEClientSendQueueHandle);
+ gBLEClientSendQueueHandle = NULL;
+ return CA_STATUS_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadStart(gBLEClientSendQueueHandle))
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "u_thread_pool_add_task failed ");
+ OICFree(gBLEClientSendQueueHandle);
+ gBLEClientSendQueueHandle = NULL;
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAInitBleServerReceiverQueue()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+ // Check if the message queue is already initialized
+ if (gCABleServerReceiverQueue)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+ return CA_STATUS_OK;
+ }
+
+ // Create send message queue
+ gCABleServerReceiverQueue = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gCABleServerReceiverQueue)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+ OICFree(gSendQueueHandle);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gCABleServerReceiverQueue, gBleAdapterThreadPool,
+ CABLEServerDataReceiverHandler))
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+ OICFree(gCABleServerReceiverQueue);
+ gCABleServerReceiverQueue = NULL;
+ return CA_STATUS_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadStart(gCABleServerReceiverQueue))
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "u_thread_pool_add_task failed ");
+ OICFree(gCABleServerReceiverQueue);
+ gCABleServerReceiverQueue = NULL;
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAInitBleClientReceiverQueue()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ // Check if the message queue is already initialized
+ if (gCABleClientReceiverQueue)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+ }
+ else
+ {
+ // Create send message queue
+ gCABleClientReceiverQueue = OICMalloc(sizeof(CAQueueingThread_t));
+ if (!gCABleClientReceiverQueue)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+ OICFree(gBLEClientSendQueueHandle);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ if (CA_STATUS_OK != CAQueueingThreadInitialize(gCABleClientReceiverQueue, gBleAdapterThreadPool,
+ CABLEClientDataReceiverHandler))
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
+ OICFree(gBLEClientSendQueueHandle);
+ OICFree(gCABleClientReceiverQueue);
+ gCABleClientReceiverQueue = NULL;
+ return CA_STATUS_FAILED;
+ }
+ }
+ //gClientUp = CA_TRUE; //AMOGH
+
+ if (CA_STATUS_OK != CAQueueingThreadStart(gCABleClientReceiverQueue))
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "u_thread_pool_add_task failed ");
+ OICFree(gCABleClientReceiverQueue);
+ gCABleClientReceiverQueue = NULL;
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CATerminateBleQueues()
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ u_mutex_lock(gBleClientSendDataMutex);
+ if (NULL != gBLEClientSendQueueHandle)
+ {
+ CAQueueingThreadStop(gBLEClientSendQueueHandle);
+ gBLEClientSendQueueHandle = NULL;
+ }
+ u_mutex_unlock(gBleClientSendDataMutex);
+
+ u_mutex_lock(gBleClientReceiveDataMutex);
+ if (NULL != gCABleClientReceiverQueue)
+ {
+ CAQueueingThreadStop(gCABleClientReceiverQueue);
+ gCABleClientReceiverQueue = NULL;
+ }
+ u_mutex_unlock(gBleClientReceiveDataMutex);
+
+ u_mutex_lock(gBleServerSendDataMutex);
+ if (NULL != gBLEClientSendQueueHandle)
+ {
+ CAQueueingThreadStop(gBLEClientSendQueueHandle);
+ gBLEClientSendQueueHandle = NULL;
+ }
+ u_mutex_unlock(gBleServerSendDataMutex);
+
+ u_mutex_lock(gBleServerReceiveDataMutex);
+ if (NULL != gCABleServerReceiverQueue)
+ {
+ CAQueueingThreadStop(gCABleServerReceiverQueue);
+ gCABleServerReceiverQueue = NULL;
+ }
+ u_mutex_unlock(gBleServerReceiveDataMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+}
+
+void CABLEServerDataReceiverHandler(void *threadData)
+{
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN");
+
+ // CAAdapterMessage_t *message = NULL;
+ static const char *remoteAddress = NULL;
+ static const char *serviceUUID = NULL;
+ static uint32_t recvDataLen = 0;
+ static uint32_t totalDataLen = 0;
+ static char *defragData = NULL;
+ static isHeaderAvailable = false;
+ static CARemoteEndpoint_t *remoteEndpoint = NULL;
+
+ u_mutex_lock(gBleClientReceiveDataMutex);
+
+ if (gDataReceiverHandlerState)
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+
+ CABLEData *bleData = (CABLEData *) threadData;
+ if (!bleData)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid wifidata!");
+ return;
+ }
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+
+ if (!isHeaderAvailable)
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Parsing the header");
+ char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+ VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "header is NULL");
+
+ memcpy(header, bleData->data, CA_HEADER_LENGTH);
+ totalDataLen = CAParseHeader(header);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "data received in the first packet [%d] bytes", bleData->dataLen);
+ defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+ if (NULL == defragData)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
+ OICFree(header);
+ return;
+ }
+
+ OICFree(header);
+
+ remoteAddress = bleData->remoteEndpoint->addressInfo.LE.leMacAddress;
+ serviceUUID = bleData->remoteEndpoint->resourceUri;
+
+ remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ serviceUUID);
+
+ memcpy(defragData + recvDataLen, bleData->data + CA_HEADER_LENGTH,
+ bleData->dataLen - CA_HEADER_LENGTH);
+ recvDataLen += bleData->dataLen - CA_HEADER_LENGTH;
+ isHeaderAvailable = true;
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen);
+ memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen);
+ recvDataLen += bleData->dataLen ;
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength [%d] recveived Datalen [%d]",
+ totalDataLen, recvDataLen);
+ }
+ CAFreeBLEData(bleData);
+ if (totalDataLen == recvDataLen)
+ {
+ u_mutex_lock(gBleAdapterReqRespCbMutex);
+ if (NULL == gNetworkPacketReceivedCallback)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
+ u_mutex_unlock(gBleAdapterReqRespCbMutex);
+ return;
+ }
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending data up !");
+ gNetworkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
+ recvDataLen = 0;
+ totalDataLen = 0;
+ isHeaderAvailable = false;
+ u_mutex_unlock(gBleAdapterReqRespCbMutex);
+ }
+
+ if (false == gDataReceiverHandlerState)
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up");
+ OICFree(defragData);
+ OICFree(remoteEndpoint);
+ u_mutex_unlock(gBleClientReceiveDataMutex);
+ return;
+ }
+ }
+ u_mutex_unlock(gBleClientReceiveDataMutex);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT");
+}
+
+void CABLEClientDataReceiverHandler(void *threadData)
+{
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN");
+
+ // CAAdapterMessage_t *message = NULL;
+ static const char *remoteAddress = NULL;
+ static const char *serviceUUID = NULL;
+ static uint32_t recvDataLen = 0;
+ static uint32_t totalDataLen = 0;
+ static char *defragData = NULL;
+ static isHeaderAvailable = false;
+ static CARemoteEndpoint_t *remoteEndpoint = NULL;
+
+ u_mutex_lock(gBleClientReceiveDataMutex);
+
+ if (gDataReceiverHandlerState)
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+
+ CABLEData *bleData = (CABLEData *) threadData;
+ if (!bleData)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid wifidata!");
+ return;
+ }
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+
+ if (!isHeaderAvailable)
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Parsing the header");
+ char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+ VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "header is NULL");
+
+ memcpy(header, bleData->data, CA_HEADER_LENGTH);
+ totalDataLen = CAParseHeader(header);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received in the first packet [%d] bytes", bleData->dataLen);
+ defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+ if (NULL == defragData)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
+ OICFree(header);
+ return;
+ }
+
+ OICFree(header);
+
+ remoteAddress = bleData->remoteEndpoint->addressInfo.LE.leMacAddress;
+ serviceUUID = bleData->remoteEndpoint->resourceUri;
+
+ remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+ serviceUUID);
+
+ memcpy(defragData , bleData->data + CA_HEADER_LENGTH,
+ bleData->dataLen - CA_HEADER_LENGTH);
+ recvDataLen += bleData->dataLen - CA_HEADER_LENGTH;
+ isHeaderAvailable = true;
+ }
+ else
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%d]", bleData->dataLen);
+ memcpy(defragData + recvDataLen, bleData->data, bleData->dataLen);
+ recvDataLen += bleData->dataLen ;
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength [%d] recveived Datalen [%d]",
+ totalDataLen, recvDataLen);
+ }
+ CAFreeBLEData(bleData);
+ if (totalDataLen == recvDataLen)
+ {
+ u_mutex_lock(gBleAdapterReqRespCbMutex);
+ if (NULL == gNetworkPacketReceivedCallback)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
+ u_mutex_unlock(gBleAdapterReqRespCbMutex);
+ return;
+ }
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending data up !");
+ gNetworkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
+ recvDataLen = 0;
+ totalDataLen = 0;
+ isHeaderAvailable = false;
+ u_mutex_unlock(gBleAdapterReqRespCbMutex);
+ }
+
+ if (false == gDataReceiverHandlerState)
+ {
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "GATTClient is terminating. Cleaning up");
+ OICFree(defragData);
+ OICFree(remoteEndpoint);
+ u_mutex_unlock(gBleClientReceiveDataMutex);
+ return;
+ }
+ }
+ u_mutex_unlock(gBleClientReceiveDataMutex);
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT");
+}
+
+void CABLEServerSendDataThread(void *threadData)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ CABLEData *bleData = (CABLEData *) threadData;
+ if (!bleData)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
+ return;
+ }
+ char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+ VERIFY_NON_NULL_VOID(header, CALEADAPTER_TAG, "Malloc failed");
+
+ char *dataSegment = (char *) OICMalloc(sizeof(char) * bleData->dataLen + CA_HEADER_LENGTH);
+ if (NULL == dataSegment)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
+ OICFree(header);
+ return;
+ }
+
+ memset(header, 0x0, sizeof(char) * CA_HEADER_LENGTH );
+ memset(dataSegment, 0x0, sizeof(char) * bleData->dataLen );
+
+ CAResult_t result = CAGenerateHeader(header, bleData->dataLen);
+ if (CA_STATUS_OK != result )
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
+ OICFree(header);
+ OICFree(dataSegment);
+ return ;
+ }
+
+ memcpy(dataSegment, header, CA_HEADER_LENGTH);
+ OICFree(header);
+ int32_t length = 0;
+ if (CA_SUPPORTED_BLE_MTU_SIZE >= bleData->dataLen)
+ {
+ length = bleData->dataLen + CA_HEADER_LENGTH;
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length);
+ memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen);
+ }
+ else
+ {
+ length = CA_SUPPORTED_BLE_MTU_SIZE;
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length);
+ memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
+ }
+
+ int32_t iter = bleData->dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
+ int32_t index = 0;
+ u_mutex_lock(gBleServerSendDataMutex);
+ // Send the first segment with the header.
+ result = CAUpdateCharacteristicsInGattServer(dataSegment, length);
+ for (index = 1; index < iter; index++)
+ {
+ // Send the remaining header.
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
+ result = CAUpdateCharacteristicsInGattServer(
+ bleData->data + ((index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH),
+ CA_SUPPORTED_BLE_MTU_SIZE);
+ }
+ if (bleData->dataLen / CA_SUPPORTED_BLE_MTU_SIZE)
+ {
+ // send the last segment of the data (Ex: 22 bytes of 622 bytes of data when MTU is 200)
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+ result = CAUpdateCharacteristicsInGattServer(
+ bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+ bleData->dataLen % CA_SUPPORTED_BLE_MTU_SIZE + CA_HEADER_LENGTH);
+ }
+
+ OICFree(bleData->remoteEndpoint);
+ OICFree(bleData);
+ u_mutex_unlock(gBleServerSendDataMutex); // AMOGH is this mutex required ?
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return;
+
+}
+
+void CABLEClientSendDataThread(void *threadData)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ CABLEData *bleData = (CABLEData *) threadData;
+ if (!bleData)
+ {
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
+ return;
+ }
+ char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+ VERIFY_NON_NULL_VOID(*header, CALEADAPTER_TAG, "Malloc failed");
+
+ char *dataSegment = (char *) OICMalloc(sizeof(char) * bleData->dataLen + CA_HEADER_LENGTH);
+ if (NULL == dataSegment)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failed");
+ OICFree(header);
+ return;
+ }
+
+ memset(header, 0x0, sizeof(char) * CA_HEADER_LENGTH );
+ memset(dataSegment, 0x0, sizeof(char) * bleData->dataLen );
+
+ CAResult_t result = CAGenerateHeader(header, bleData->dataLen);
+ if (CA_STATUS_OK != result )
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Generate header failed");
+ OICFree(header);
+ OICFree(dataSegment);
+ return ;
+ }
+ memcpy(dataSegment, header, CA_HEADER_LENGTH);
+ OICFree(header);
+ int32_t length = 0;
+ if (CA_SUPPORTED_BLE_MTU_SIZE >= bleData->dataLen)
+ {
+ length = bleData->dataLen + CA_HEADER_LENGTH;
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length);
+ memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data, bleData->dataLen);
+ }
+ else
+ {
+ length = CA_SUPPORTED_BLE_MTU_SIZE;
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "length [%d]", length);
+ memcpy(dataSegment + CA_HEADER_LENGTH, bleData->data,
+ CA_SUPPORTED_BLE_MTU_SIZE - CA_HEADER_LENGTH);
+ }
+
+ int32_t iter = bleData->dataLen / CA_SUPPORTED_BLE_MTU_SIZE;
+ int32_t index = 0;
+ u_mutex_lock(gBleClientSendDataMutex);
+ if (NULL != bleData->remoteEndpoint)
+ {
+ // Send the first segment with the header.
+ result = CAUpdateCharacteristicsToGattServer(bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
+ dataSegment,
+ length,
+ UNICAST, 0);
+ for (index = 1; index < iter; index++)
+ {
+ // Send the remaining header.
+ result = CAUpdateCharacteristicsToGattServer(bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
+ bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+ CA_SUPPORTED_BLE_MTU_SIZE,
+ UNICAST, 0);
+ }
+ if (bleData->dataLen / CA_SUPPORTED_BLE_MTU_SIZE)
+ {
+ // send the last segment of the data (Ex: 22 bytes of 622 bytes of data when MTU is 200)
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+ result = CAUpdateCharacteristicsToGattServer(bleData->remoteEndpoint->addressInfo.LE.leMacAddress,
+ bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+ bleData->dataLen % CA_SUPPORTED_BLE_MTU_SIZE + CA_HEADER_LENGTH,
+ UNICAST, 0);
+ }
+ }
+ else
+ {
+ // Send the first segment with the header.
+ result = CAUpdateCharacteristicsToAllGattServers(dataSegment + (index * length),
+ length);
+ // Send the remaining header.
+ for (index = 1; index <= iter; index++)
+ {
+ result = CAUpdateCharacteristicsToAllGattServers(
+ bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+ CA_SUPPORTED_BLE_MTU_SIZE);
+ }
+ if (bleData->dataLen / CA_SUPPORTED_BLE_MTU_SIZE)
+ {
+ // send the last segment of the data (Ex: 22 bytes of 622 bytes of data when MTU is 200)
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
+ result = CAUpdateCharacteristicsToAllGattServers(
+ bleData->data + (index * CA_SUPPORTED_BLE_MTU_SIZE) - CA_HEADER_LENGTH,
+ bleData->dataLen % CA_SUPPORTED_BLE_MTU_SIZE + CA_HEADER_LENGTH);
+ }
+ }
+
+ OICFree(bleData->remoteEndpoint);
+ OICFree(bleData);
+ u_mutex_unlock(gBleClientSendDataMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+ return;
+
+}
+
+CABLEData *CACreateBLEData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength)
+{
+ CABLEData *bleData = (CABLEData *) OICMalloc(sizeof(CABLEData));
+ if (!bleData)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+ return NULL;
+ }
+
+ bleData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
+ bleData->data = (void *)OICMalloc(dataLength);
+ if (NULL == bleData->data)
+ {
+ OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+ CAFreeBLEData(bleData);
+ return NULL;
+ }
+ memcpy(bleData->data, data, dataLength);
+ bleData->dataLen = dataLength;
+
+ return bleData;
+}
+
+void CAFreeBLEData(CABLEData *bleData)
+{
+ if (!bleData)
+ return;
+
+ CAAdapterFreeRemoteEndpoint(bleData->remoteEndpoint);
+ OICFree(bleData->data);
+ OICFree(bleData);
+}
+
+CAResult_t CABLEClientSendData(const CARemoteEndpoint_t *remoteEndpoint,
+ void *data,
+ uint32_t dataLen)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN ");
+
+ VERIFY_NON_NULL(data, NULL, "Param data is NULL");
+
+ VERIFY_NON_NULL_RET(gBLEClientSendQueueHandle, CALEADAPTER_TAG,
+ "gBLEClientSendQueueHandle is NULL",
+ CA_STATUS_FAILED);
+ VERIFY_NON_NULL_RET(gBleClientSendDataMutex, CALEADAPTER_TAG,
+ "gBleClientSendDataMutex is NULL",
+ CA_STATUS_FAILED);
+
+ VERIFY_NON_NULL_RET(gBLEClientSendQueueHandle, CALEADAPTER_TAG, "gBLEClientSendQueueHandle",
+ CA_STATUS_FAILED);
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%d]", dataLen);
+
+ CABLEData *bleData = CACreateBLEData(remoteEndpoint, data, dataLen);
+ if (!bleData)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ // Add message to send queue
+ u_mutex_lock(gBleClientSendDataMutex);
+ CAQueueingThreadAddData(gBLEClientSendQueueHandle, bleData, sizeof(CABLEData));
+ u_mutex_unlock(gBleClientSendDataMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT ");
+ return CA_STATUS_OK;
+}
+
+
+CAResult_t CABLEServerSendData(const CARemoteEndpoint_t *remoteEndpoint,
+ void *data,
+ uint32_t dataLen)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN ");
+
+ VERIFY_NON_NULL(data, NULL, "Param data is NULL");
+
+ VERIFY_NON_NULL_RET(gSendQueueHandle, CALEADAPTER_TAG,
+ "BleClientReceiverQueue is NULL",
+ CA_STATUS_FAILED);
+ VERIFY_NON_NULL_RET(gBleClientSendDataMutex, CALEADAPTER_TAG,
+ "BleClientSendDataMutex is NULL",
+ CA_STATUS_FAILED);
+
+ VERIFY_NON_NULL_RET(gSendQueueHandle, CALEADAPTER_TAG, "sendQueueHandle",
+ CA_STATUS_FAILED);
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%d]", dataLen);
+
+ CABLEData *bleData = CACreateBLEData(remoteEndpoint, data, dataLen);
+ if (!bleData)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ // Add message to send queue
+ u_mutex_lock(gBleServerSendDataMutex);
+ CAQueueingThreadAddData(gSendQueueHandle, bleData, sizeof(CABLEData));
+ u_mutex_unlock(gBleServerSendDataMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT ");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CABLEServerReceivedData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength)
+{
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN");
+
+ //Input validation
+ VERIFY_NON_NULL(serviceUUID, CALEADAPTER_TAG, "service UUID is null");
+ VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Data is null");
+ VERIFY_NON_NULL(sentLength, CALEADAPTER_TAG, "Sent data length holder is null");
+ VERIFY_NON_NULL_RET(gCABleServerReceiverQueue, CALEADAPTER_TAG, "gCABleServerReceiverQueue",
+ CA_STATUS_FAILED);
+
+ //Add message to data queue
+ CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
+ serviceUUID);
+ if (NULL == remoteEndpoint)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create remote endpoint !");
+ return CA_STATUS_FAILED;
+ }
+
+ // Create bleData to add to queue
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received from LE layer [%d]", dataLength);
+
+ CABLEData *bleData = CACreateBLEData(remoteEndpoint, data, dataLength);
+ if (!bleData)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ // Add message to send queue
+ CAQueueingThreadAddData(gCABleServerReceiverQueue, bleData, sizeof(CABLEData));
+
+ *sentLength = dataLength;
+
+ OICFree(data);
+ data = NULL;
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CABLEClientReceivedData(const char *remoteAddress, const char *serviceUUID,
+ void *data, uint32_t dataLength, uint32_t *sentLength)
+{
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN");
+
+ //Input validation
+ VERIFY_NON_NULL(serviceUUID, CALEADAPTER_TAG, "service UUID is null");
+ VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Data is null");
+ VERIFY_NON_NULL(sentLength, CALEADAPTER_TAG, "Sent data length holder is null");
+ VERIFY_NON_NULL_RET(gCABleClientReceiverQueue, CALEADAPTER_TAG, "gCABleClientReceiverQueue",
+ CA_STATUS_FAILED);
+
+ //Add message to data queue
+ CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
+ serviceUUID);
+ if (NULL == remoteEndpoint)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create remote endpoint !");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received from LE layer [%d]", dataLength);
+
+ // Create bleData to add to queue
+ CABLEData *bleData = CACreateBLEData(remoteEndpoint, data, dataLength);
+ if (!bleData)
+ {
+ OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ // Add message to send queue
+ CAQueueingThreadAddData(gCABleClientReceiverQueue, bleData, sizeof(CABLEData));
+
+ *sentLength = dataLength;
+
+ OICFree(data);
+ data = NULL;
+
+ OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CASetBleAdapterThreadPoolHandle(u_thread_pool_t handle)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+ gBleAdapterThreadPool = handle;
+ u_mutex_unlock(gBleAdapterThreadPoolMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+}
+
+void CASetBLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback)
+{
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+
+ u_mutex_lock(gBleAdapterReqRespCbMutex);
+
+ gNetworkPacketReceivedCallback = callback;
+
+ u_mutex_unlock(gBleAdapterReqRespCbMutex);
+
+ OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+}
+
+
#endif //#ifdef OIC_TIZEN
static u_thread_pool_t gThreadPoolHandle = NULL;
CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
- u_thread_pool_t handle)
+ CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
+ u_thread_pool_t handle)
{
OIC_LOG_V(DEBUG, TAG, "CAInitializeLE");
return CA_STATUS_OK;
}
-uint32_t CASendLEUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen)
+uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
{
OIC_LOG_V(DEBUG, TAG, "CASendLEUnicastData");
return 0;
}
-uint32_t CASendLEMulticastData(void* data, uint32_t dataLen)
+uint32_t CASendLEMulticastData(void *data, uint32_t dataLen)
{
OIC_LOG_V(DEBUG, TAG, "CASendLEMulticastData");
return 0;
}
-CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size)
+CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
{
OIC_LOG_V(DEBUG, TAG, "CAGetLEInterfaceInformation");
#include "umutex.h"
#include "uarraylist.h"
-#include "camessagequeue.h"
+#include "caqueueingthread.h"
#include "caadapterutils.h"
#include "camsgparser.h"
static CABool_t gIsBleGattClientStarted = CA_FALSE;
/**
- * @var gCABleClientSenderQueue
- * @brief Queue to process the outgoing packets from GATTClient.
- */
-static CAAdapterMessageQueue_t *gCABleClientSenderQueue = NULL;
-
-/**
- * @var gCABleClientReceiverQueue
- * @brief Queue to process the incoming packets to GATT Client.
- */
-static CAAdapterMessageQueue_t *gCABleClientReceiverQueue = NULL;
-
-/**
* @var gBleServiceListMutex
* @brief Mutex to synchronize access to BleServiceList.
*/
static u_mutex gBleClientStateMutex = NULL;
/**
- * @var gBleClientSendDataMutex
- * @brief Mutex to synchronize the queing of the data from SenderQueue.
- */
-static u_mutex gBleClientSendDataMutex = NULL;
-
-/**
* @var gBleClientSendCondWait
* @brief Condition used for notifying handler the presence of data in send queue.
*/
static u_cond gBleClientSendCondWait = NULL;
/**
- * @var gBleClientReceiveDataMutex
- * @brief Mutex to synchronize the queing of the data from ReceiverQueue.
- */
-static u_mutex gBleClientReceiveDataMutex = NULL;
-
-/**
- * @var gReceiverDataCond
- * @brief Condition used for notifying handler the presence of data in recv queue.
- */
-static u_cond gReceiverDataCond = NULL;
-
-/**
* @var gDataReceiverHandlerState
* @brief Stop condition of redvhandler.
*/
static bool gDataReceiverHandlerState = false;
/**
- * @var isHeaderAvailable
- * @brief to differentiate btw header and data packet.
- */
-static CABool_t isHeaderAvailable = false;
-
-/**
* @var gBleClientThreadPoolMutex
* @brief Mutex to synchronize the task to be pushed to thread pool.
*/
* @brief Maintains the callback to be notified on receival of network packets from other
* BLE devices
*/
-static CANetworkPacketReceivedCallback gNetworkPacketReceivedClientCallback = NULL;
+static CABLEClientDataReceivedCallback gCABLEClientDataReceivedCallback = NULL;
/**
* @var gClientUp
static u_arraylist_t *gNonOicDeviceList = NULL;
static CABool_t gIsOicDeviceFound = CA_FALSE;
-/**
- * @fn CABLEDataReceiverHandler
- * @brief This function handles data from recv message queue.
- */
-static void CABLEDataReceiverHandler(void *context);
-
-CAResult_t CABLEPushDataToReceiverQueue(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength)
-{
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
- //Input validation
- VERIFY_NON_NULL(serviceUUID, TZ_BLE_CLIENT_TAG, "service UUID is null");
- VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "Data is null");
- VERIFY_NON_NULL(sentLength, TZ_BLE_CLIENT_TAG, "Sent data length holder is null");
-
- //Add message to data queue
- CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
- serviceUUID);
- if (NULL == remoteEndpoint)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "Failed to create remote endpoint !");
- return CA_STATUS_FAILED;
- }
-
- if (CA_STATUS_OK != CAAdapterEnqueueMessage(gCABleClientReceiverQueue, remoteEndpoint, data,
- dataLength))
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "Failed to add message to queue !");
-
- CAAdapterFreeRemoteEndpoint(remoteEndpoint);
- return CA_STATUS_FAILED;
- }
-
- *sentLength = dataLength;
-
- OICFree(data);
- data = NULL;
-
- //Signal message handler for processing data for sending
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Signalling message send handler");
- u_mutex_lock(gBleClientReceiveDataMutex);
- u_cond_signal(gReceiverDataCond);
- u_mutex_unlock(gBleClientReceiveDataMutex);
-
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
- return CA_STATUS_OK;
-}
void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
unsigned char *value,
uint32_t sentLength = 0;
- CAResult_t res = CABLEPushDataToReceiverQueue(gRemoteAddress, OIC_BLE_SERVICE_ID,
- data, strlen(data), &sentLength);
- if (CA_STATUS_OK != res)
+ u_mutex_lock(gBleReqRespClientCbMutex);
+ if (NULL == gCABLEClientDataReceivedCallback)
{
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABLEPushDataToReceiverQueue failed");
- OICFree(data);
- return ;
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
+ u_mutex_unlock(gBleReqRespClientCbMutex);
+ return;
}
+ OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
+ gCABLEClientDataReceivedCallback(gRemoteAddress, OIC_BLE_SERVICE_ID,
+ data, strlen(data), &sentLength);
+
+ u_mutex_unlock(gBleReqRespClientCbMutex);
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
return;
"LE Client initialization flow complete. Enabling gClientUp state to TRUE ");
gClientUp = CA_TRUE;
- ret = u_thread_pool_add_task(gBleClientThreadPool,
- (void *) CABleClientSenderQueueProcessor,
- (void *) NULL);
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
- u_mutex_unlock(gBleClientThreadPoolMutex);
- return ;
- }
-
- gDataReceiverHandlerState = true;
- if (CA_STATUS_OK != u_thread_pool_add_task(gBleClientThreadPool, CABLEDataReceiverHandler, NULL))
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "Failed to start data send handler!");
- return ;
- }
-
u_mutex_unlock(gBleClientThreadPoolMutex);
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
if (CA_STATUS_OK != retVal)
{
OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAGetBLEServiceInfo failed! ");
- bleServiceInfo = NULL;
return;
}
u_mutex_unlock(gBleServiceListMutex);
for (indexValue = 0; indexValue < listLen; indexValue++)
{
char *storedAddr = u_arraylist_get(gNonOicDeviceList, indexValue);
+ if (NULL == storedAddr)
+ {
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+ "storedAddr is NULL");
+ OICFree(addr);
+ return false;
+ }
if (strcmp(storedAddr, addr) == 0)
{
found = CA_TRUE;
{
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
"CABleGattDisConnect failed!");
+ OICFree(addr);
return false;
}
}
int32_t len = strlen(bdAddress);
stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
-
if (NULL == stTemp->address)
{
OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! ");
BLEServiceInfo *bleServiceInfo = NULL;
- CAResult_t result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
+ result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
if (CA_STATUS_OK != result)
{
OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
+ OICFree(stTemp->address);
OICFree(stTemp);
+ OICFree(bleServiceInfo);
+ return false;
+ }
+ if (NULL == bleServiceInfo )
+ {
+ OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , " bleServiceInfo is NULL");
OICFree(stTemp->address);
- bleServiceInfo = NULL;
+ OICFree(stTemp);
+ OICFree(bleServiceInfo);
return false;
}
VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
+ CAResult_t ret = CA_STATUS_FAILED;
if (!connected)
{
OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
- CAResult_t result = CABleGattStartDeviceDiscovery();
+ ret = CABleGattStartDeviceDiscovery();
if (CA_STATUS_OK != result)
{
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
return;
}
- CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CADiscoverBLEServicesThread,
- (void *) addr);
+ ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CADiscoverBLEServicesThread,
+ (void *) addr);
if (CA_STATUS_OK != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
for (index = 0; index < listLen; index++)
{
char *storedAddr = u_arraylist_get(gNonOicDeviceList, index);
+ if (NULL == storedAddr)
+ {
+ OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+ "storedAddr is NULL");
+ return ;
+ }
if (strcmp(storedAddr, discoveryInfo->remote_address) == 0)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Discovered Device is NON OIC Device. Ignore.");
}
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-}
-
-void CABLEDataReceiverHandler(void *context)
-{
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
- CAAdapterMessage_t *message = NULL;
- const char *remoteAddress = NULL;
- const char *serviceUUID = NULL;
- uint32_t recvDataLen = 0;
- uint32_t totalDataLen = 0;
- char *dataSegment = NULL;
- char *defragData = NULL;
- CARemoteEndpoint_t *remoteEndpoint = NULL;
-
- u_mutex_lock(gBleClientReceiveDataMutex);
-
- while (gDataReceiverHandlerState)
- {
-
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, " waiting for the data");
-
- u_cond_wait(gReceiverDataCond, gBleClientReceiveDataMutex);
-
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "wait unlocked");
-
- //Extract the message from queue and send to remote ble device
- while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleClientReceiverQueue, &message))
- {
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "checking for DE Fragmentation");
-
- if (!isHeaderAvailable)
- {
- char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
- memcpy(header, message->data, CA_HEADER_LENGTH);
- totalDataLen = CAParseHeader(header);
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
- defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
- OICFree(header);
-
- remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
- serviceUUID = message->remoteEndpoint->resourceUri;
-
- remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
- serviceUUID);
-
- memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
- message->dataLen - CA_HEADER_LENGTH);
- recvDataLen += message->dataLen - CA_HEADER_LENGTH;
- isHeaderAvailable = true;
- }
- else
- {
- memcpy(defragData + recvDataLen, message->data, message->dataLen);
- recvDataLen += message->dataLen ;
- }
- CAAdapterFreeMessage(message);
- if (totalDataLen == recvDataLen)
- {
- u_mutex_lock(gBleReqRespClientCbMutex);
- if (NULL == gNetworkPacketReceivedClientCallback)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
- u_mutex_unlock(gBleReqRespClientCbMutex);
- return;
- }
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
- gNetworkPacketReceivedClientCallback(remoteEndpoint, defragData, recvDataLen);
- OICFree(remoteEndpoint);
- OICFree(defragData);
- recvDataLen = 0;
- totalDataLen = 0;
- isHeaderAvailable = false;
- u_mutex_unlock(gBleReqRespClientCbMutex);
- }
-
- }
-
- if (false == gDataReceiverHandlerState)
- {
- break;
- }
-
-
- }
- u_mutex_unlock(gBleClientReceiveDataMutex);
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+ return;
}
void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo)
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}
-void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback)
+void CASetBLEReqRespClientCallback(CABLEClientDataReceivedCallback callback)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
u_mutex_lock(gBleReqRespClientCbMutex);
- gNetworkPacketReceivedClientCallback = callback;
+ gCABLEClientDataReceivedCallback = callback;
u_mutex_unlock(gBleReqRespClientCbMutex);
return CA_STATUS_FAILED;
}
gNonOicDeviceList = u_arraylist_create();
- u_mutex_unlock(gBleClientThreadPoolMutex);
+ u_mutex_lock(gBleClientThreadPoolMutex);
if (NULL == gBleClientThreadPool)
{
OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
}
u_mutex_unlock(gBleClientThreadPoolMutex);
+ OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
return CA_STATUS_OK;
}
return NULL;
}
- CAResult_t ret = CAInitBleQueues();
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CAInitBleQueues failed");
- CATerminateBleQueues();
- u_mutex_unlock(gBleClientStateMutex);
- return NULL;
- }
-
- ret = CABleGattSetScanParameter();
+ CAResult_t ret = CABleGattSetScanParameter();
if (CA_STATUS_OK != ret)
{
OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
u_mutex_unlock(gBleClientStateMutex);
+ OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Giveing the control to threadPool");
+
GMainContext *thread_context = NULL;
thread_context = g_main_context_new();
}
u_mutex_unlock(gBleClientStateMutex);
- //Stop data send and receive handlers
- if (gBleClientReceiveDataMutex && gReceiverDataCond && gDataReceiverHandlerState)
+ // Stop data send and receive handlers
+ if ( gDataReceiverHandlerState)
{
- u_mutex_lock(gBleClientReceiveDataMutex);
gDataReceiverHandlerState = CA_FALSE;
- u_cond_signal(gReceiverDataCond);
- u_mutex_unlock(gBleClientReceiveDataMutex);
}
CATerminateBLEGattClient();
gClientUp = CA_FALSE;
gIsOicDeviceFound = CA_FALSE;
- u_cond_signal(gBleClientSendCondWait);
-
u_mutex_lock(gBleClientStateMutex);
// Required for waking up the thread which is running in gmain loop
GMainContext *context_event_loop = g_main_loop_get_context(g_event_loop);
CAResetRegisteredServiceCount();
- CATerminateBleQueues();
-
gIsBleGattClientStarted = CA_FALSE;
u_mutex_unlock(gBleClientStateMutex);
}
}
- if (!gReceiverDataCond)
- {
- gReceiverDataCond = u_cond_new();
- if (NULL == gReceiverDataCond)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_cond_new failed");
- return CA_STATUS_FAILED;
- }
- }
-
if (NULL == gBleServiceListMutex)
{
gBleServiceListMutex = u_mutex_new();
}
}
- if (NULL == gBleClientSendDataMutex)
- {
- gBleClientSendDataMutex = u_mutex_new();
- if (NULL == gBleClientSendDataMutex)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
- return CA_STATUS_FAILED;
- }
- }
-
- if (NULL == gBleClientReceiveDataMutex)
- {
- gBleClientReceiveDataMutex = u_mutex_new();
- if (NULL == gBleClientReceiveDataMutex)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
- return CA_STATUS_FAILED;
- }
- }
-
if (NULL == gBleClientThreadPoolMutex)
{
gBleClientThreadPoolMutex = u_mutex_new();
u_mutex_free(gBleReqRespClientCbMutex);
gBleReqRespClientCbMutex = NULL;
- u_mutex_free(gBleClientSendDataMutex);
- gBleClientSendDataMutex = NULL;
-
- u_mutex_free(gBleClientReceiveDataMutex);
- gBleClientReceiveDataMutex = NULL;
-
u_mutex_free(gBleClientThreadPoolMutex);
gBleClientThreadPoolMutex = NULL;
u_cond_free(gBleClientSendCondWait);
gBleClientSendCondWait = NULL;
- if (gReceiverDataCond)
- {
- u_cond_free(gReceiverDataCond);
- gReceiverDataCond = NULL;
- }
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
}
-CAResult_t CAInitBleQueues()
-{
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
- u_mutex_lock(gBleClientSendDataMutex);
- CAResult_t retVal = CAAdapterInitializeMessageQueue(&gCABleClientSenderQueue);
- if (CA_STATUS_OK != retVal )
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!");
- u_mutex_unlock(gBleClientSendDataMutex);
- return CA_STATUS_FAILED;
- }
- u_mutex_unlock(gBleClientSendDataMutex);
-
- u_mutex_lock(gBleClientReceiveDataMutex);
- retVal = CAAdapterInitializeMessageQueue(&gCABleClientReceiverQueue);
- if (CA_STATUS_OK != retVal)
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!");
- u_mutex_unlock(gBleClientReceiveDataMutex);
- return CA_STATUS_FAILED;
- }
- u_mutex_unlock(gBleClientReceiveDataMutex);
-
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CATerminateBleQueues()
-{
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
- u_mutex_lock(gBleClientSendDataMutex);
- if (NULL != gCABleClientSenderQueue)
- {
- CAAdapterTerminateMessageQueue(gCABleClientSenderQueue);
- gCABleClientSenderQueue = NULL;
- }
- u_mutex_unlock(gBleClientSendDataMutex);
-
- u_mutex_lock(gBleClientReceiveDataMutex);
- if (NULL != gCABleClientReceiverQueue)
- {
- CAAdapterTerminateMessageQueue(gCABleClientReceiverQueue);
- gCABleClientReceiverQueue = NULL;
- }
- u_mutex_unlock(gBleClientReceiveDataMutex);
-
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-}
-
void CAClearNonOICDeviceList()
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
{
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
OICFree(address);
- address = NULL;
return NULL;
}
{
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
OICFree(address);
- address = NULL;
return NULL;
}
strncpy(addr, remoteAddress, len);
int32_t ret = bt_gatt_foreach_primary_services(remoteAddress, CABleGattPrimaryServiceCb,
- (void *)addr); //addr memory will be free in callback.
+ (void *)addr); // addr memory will be free in callback.
if (BT_ERROR_NONE != ret)
{
OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_foreach_primary_services Failed with ret value [%d] ",
return CA_STATUS_OK;
}
-CAResult_t CABleClientSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint,
- void *data,
- uint32_t dataLen)
-{
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
-
- VERIFY_NON_NULL(data, NULL, "Param data is NULL");
-
- VERIFY_NON_NULL_RET(gCABleClientSenderQueue, TZ_BLE_CLIENT_TAG,
- "BleClientReceiverQueue is NULL",
- CA_STATUS_FAILED);
- VERIFY_NON_NULL_RET(gBleClientSendDataMutex, TZ_BLE_CLIENT_TAG,
- "BleClientSendDataMutex is NULL",
- CA_STATUS_FAILED);
- VERIFY_NON_NULL_RET(gBleClientSendCondWait, TZ_BLE_CLIENT_TAG,
- "BleClientSendCondWait is NULL",
- CA_STATUS_FAILED);
-
- u_mutex_lock(gBleClientSendDataMutex);
- CAResult_t retVal = CAAdapterEnqueueMessage(gCABleClientSenderQueue,
- remoteEndpoint, data, dataLen);
- if (CA_STATUS_OK != retVal )
- {
- OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterEnqueueMessage failed!");
- u_mutex_unlock(gBleClientSendDataMutex);
- return CA_STATUS_FAILED;
- }
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending signal for the sender processor ");
- u_mutex_unlock(gBleClientSendDataMutex);
- u_cond_signal(gBleClientSendCondWait);
-
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
- return CA_STATUS_OK;
-}
-
-void *CABleClientSenderQueueProcessor()
-{
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
-
- while (gClientUp)
- {
- CAAdapterMessage_t *message = NULL;
- const char *remoteAddress = NULL;
- const char *serviceUUID = NULL;
- uint32_t sentLength = 0;
- int32_t headerAdded = 0;
-
-
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " Waiting for the data ... ");
-
- u_mutex_lock(gBleClientSendDataMutex);
- u_cond_wait(gBleClientSendCondWait, gBleClientSendDataMutex);
-
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Data got pushed to the queue...");
-
- CAResult_t result = CA_STATUS_FAILED;
-
- while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleClientSenderQueue,
- &message))
- {
- if (NULL == message)
- {
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "senderData is NULL");
- continue;
- }
- char *dataSegment = NULL;
- uint32_t offset = 0, ret = 1;
- int datalen = message->dataLen;
- while ( 1)
- {
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "fragmenting the data DataLen [%d] Offset [%d]", datalen,
- offset);
- ret = CAFragmentData(message->data, &dataSegment, datalen, offset);
- sleep(1);
- if (0 == ret)
- {
- break;
- }
- if (NULL != message->remoteEndpoint)
- {
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending Unicast data");
- const char *bdAddress = message->remoteEndpoint->addressInfo.LE.leMacAddress;
-
- VERIFY_NON_NULL_RET(bdAddress, TZ_BLE_CLIENT_TAG, "bdAddress is NULL", NULL);
-
- result = CAUpdateCharacteristicsToGattServer(bdAddress, dataSegment,
- ret,
- UNICAST, 0);
- if (CA_STATUS_OK != result)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
- "Failed to UpdateCharacteristicsToGattServer [%s]", bdAddress);
- }
- }
- else
- {
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending Multicast data");
- result = CAUpdateCharacteristicsToAllGattServers(dataSegment, ret);
- if (CA_STATUS_OK != result)
- {
- OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
- "Failed to UpdateCharacteristicsToAllGattServers !");
- }
- }
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "freeing dataSegment");
-
- OICFree(dataSegment);
- dataSegment = NULL;
- offset += ret;
- if (headerAdded == 0)
- {
- datalen -= offset - CA_HEADER_LENGTH;
- offset = offset - CA_HEADER_LENGTH;
- headerAdded = 1;
- }
- else
- {
- datalen -= ret;
- }
-
- if (datalen < 0)
- {
- datalen += ret ;
- }
- if (datalen == message->dataLen)
- {
- OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "All data has been fragmented and sent");
- break;
- }
- }
-
- CAAdapterFreeMessage(message);
- }
- u_mutex_unlock(gBleClientSendDataMutex);
- }
-
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
- return NULL;
-}
-
CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
- int32_t dataLen, TRANSFER_TYPE type, int32_t position)
+ const int32_t dataLen, TRANSFER_TYPE type, const int32_t position)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
return CA_STATUS_OK;
}
-CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, int32_t dataLen)
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, const int32_t dataLen)
{
OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
return CA_STATUS_OK;
}
-CAResult_t CALEReadDataFromLEClient()
-{
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
-
- ///TODO: If CA layer request for the data, this function ll be implemented.
-
- OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
- return CA_STATUS_OK;
-}
-
#include "caadapterinterface.h"
#include "logger.h"
#include "uthreadpool.h"
-
+#include "caleinterface.h"
/**
/**
* @fn CABleGattCharacteristicsDiscoveredCb
-* @brief This is the callback which will be called after the characteristics are discovered by bt_gatt_discover_characteristics()
+* @brief This is the callback which will be called after the characteristics are discovered by
+* bt_gatt_discover_characteristics()
*
* @param[in] result The result of discovering
* @param[in] inputIndex The index of characteristics in a service, starts from 0
/**
* @fn CABleGattConnectionStateChangedCb
-* @brief This is the callback which will be called whenever there is change in gatt connection with server(Connected/Disconnected)
+* @brief This is the callback which will be called whenever there is change in gatt connection
+* with server(Connected/Disconnected)
*
* @param[in] result The result of discovering
* @param[in] connected State of connection
void CASetBleClientThreadPoolHandle(u_thread_pool_t handle);
/**
- * @fn CASetBLEReqRespClientCallback
- * @brief used to store upper layer callback locally which will be used to send the data to application
- *
- * @param[in] CANetworkPacketReceivedCallback - upper layer callback function to pass the data to CA layer.
- *
- * @return void
- *
- */
-void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback);
-
-/**
-* @fn CAStartBLEGattClient
-* @brief Used to start CAStartBleGattClientThread for initializing Gatt Client
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAStartBLEGattClient();
-
-/**
* @fn CAStartBleGattClientThread
* @brief This is thread which will be used to initialize the Gatt Client and start device discovery.
-* 1. Set scan parameters 2.Setting neccessary callbacks for connection, characteristics changed and discovery and bond creation.
+* 1. Set scan parameters 2.Setting neccessary callbacks for connection, characteristics changed and
+* discovery and bond creation.
* 3. Start device discovery
*
* @param[in] data - Currently it will be NULL(no parameter)
void *CAStartBleGattClientThread(void *data);
/**
-* @fn CAStopBLEGattClient
-* @brief Used to stop Gatt Client gracefully in turn it will call CATerminateBLEGattClient function.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-void CAStopBLEGattClient();
-
-/**
-* @fn CATerminateBLEGattClient
-* @brief Used to unset all the callbacks and stop service discovery
-*
-* @return void
-*
-*/
-void CATerminateBLEGattClient();
-
-/**
* @fn CAInitGattClientMutexVaraibles
* @brief Used to initialize all required mutex variable for Gatt Client implementation.
*
void CATerminateGattClientMutexVariables();
/**
-* @fn CAInitBleQueues
-* @brief Used to initiate sender and receiver queues which will be used for data processing.
-*
-* @return void
-*
-*/
-CAResult_t CAInitBleQueues();
-
-/**
-* @fn CATerminateBleQueues
-* @brief Used to terminate sender and receiver queues which will be used for data processing.
-*
-* @return void
-*
-*/
-void CATerminateBleQueues();
-
-/**
* @fn CAClearNonOICDeviceList
* @brief Used to clear NonOICDeviceList
*
/**
* @fn CADiscoverBLEServicesThread
-* @brief This is thread which will be spawned for discovering ble services. Once called discover api, then it will be terminated.
+* @brief This is thread which will be spawned for discovering ble services. Once called discover api,
+* then it will be terminated.
*
* @param[in] remoteAddress Mac address of the remote device in which we want to search services.
*
* @fn CADiscoverCharThread
* @brief This is the thread which will be used for finding characteristic of a service.
*
-* @param[in] stServiceInfo Service Information which contains the remote address and service handle, characteristic handle.
+* @param[in] stServiceInfo Service Information which contains the remote address and service handle,
+* characteristic handle.
*
* @return NULL on success or failure.
*
* @fn CADiscoverDescriptorThread
* @brief This is the thread which will be used for finding descriptor of characteristic.
*
-* @param[in] stServiceInfo Service Information which contains the remote address and service handle, characteristic handle.
+* @param[in] stServiceInfo Service Information which contains the remote address and service handle,
+* characteristic handle.
*
* @return NULL on success or failure.
*
* @fn CASetCharacteristicDescriptorValueThread
* @brief This is thread which will be used for calling CASetCharacteristicDescriptorValue api.
*
-* @param[in] stServiceInfo - Service Information which contains the remote address and service handle, characteristic handle.
+* @param[in] stServiceInfo - Service Information which contains the remote address and service handle,
+* characteristic handle.
*
* @return NULL on sucess or failure.
*
* @fn CAGATTCreateBondThread
* @brief This is the thread which will be used for creating bond with remote device.
*
-* @param[in] stServiceInfo Service Information which contains the remote address and service handle, characteristic handle.
+* @param[in] stServiceInfo Service Information which contains the remote address and service handle,
+* characteristic handle.
*
* @return NULL on success or failure.
*
/**
* @fn CABleClientSenderQueueEnqueueMessage
-* @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make signal to the thread to process.
+* @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make signal
+* to the thread to process.
*
* @param[in] remoteEndpoint Remote device information
* @param[in] data data which we wants to send to remote device
void *CABleClientSenderQueueProcessor();
/**
-* @fn CAUpdateCharacteristicsToGattServer
-* @brief Sets the value of characteristic and update the value to GATTServer(unicast).
-*
-* @param[in] remoteAddress The address of the remote device
-* @param[in] data The value of characteristic (byte array)
-* @param[in] dataLen The length of value
-* @param[in] TRANSFER_TYPE (UNICAST/MULTICAST)
-* @param[in] position The unique index of each ble server. Used for multicast feature.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*/
-CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data,
- int32_t dataLen, TRANSFER_TYPE type, int32_t position);
-
-/**
- * @fn CAUpdateCharacteristicsToAllGattServers
- * @brief Sets the value of characteristic and update the value to All registered GATTServer -> Multicast
- *
- * @param[in] data The value of characteristic (byte array)
- * @param[in] dataLen The length of value
- *
- * @return 0 on success otherwise a positive error value.
- * @retval CA_STATUS_OK Successful
- * @retval CA_STATUS_INVALID_PARAM Invalid input argumets
- * @retval CA_STATUS_FAILED Operation failed
- */
-CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, int32_t dataLen);
-
-/**
* @fn CALEReadDataFromLEClient
* @brief synchronous function for reading characteristic value.
*
NOTIFY_CHAR_INDEX = 3 /**< reserved char index for the time being. */
} CHAR_INDEX;
+
/**
- * @ENUM TRANSFER_TYPE
- * @brief Provide info about different mode of data transfer
+ * @Structure stGattCharDescriptor_t
+ * @brief Stores the information required to set the descriptor value of the Service.
*
- * This enum is used to differentiate between unicast and multicast data transfer.
*/
-typedef enum
-{
- MULTICAST, /**< When this enum is selected, data will be updated to all OIC servers. */
- UNICAST /**< When this enum is selected, data will be updated to desired OIC Server. */
-} TRANSFER_TYPE;
-
typedef struct gattCharDescriptor
{
bt_gatt_attribute_h characteristic;
int total;
} stGattCharDescriptor_t;
-#define OIC_BLE_SERVICE_ID "713d0000-503e-4c75-ba94-3148f18d941e"
+#define OIC_BLE_SERVICE_ID "713D0000-503E-4C75-BA94-3148F18D941E"
///TODO: OIC_BLE_SERVICE_ID will be generated by invoking API in future.
/**
* @fn CAIncrementRegisteredServiceCount
*
*/
const char *CABTGetErrorMsg(bt_error_e err);
+
#endif //#ifndef _BLE_CLIENT_UTIL
*
******************************************************************/
+#include <bluetooth.h>
+#include <bluetooth_type.h>
+#include <bluetooth_product.h>
+
#include "cableserver.h"
#include <pthread.h>
#include "cacommon.h"
#include "caadapterutils.h"
#include <gio/gio.h>
#include "umutex.h"
-#include "camessagequeue.h"
+#include "caqueueingthread.h"
#include "caadapterutils.h"
#include "camsgparser.h"
#include "cableclientutil.h"
*/
#define TZ_BLE_SERVER_TAG "TZ_BLE_GATT_SERVER"
-///TODO:: Currently keeping as single service. Later service path will be added in list for supporting multiple services.
+///TODO:: Currently keeping as single service. Later service path will be added in list for \
+///TODO:: supporting multiple services.
+
+#define CA_BLE_SERVICE_UUID "713d0000-503e-4c75-ba94-3148f18d941e"
+
+#define CA_BLE_READ_CHAR_UUID "00002af5-0000-1000-8000-00805f9b34fb"
+
+#define CA_BLE_WRITE_CHAR_UUID "00002af6-0000-1000-8000-00805f9b34fb"
/**
* @var gGattSvcPath
static bt_advertiser_h hAdvertiser = NULL;
/**
- * @var gNetworkPacketReceivedServerCallback
+ * @var gCABLEServerDataReceivedCallback
* @brief Maintains the callback to be notified on receival of network packets from other
* BLE devices
*/
-static CANetworkPacketReceivedCallback gNetworkPacketReceivedServerCallback = NULL;
-
-/**
- * @var gCABleServerSenderQueue
- * @brief Queue to process the outgoing packets from GATTServer.
- */
-static CAAdapterMessageQueue_t *gCABleServerSenderQueue = NULL;
-
-/**
- * @var gCABleServerReceiverQueue
- * @brief Queue to process the incoming packets to GATTServer
- */
-static CAAdapterMessageQueue_t *gCABleServerReceiverQueue = NULL;
+static CABLEServerDataReceivedCallback gCABLEServerDataReceivedCallback = NULL;
/**
* @var gIsBleGattServerStarted
static u_mutex gBleReqRespCbMutex = NULL;
/**
- * @var gBleServerSendDataMutex
- * @brief Mutex to synchronize the queing of the data from SenderQueue.
- */
-static u_mutex gBleServerSendDataMutex = NULL;
-
-/**
* @var gBleServerThreadPoolMutex
* @brief Mutex to synchronize the task to be pushed to thread pool.
*/
static bool gDataReceiverHandlerState = false;
/**
- * @var isHeaderAvailable
- * @brief to differentiate btw header and data packet.
- */
-static CABool_t isHeaderAvailable = false;
-
-/**
* @struct gRemoteAddress
* @brief Remote address of Gatt client
*
*/
static const char *gRemoteClientAddress = "DB:F7:EB:B5:0F:07";
///TODO: later this will be replaced with the platform apis.
-/**
- * @var gBleServerReceiveDataMutex
- * @brief Mutex to synchronize the queing of the data from ReceiverQueue.
- */
-static u_mutex gBleServerReceiveDataMutex = NULL;
/**
* @var g_event_loop
*/
static CABool_t gServerUp = CA_FALSE;
-/**
- * @fn CABLEDataReceiverHandler
- * @brief This function handles data from recv message queue.
- */
-static void CABLEDataReceiverHandler(void *context);
-
-CAResult_t CABLEPushDataToServerReceiverQueue(const char *remoteAddress, const char *serviceUUID,
- void *data, uint32_t dataLength, uint32_t *sentLength)
-{
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "IN");
-
- //Input validation
- VERIFY_NON_NULL(serviceUUID, TZ_BLE_SERVER_TAG, "service UUID is null");
- VERIFY_NON_NULL(data, TZ_BLE_SERVER_TAG, "Data is null");
- VERIFY_NON_NULL(sentLength, TZ_BLE_SERVER_TAG, "Sent data length holder is null");
-
- //Add message to data queue
- CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
- serviceUUID);
- if (NULL == remoteEndpoint)
- {
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "Failed to create remote endpoint !");
- return CA_STATUS_FAILED;
- }
-
- if (CA_STATUS_OK != CAAdapterEnqueueMessage(gCABleServerReceiverQueue, remoteEndpoint, data,
- dataLength))
- {
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "Failed to add message to queue !");
-
- CAAdapterFreeRemoteEndpoint(remoteEndpoint);
- return CA_STATUS_FAILED;
- }
-
- *sentLength = dataLength;
-
- OICFree(data);
- data = NULL;
-
- //Signal message handler for processing data for sending
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Signalling message send handler");
- u_mutex_lock(gBleServerReceiveDataMutex);
- u_cond_signal(gReceiverDataCond);
- u_mutex_unlock(gBleServerReceiveDataMutex);
-
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-void *CABleServerSenderQueueProcessor()
-{
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN ");
-
- while (gServerUp)
- {
- CAAdapterMessage_t *message = NULL;
- const char *remoteAddress = NULL;
- const char *serviceUUID = NULL;
- uint32_t sentLength = 0;
- int32_t headerAdded = 0;
-
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, " conditional wait");
-
- u_mutex_lock(gBleServerSendDataMutex);
- u_cond_wait(gBleServerSendCondWait, gBleServerSendDataMutex);
-
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "wait unlocked");
-
- CAResult_t result = CA_STATUS_FAILED;
-
- while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleServerSenderQueue, &message))
- {
- if (message == NULL)
- {
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "senderData is NULL");
- continue;
- }
- char *dataSegment = NULL;
- uint32_t offset = 0, ret = 1;
- int32_t datalen = message->dataLen;
- while ( 1)
- {
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "fragmenting the data DataLen [%d] Offset [%d]", datalen,
- offset);
- ret = CAFragmentData(message->data, &dataSegment, datalen, offset);
- sleep(1);
- if (0 == ret)
- {
- break;
- }
-
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "Sending Multicast data");
- result = CAUpdateCharacteristicsInGattServer(dataSegment, ret);
- if (CA_STATUS_OK != result)
- {
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
- "Failed to CAUpdateCharacteristicsInGattServer !");
- }
-
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "freeing dataSegment");
-
- OICFree(dataSegment);
- dataSegment = NULL;
- offset += ret;
- if (headerAdded == 0)
- {
- datalen -= offset - CA_HEADER_LENGTH;
- offset = offset - CA_HEADER_LENGTH;
- headerAdded = 1;
- }
- else
- {
- datalen -= ret;
- }
-
- if (datalen < 0)
- {
- datalen += ret ;
- }
- if (datalen == message->dataLen)
- {
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "All data has been fragmented and sent");
- break;
- }
- }
- CAAdapterFreeMessage(message);
- }
-
- u_mutex_unlock(gBleServerSendDataMutex);
- }
-
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT ");
- return NULL;
-}
-
-void CABLEDataReceiverHandler(void *context)
-{
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "IN");
-
- CAAdapterMessage_t *message = NULL;
- const char *remoteAddress = NULL;
- const char *serviceUUID = NULL;
- uint32_t recvDataLen = 0;
- uint32_t totalDataLen = 0;
- char *dataSegment = NULL;
- char *defragData = NULL;
- isHeaderAvailable = false;
- CARemoteEndpoint_t *remoteEndpoint = NULL;
-
- u_mutex_lock(gBleServerReceiveDataMutex);
-
- while (gDataReceiverHandlerState)
- {
-
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, " waiting for the data");
-
- u_cond_wait(gReceiverDataCond, gBleServerReceiveDataMutex);
-
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "wait unlocked");
-
- //Extract the message from queue and send to remote ble device
- while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleServerReceiverQueue, &message))
- {
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "checking for DE Fragmentation");
-
- if (!isHeaderAvailable)
- {
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Parsing the header");
- char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
- memcpy(header, message->data, CA_HEADER_LENGTH);
- totalDataLen = CAParseHeader(header);
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
- defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
- OICFree(header);
-
- remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
- serviceUUID = message->remoteEndpoint->resourceUri;
-
- remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
- serviceUUID);
-
- memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
- message->dataLen - CA_HEADER_LENGTH);
- recvDataLen += message->dataLen - CA_HEADER_LENGTH;
- isHeaderAvailable = true;
- }
- else
- {
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Copying the data of length [%d]", message->dataLen);
- memcpy(defragData + recvDataLen, message->data, message->dataLen);
- recvDataLen += message->dataLen ;
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "totalDatalength [%d] recveived Datalen [%d]",
- totalDataLen, recvDataLen);
- }
- CAAdapterFreeMessage(message);
- if (totalDataLen == recvDataLen)
- {
- u_mutex_lock(gBleReqRespCbMutex);
- if (NULL == gNetworkPacketReceivedServerCallback)
- {
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!");
- u_mutex_unlock(gBleReqRespCbMutex);
- return;
- }
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Sending data up !");
- gNetworkPacketReceivedServerCallback(remoteEndpoint, defragData, recvDataLen);
- OICFree(remoteEndpoint);
- OICFree(defragData);
- recvDataLen = 0;
- totalDataLen = 0;
- isHeaderAvailable = false;
- u_mutex_unlock(gBleReqRespCbMutex);
- }
-
- }
-
- if (false == gDataReceiverHandlerState)
- {
- break;
- }
-
-
- }
- u_mutex_unlock(gBleServerReceiveDataMutex);
- OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-}
-
CAResult_t CAStartBleGattServer()
{
///TODO:: Check BT adapter is enabled or not ..if its not enabled, enable bt adapter.
return CA_STATUS_FAILED;
}
- ret = CAAdapterInitializeMessageQueue(&gCABleServerSenderQueue);
- if (CA_STATUS_OK != ret )
- {
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAdapterInitializeMessageQueue failed!");
- CATerminateBleGattServer();
- u_mutex_unlock(gBleServerThreadPoolMutex);
- return CA_STATUS_FAILED;
- }
-
- ret = CAAdapterInitializeMessageQueue(&gCABleServerReceiverQueue);
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAdapterInitializeMessageQueue failed!");
- CATerminateBleGattServer();
- u_mutex_unlock(gBleServerThreadPoolMutex);
- return CA_STATUS_FAILED;
- }
- gServerUp = CA_TRUE;
- ret = u_thread_pool_add_task(gBleServerThreadPool, (void *) CABleServerSenderQueueProcessor,
- (void *) NULL);
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
-
- u_mutex_unlock(gBleServerThreadPoolMutex);
- return CA_STATUS_FAILED;
- }
gDataReceiverHandlerState = true;
- if (CA_STATUS_OK != u_thread_pool_add_task(gBleServerThreadPool, CABLEDataReceiverHandler, NULL))
- {
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "Failed to start data send handler!");
- return ;
- }
+
u_mutex_unlock(gBleServerThreadPoolMutex);
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
return CA_STATUS_OK;
sleep(5); // Sleep is must. otherwise its crashing
- char *serviceUUID = "713d0000-503e-4c75-ba94-3148f18d941e";
+ char *serviceUUID = CA_BLE_SERVICE_UUID;
ret = CAAddNewBleServiceInGattServer(serviceUUID);
return NULL;
}
- char *charReadUUID = "00002af5-0000-1000-8000-00805f9b34fb";
+ char *charReadUUID = CA_BLE_READ_CHAR_UUID;
char charReadValue[4] = {33, 44, 55, 66};
return NULL;
}
- char *charWriteUUID = "00002af6-0000-1000-8000-00805f9b34fb";
+ char *charWriteUUID = CA_BLE_WRITE_CHAR_UUID;
char charWriteValue[4] = {33, 44, 55, 66};
}
u_mutex_unlock(gBleServerStateMutex);
- //Stop data send and receive handlers
- if (gBleServerReceiveDataMutex && gReceiverDataCond && gDataReceiverHandlerState)
+ // Stop data send and receive handlers
+ if (gDataReceiverHandlerState)
{
- u_mutex_lock(gBleServerReceiveDataMutex);
- gDataReceiverHandlerState = CA_FALSE;
u_cond_signal(gReceiverDataCond);
- u_mutex_unlock(gBleServerReceiveDataMutex);
}
CATerminateBleGattServer();
u_mutex_unlock(gBleServerStateMutex);
- // Terminating gCABleServerSenderQueue
- u_mutex_lock(gBleServerSendDataMutex);
- if (NULL != gCABleServerSenderQueue)
- {
- CAAdapterTerminateMessageQueue(gCABleServerSenderQueue);
- gCABleServerSenderQueue = NULL;
- }
- u_mutex_unlock(gBleServerSendDataMutex);
-
- // Terminating gCABleServerReceiverQueue
- u_mutex_lock(gBleServerReceiveDataMutex);
- if (NULL != gCABleServerReceiverQueue)
- {
- CAAdapterTerminateMessageQueue(gCABleServerReceiverQueue);
- gCABleServerReceiverQueue = NULL;
- }
- u_mutex_unlock(gBleServerReceiveDataMutex);
-
// Terminating all mutex variables.
CATerminateGattServerMutexVaraibles();
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
return CA_STATUS_FAILED;
}
}
-
- if (NULL == gBleServerSendDataMutex)
- {
- gBleServerSendDataMutex = u_mutex_new();
- if (NULL == gBleServerSendDataMutex)
- {
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed");
- return CA_STATUS_FAILED;
- }
- }
-
- if (NULL == gBleServerReceiveDataMutex)
- {
- gBleServerReceiveDataMutex = u_mutex_new();
- if (NULL == gBleServerReceiveDataMutex)
- {
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed");
- return CA_STATUS_FAILED;
- }
- }
-
- if (NULL == gBleServerSendCondWait)
- {
- gBleServerSendCondWait = u_cond_new();
- if (NULL == gBleServerSendCondWait)
- {
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed");
- return CA_STATUS_FAILED;
- }
- }
-
- if (!gReceiverDataCond)
- {
- gReceiverDataCond = u_cond_new();
- if (NULL == gReceiverDataCond)
- {
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_cond_new failed");
- return CA_STATUS_FAILED;
- }
- }
-
return CA_STATUS_OK;
}
void CATerminateGattServerMutexVaraibles()
u_mutex_free(gBleServerStateMutex);
gBleServerStateMutex = NULL;
- u_mutex_free(gBleServerReceiveDataMutex);
- gBleServerReceiveDataMutex = NULL;
- u_mutex_free(gBleServerSendDataMutex);
- gBleServerSendDataMutex = NULL;
-
gBleServerStateMutex = NULL;
u_mutex_free(gBleServiceMutex);
gBleServiceMutex = NULL;
u_mutex_free(gBleReqRespCbMutex);
gBleReqRespCbMutex = NULL;
- u_cond_free(gBleServerSendCondWait);
- gBleServerSendCondWait = NULL;
-
- if (gReceiverDataCond)
- {
- u_cond_free(gReceiverDataCond);
- gReceiverDataCond = NULL;
- }
-
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
}
CAResult_t CAInitBleGattService()
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
}
-
-CAResult_t CALEReadDataFromLEServer()
-{
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT ");
-
- return CA_STATUS_OK;
-}
-
CAResult_t CAAddNewBleServiceInGattServer(const char *serviceUUID)
{
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
if (NULL == data)
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc failed!");
- // OICFree(remoteEndPoint);
return;
}
uint32_t sentLength = 0;
- CAResult_t res = CABLEPushDataToServerReceiverQueue(gRemoteClientAddress, OIC_BLE_SERVICE_ID,
- data, strlen(data), &sentLength);
- if (CA_STATUS_OK != res)
- {
- OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "CABLEPushDataToReceiverQueue failed");
- OICFree(data);
- return ;
- }
-
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
-}
-
-CAResult_t CABleServerSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint,
- void *data, uint32_t dataLen)
-{
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN ");
-
- VERIFY_NON_NULL(data, NULL, "Param data is NULL");
-
- VERIFY_NON_NULL_RET(gCABleServerSenderQueue, TZ_BLE_SERVER_TAG, "BleServerReceiverQueue is NULL",
- CA_STATUS_FAILED);
- VERIFY_NON_NULL_RET(gBleServerSendDataMutex, TZ_BLE_SERVER_TAG, "BleServerSendDataMutex is NULL",
- CA_STATUS_FAILED);
- VERIFY_NON_NULL_RET(gBleServerSendCondWait, TZ_BLE_SERVER_TAG, "BleServerSendCondWait is NULL",
- CA_STATUS_FAILED);
-
- u_mutex_lock(gBleServerSendDataMutex);
- CAResult_t retVal = CAAdapterEnqueueMessage(gCABleServerSenderQueue, remoteEndpoint, data, dataLen);
- if (CA_STATUS_OK != retVal )
+ u_mutex_lock(gBleReqRespCbMutex);
+ if (NULL == gCABLEServerDataReceivedCallback)
{
- OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAdapterEnqueueMessage failed!");
- u_mutex_unlock(gBleServerSendDataMutex);
- return CA_STATUS_FAILED;
+ OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!");
+ u_mutex_unlock(gBleReqRespCbMutex);
+ return;
}
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "Sending signal for the sender processor ");
- u_mutex_unlock(gBleServerSendDataMutex);
- u_cond_signal(gBleServerSendCondWait);
- OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT ");
+ OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Sending data up !");
+ gCABLEServerDataReceivedCallback(gRemoteClientAddress, OIC_BLE_SERVICE_ID,
+ data, strlen(data), &sentLength);
+ u_mutex_unlock(gBleReqRespCbMutex);
- return CA_STATUS_OK;
+ OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
}
CAResult_t CARegisterBleServicewithGattServer(const char *svcPath)
return CA_STATUS_OK;
}
-CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUUID, char *charValue,
- int32_t charValueLen, int32_t read)
+CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUUID,
+ char *charValue, int32_t charValueLen, int32_t read)
{
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
return CA_STATUS_OK;
}
-CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, int32_t charValueLen)
+CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue,
+ const uint32_t charValueLen)
{
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
}
char *data = (char *) OICMalloc(sizeof(char) * (charValueLen + 1));
-
if (NULL == data)
{
OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "malloc failed!");
return CA_STATUS_FAILED;
}
OICFree(data);
- data = NULL;
u_mutex_unlock(gBleCharacteristicMutex);
return CA_STATUS_OK;
}
-void CASetBLEReqRespServerCallback(CANetworkPacketReceivedCallback callback)
+void CASetBLEReqRespServerCallback(CABLEServerDataReceivedCallback callback)
{
OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
u_mutex_lock(gBleReqRespCbMutex);
- gNetworkPacketReceivedServerCallback = callback;
+ gCABLEServerDataReceivedCallback = callback;
u_mutex_unlock(gBleReqRespCbMutex);
#ifndef __TZ_BLE_SERVER_H_
#define __TZ_BLE_SERVER_H_
-#include <bluetooth.h>
-#include <bluetooth_type.h>
-#include <bluetooth_product.h>
-
#include "caadapterinterface.h"
#include "logger.h"
#include "uthreadpool.h"
-
-/**
-* @fn CAStartBleGattServer
-* @brief Used to start Gatt Server thread for service creation and advertise ble service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAStartBleGattServer();
+#include "caleinterface.h"
/**
* @fn CAStartBleGattServerThread
void *CAStartBleGattServerThread(void *data);
/**
-* @fn CAStopBleGattServer
-* @brief Used to terminate BLE Gatt Service.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAStopBleGattServer();
-
-/**
* @fn CATerminateBleGattServer
* @brief Used to stop Gatt Server thread and remove service registration, stop advertising.
*
* @retval CA_STATUS_FAILED Operation failed
*
*/
-CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUUID, char *charValue,
- int32_t charValueLen, int32_t read);
+CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUUID,
+ char *charValue, int32_t charValueLen,
+ int32_t read);
/**
* @fn CARemoveCharacteristicsFromGattServer
CAResult_t CARemoveCharacteristicsFromGattServer(const char *charPath);
/**
-* @fn CAUpdateCharacteristicsInGattServer
-* @brief Used to update characteristics(Read/Write) value that we want to send to particular client.
-* Both unicast and multicast will use the same api. In mulicast, we will be sending in loop to all clients.
-*
-* @param[in] charValue - data that we want to send to client(unicast)/clients(multicast)
-* @param[in] charValueLen - length of the data.
-*
-* @return 0 on success otherwise a positive error value.
-* @retval CA_STATUS_OK Successful
-* @retval CA_STATUS_INVALID_PARAM Invalid input argumets
-* @retval CA_STATUS_FAILED Operation failed
-*
-*/
-CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, int32_t charValueLen);
-
-/**
* @fn CABleGattRemoteCharacteristicWriteCb
* @brief This is the callback which will be called when client update one of the characteristics with data.
*
unsigned char *charValue, int32_t charValueLen, void *userData);
/**
-* @fn CASetBLEReqRespServerCallback
-* @brief used to store upper layer callback locally which will be used to send the data to application
-*
-* @param[in] CANetworkPacketReceivedCallback - upper layer callback function to pass the data to CA layer.
-*
-* @return void
-*
-*/
-void CASetBLEReqRespServerCallback(CANetworkPacketReceivedCallback callback);
-
-/**
* @fn CALEReadDataFromLEServer
* @brief synchronous function for reading characteristic value.
*
/**
* @fn CABleServerSenderQueueEnqueueMessage
-* @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make signal to the thread to process.
+* @brief Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make
+* signal to the thread to process.
*
* @param[in] remoteEndpoint Remote device information
* @param[in] data data which we wants to send to remote device
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+#include "caadapternetdtls.h"
+#include "cacommon.h"
+#include "cawifiinterface.h"
+#include "dtls.h"
+
+/**
+ * @def NET_DTLS_TAG
+ * @brief Logging tag for module name
+ */
+#define NET_DTLS_TAG "NET_DTLS"
+
+/**
+ * @var gCaDtlsContext
+ * @brief global context which holds dtls context and cache list information.
+ */
+static stCADtlsContext_t *gCaDtlsContext = NULL;
+
+/**
+ * @var gDtlsContextMutex
+ * @brief Mutex to synchronize access to gCaDtlsContext.
+ */
+static u_mutex gDtlsContextMutex = NULL;
+
+/**
+ * @var gDtlsListMutex
+ * @brief Mutex to synchronize access to DTLS Cache.
+ */
+static u_mutex gDtlsListMutex = NULL;
+
+static eDtlsRet_t CAAdapterNetDtlsEncryptInternal(const stCADtlsAddrInfo_t *dstSession,
+ uint8_t *data, uint32_t dataLen)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ VERIFY_NON_NULL_RET(dstSession, NET_DTLS_TAG, "Param dstSession is NULL", DTLS_FAIL);
+ VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL", DTLS_FAIL);
+
+ if (0 == dataLen)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
+ return DTLS_FAIL;
+ }
+
+ u_mutex_lock(gDtlsContextMutex);
+ if (NULL == gCaDtlsContext)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+ u_mutex_unlock(gDtlsContextMutex);
+ return DTLS_FAIL;
+ }
+
+ int32_t retLen = dtls_write(gCaDtlsContext->dtlsContext, (session_t *) dstSession, data,
+ dataLen);
+ OIC_LOG_V(DEBUG, NET_DTLS_TAG, "dtls_write retun len [%d]", retLen);
+ if (0 == retLen)
+ {
+ // A new DTLS session was initiated by tinyDTLS library and wait for callback.
+ u_mutex_unlock(gDtlsContextMutex);
+ return DTLS_SESSION_INITIATED;
+ }
+ u_mutex_unlock(gDtlsContextMutex);
+ if (dataLen == retLen)
+ {
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return DTLS_OK;
+ }
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
+ return DTLS_FAIL;
+}
+
+static eDtlsRet_t CAAdapterNetDtlsDecryptInternal(const stCADtlsAddrInfo_t *srcSession,
+ uint8_t *buf, uint32_t bufLen)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ VERIFY_NON_NULL_RET(srcSession, NET_DTLS_TAG, "Param srcSession is NULL", DTLS_FAIL);
+ VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", DTLS_FAIL);
+
+ if (0 == bufLen)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Given Packet length is equal to zero.");
+ return DTLS_FAIL;
+ }
+
+ eDtlsRet_t ret = DTLS_FAIL;
+
+ /// TODO: how to protect gCaDtlsContext as dtls_handle_message is blocking call
+ if (dtls_handle_message(gCaDtlsContext->dtlsContext, (session_t *) srcSession, buf, bufLen)
+ == 0)
+ {
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "dtls_handle_message success");
+ ret = DTLS_OK;
+ }
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return ret;
+}
+
+static void CAFreeCacheMsg(stCACacheMessage_t *msg)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ OICFree(msg->destSession);
+ OICFree(msg->data);
+ OICFree(msg);
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+}
+
+static void CAClearCacheList()
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+ uint32_t list_index = 0;
+ uint32_t list_length = 0;
+ u_mutex_lock(gDtlsListMutex);
+ if (NULL == gCaDtlsContext)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
+ u_mutex_unlock(gDtlsListMutex);
+ return;
+ }
+ list_length = u_arraylist_length(gCaDtlsContext->cacheList);
+ for (list_index = 0; list_index < list_length; list_index++)
+ {
+ stCACacheMessage_t *msg = (stCACacheMessage_t *) u_arraylist_get(gCaDtlsContext->cacheList,
+ list_index);
+ CAFreeCacheMsg(msg);
+ }
+ u_arraylist_free(gCaDtlsContext->cacheList);
+ gCaDtlsContext->cacheList = NULL;
+ u_mutex_unlock(gDtlsListMutex);
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+}
+
+static CAResult_t CADtlsCacheMsg(stCACacheMessage_t *msg)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ u_mutex_lock(gDtlsListMutex);
+ if (NULL == gCaDtlsContext)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Dtls Context is NULL");
+ u_mutex_unlock(gDtlsListMutex);
+ return CA_STATUS_FAILED;
+ }
+
+ CAResult_t result = u_arraylist_add(gCaDtlsContext->cacheList, (void *) msg);
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "u_arraylist_add failed!");
+ }
+ u_mutex_unlock(gDtlsListMutex);
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return result;
+}
+
+static CABool_t CAIsAddressMatching(const stCADtlsAddrInfo_t *a, const stCADtlsAddrInfo_t *b)
+{
+ if (a->size != b->size || a->addr.sa.sa_family != b->addr.sa.sa_family)
+ return CA_FALSE;
+
+ if ((a->addr.sin.sin_port == b->addr.sin.sin_port)
+ && (memcmp(&a->addr.sin.sin_addr, &b->addr.sin.sin_addr, sizeof(struct in_addr)) == 0))
+ {
+ return CA_TRUE;
+ }
+ return CA_FALSE;
+}
+
+static void CASendCachedMsg(const stCADtlsAddrInfo_t *dstSession)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ ///TODO: if dstSession is coming as NULL, what we will do with cached msg.(will be cleared in termination)
+ VERIFY_NON_NULL_VOID(dstSession, NET_DTLS_TAG, "Param dstSession is NULL");
+
+ uint32_t list_index = 0;
+ uint32_t list_length = 0;
+ u_mutex_lock(gDtlsListMutex);
+ list_length = u_arraylist_length(gCaDtlsContext->cacheList);
+ for (list_index = 0; list_index < list_length; list_index++)
+ {
+ stCACacheMessage_t *msg = (stCACacheMessage_t *) u_arraylist_get(gCaDtlsContext->cacheList,
+ list_index);
+ if ((NULL != msg) && (CA_TRUE == CAIsAddressMatching(msg->destSession, dstSession)))
+ {
+ eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(msg->destSession, msg->data,
+ msg->dataLen);
+ if (ret == DTLS_OK)
+ {
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal success");
+ }
+ else
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "CAAdapterNetDtlsEncryptInternal failed.");
+ }
+ u_arraylist_remove(gCaDtlsContext->cacheList, list_index);
+ CAFreeCacheMsg(msg);
+ break;
+ }
+
+ }
+ u_mutex_unlock(gDtlsListMutex);
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+}
+
+static int32_t CAReadDecryptedPayload(dtls_context_t *dtlsContext, session_t *session, uint8_t *buf,
+ size_t bufLen)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
+
+ OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Decrypted buf len [%d]", bufLen);
+
+ stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) session;
+
+ char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
+ uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
+
+ //Notify data to upper layer
+ u_mutex_lock(gDtlsContextMutex);
+ if (NULL == gCaDtlsContext)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+ u_mutex_unlock(gDtlsContextMutex);
+ return 0;
+ }
+ if (gCaDtlsContext->gPacketReceivedCallback)
+ {
+ gCaDtlsContext->gPacketReceivedCallback(remoteAddress, port, buf, bufLen, CA_TRUE);
+ }
+ else
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "gPacketReceivedCallback NULL");
+ }
+ u_mutex_unlock(gDtlsContextMutex);
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return 0;
+}
+
+static int32_t CASendSecureData(dtls_context_t *dtlsContext, session_t *session, uint8_t *buf,
+ size_t bufLen)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
+ VERIFY_NON_NULL_RET(buf, NET_DTLS_TAG, "Param buf is NULL", 0);
+
+ if (0 == bufLen)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Encrypted Buffer length is equal to zero");
+ return 0;
+ }
+
+ stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) session;
+
+ char *remoteAddress = inet_ntoa(addrInfo->addr.sin.sin_addr);
+ uint32_t port = ntohs(addrInfo->addr.sin.sin_port);
+
+ uint32_t sentLen = CAWiFiSendData(remoteAddress, port, buf, bufLen, CA_FALSE, CA_TRUE);
+
+ OIC_LOG_V(DEBUG, NET_DTLS_TAG, "sent buffer length [%d]", sentLen);
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return sentLen;
+}
+
+static int32_t CAHandleSecureEvent(dtls_context_t *dtlsContext, session_t *session,
+ dtls_alert_level_t level, unsigned short code)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ VERIFY_NON_NULL_RET(session, NET_DTLS_TAG, "Param Session is NULL", 0);
+
+ OIC_LOG_V(DEBUG, NET_DTLS_TAG, "level [%d] code [%u]", level, code);
+
+ if (!level && (code == DTLS_EVENT_CONNECTED))
+ {
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "Received DTLS_EVENT_CONNECTED. Sending Cached data");
+ CASendCachedMsg((stCADtlsAddrInfo_t *) session);
+ }
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return 0;
+}
+
+static int32_t CAGetPskCredentials(dtls_context_t *ctx, const session_t *session,
+ dtls_credentials_type_t type, const unsigned char *desc, size_t descLen,
+ unsigned char *result, size_t resultLen)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ int32_t ret = -1;
+
+ CADtlsPskCredsBlob_t * credInfo = NULL;
+ CAGetDtlsPskCredentials(&credInfo);
+
+ VERIFY_NON_NULL_RET(credInfo, NET_DTLS_TAG, "CAGetDtlsPskCredentials credInfo is NULL", 0);
+
+ if ((type == DTLS_PSK_HINT) || (type == DTLS_PSK_IDENTITY))
+ {
+ if (DTLS_PSK_ID_LEN <= resultLen)
+ {
+ memcpy(result, credInfo->rsIdentity, DTLS_PSK_ID_LEN);
+ ret = DTLS_PSK_ID_LEN;
+ }
+ }
+
+ if ((type == DTLS_PSK_KEY) && (desc) && (descLen == DTLS_PSK_PSK_LEN))
+ {
+ int index = 0;
+ for (index = 0; index < credInfo->num; index++)
+ {
+ if (memcmp(desc, credInfo->creds[index].clientIdentity, DTLS_PSK_ID_LEN) == 0)
+ {
+ memcpy(result, credInfo->creds[index].rsClientPsk, DTLS_PSK_PSK_LEN);
+ ret = DTLS_PSK_PSK_LEN;
+ }
+ }
+ }
+
+ return ret;
+}
+
+void CADTLSSetPacketReceiveCallback(CAPacketReceivedCallback callback)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+ u_mutex_lock(gDtlsContextMutex);
+ if (NULL == gCaDtlsContext)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
+ u_mutex_unlock(gDtlsContextMutex);
+ return;
+ }
+
+ gCaDtlsContext->gPacketReceivedCallback = callback;
+
+ u_mutex_unlock(gDtlsContextMutex);
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+}
+
+CAResult_t CAAdapterNetDtlsInit()
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+ u_mutex_init();
+ if (NULL == gDtlsContextMutex)
+ {
+ gDtlsContextMutex = u_mutex_new();
+ VERIFY_NON_NULL_RET(gDtlsContextMutex, NET_DTLS_TAG, "malloc failed",
+ CA_MEMORY_ALLOC_FAILED);
+ }
+
+ if (NULL == gDtlsListMutex)
+ {
+ gDtlsListMutex = u_mutex_new();
+ if (NULL == gDtlsListMutex)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "gDtlsListMutex malloc failed");
+ u_mutex_free(gDtlsContextMutex);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ }
+
+ u_mutex_lock(gDtlsContextMutex);
+ gCaDtlsContext = (stCADtlsContext_t *) OICMalloc(sizeof(stCADtlsContext_t));
+
+ if (NULL == gCaDtlsContext)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Context malloc failed");
+ u_mutex_unlock(gDtlsContextMutex);
+ u_mutex_free(gDtlsContextMutex);
+ u_mutex_free(gDtlsListMutex);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ memset(gCaDtlsContext, 0x0, sizeof(stCADtlsContext_t));
+
+ u_mutex_lock(gDtlsListMutex);
+ gCaDtlsContext->cacheList = u_arraylist_create();
+
+ if (NULL == gCaDtlsContext->cacheList)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "cacheList initialization failed!");
+ u_mutex_unlock(gDtlsListMutex);
+ u_mutex_unlock(gDtlsContextMutex);
+ u_mutex_free(gDtlsContextMutex);
+ u_mutex_free(gDtlsListMutex);
+ OICFree(gCaDtlsContext);
+ gCaDtlsContext = NULL;
+ return CA_STATUS_FAILED;
+ }
+ u_mutex_unlock(gDtlsListMutex);
+ // Initialize clock, crypto and other global vars in tinyDTLS library
+ dtls_init();
+
+ gCaDtlsContext->dtlsContext = dtls_new_context(gCaDtlsContext);
+
+ if (NULL == gCaDtlsContext->dtlsContext)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "dtls_new_context failed");
+ u_mutex_unlock(gDtlsContextMutex);
+ CAAdapterNetDtlsDeInit();
+ return CA_STATUS_FAILED;
+ }
+
+ gCaDtlsContext->callbacks.write = CASendSecureData;
+ gCaDtlsContext->callbacks.read = CAReadDecryptedPayload;
+ gCaDtlsContext->callbacks.event = CAHandleSecureEvent;
+ gCaDtlsContext->callbacks.get_psk_info = CAGetPskCredentials;
+
+ dtls_set_handler(gCaDtlsContext->dtlsContext, &(gCaDtlsContext->callbacks));
+ u_mutex_unlock(gDtlsContextMutex);
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAAdapterNetDtlsDeInit()
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ VERIFY_NON_NULL_VOID(gCaDtlsContext, NET_DTLS_TAG, "context is NULL");
+
+ u_mutex_lock(gDtlsContextMutex);
+ CAClearCacheList();
+ dtls_free_context(gCaDtlsContext->dtlsContext);
+ gCaDtlsContext->dtlsContext = NULL;
+ OICFree(gCaDtlsContext);
+ gCaDtlsContext = NULL;
+ u_mutex_unlock(gDtlsContextMutex);
+
+ u_mutex_free(gDtlsContextMutex);
+ u_mutex_free(gDtlsListMutex);
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+}
+
+CAResult_t CAAdapterNetDtlsEncrypt(const char *remoteAddress, const uint32_t port, const void *data,
+ uint32_t dataLen, uint8_t *cacheFlag)
+{
+
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ VERIFY_NON_NULL_RET(remoteAddress, NET_DTLS_TAG, "Param remoteAddress is NULL",
+ CA_STATUS_FAILED);
+
+ VERIFY_NON_NULL_RET(data, NET_DTLS_TAG, "Param data is NULL", CA_STATUS_FAILED);
+
+ if (0 == dataLen)
+ {
+ OIC_LOG_V(ERROR, NET_DTLS_TAG, "dataLen is less than or equal zero [%d]", dataLen);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, NET_DTLS_TAG, " Data to be encrypted dataLen [%d]", dataLen);
+
+ stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) OICMalloc(sizeof(stCADtlsAddrInfo_t));
+
+ VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+
+ memset(addrInfo, 0x0, sizeof(stCADtlsAddrInfo_t));
+
+ addrInfo->addr.sin.sin_family = AF_INET;
+ addrInfo->addr.sin.sin_port = htons(port);
+ // Conversion from ASCII format to Network format
+ if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
+ OICFree(addrInfo);
+ return CA_STATUS_FAILED;
+ }
+ addrInfo->size = sizeof(addrInfo->addr);
+
+ ///TODO: we need to check this memory allocation is needed or not
+ uint8_t *buf = (uint8_t *) OICMalloc(sizeof(uint8_t) * (dataLen + 1));
+ if (NULL == buf)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "malloc failed!");
+ OICFree(addrInfo);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(buf, 0x0, sizeof(uint8_t) * (dataLen + 1));
+ memcpy(buf, data, dataLen);
+
+ eDtlsRet_t ret = CAAdapterNetDtlsEncryptInternal(addrInfo, buf, dataLen);
+ if (ret == DTLS_SESSION_INITIATED)
+ {
+ stCACacheMessage_t *message = (stCACacheMessage_t *) OICMalloc(sizeof(stCACacheMessage_t));
+ if (NULL == message)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "malloc failed!");
+ OICFree(addrInfo);
+ OICFree(buf);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(message, 0x0, sizeof(stCACacheMessage_t));
+
+ message->data = buf;
+ message->dataLen = dataLen;
+ message->destSession = addrInfo;
+
+ CAResult_t result = CADtlsCacheMsg(message);
+ if (CA_STATUS_OK == result)
+ {
+ if (cacheFlag)
+ {
+ *cacheFlag = 1;
+ }
+ }
+ else
+ {
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "CADtlsCacheMsg failed!");
+ CAFreeCacheMsg(message);
+ }
+ OIC_LOG_V(DEBUG, NET_DTLS_TAG, "OUT Initiating Dtls session [%d]", result);
+ return result;
+ }
+
+ if (ret == DTLS_OK)
+ {
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ OICFree(addrInfo);
+ OICFree(buf);
+ return CA_STATUS_OK;
+ }
+ OICFree(addrInfo);
+ OICFree(buf);
+ OIC_LOG(ERROR, NET_DTLS_TAG, "OUT FAILURE");
+ return CA_STATUS_FAILED;
+}
+
+CAResult_t CAAdapterNetDtlsDecrypt(const char *remoteAddress, const uint32_t port, uint8_t *data,
+ uint32_t dataLen)
+{
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
+
+ stCADtlsAddrInfo_t *addrInfo = (stCADtlsAddrInfo_t *) OICMalloc(sizeof(stCADtlsAddrInfo_t));
+
+ VERIFY_NON_NULL_RET(addrInfo, NET_DTLS_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+
+ memset(addrInfo, 0x0, sizeof(stCADtlsAddrInfo_t));
+
+ addrInfo->addr.sin.sin_family = AF_INET;
+ addrInfo->addr.sin.sin_port = htons(port);
+ // Conversion from ASCII format to Network format
+ if (inet_aton(remoteAddress, &addrInfo->addr.sin.sin_addr) == 0)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Failed to convert from ASCII to Network Address");
+ OICFree(addrInfo);
+ return CA_STATUS_FAILED;
+ }
+ addrInfo->size = sizeof(addrInfo->addr);
+
+ uint8_t *buf = (uint8_t *) OICMalloc(sizeof(uint8_t) * (dataLen + 1));
+ if (NULL == buf)
+ {
+ OIC_LOG(ERROR, NET_DTLS_TAG, "malloc failed!");
+ OICFree(addrInfo);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(buf, 0x0, sizeof(uint8_t) * (dataLen + 1));
+ memcpy(buf, data, dataLen);
+
+ eDtlsRet_t ret = CAAdapterNetDtlsDecryptInternal(addrInfo, buf, dataLen);
+ if (DTLS_OK == ret || DTLS_HS_MSG == ret)
+ {
+ OIC_LOG_V(DEBUG, NET_DTLS_TAG, "Successfully Decrypted or Handshake msg recvd [%d]", ret);
+ OICFree(buf);
+ OICFree(addrInfo);
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
+ return CA_STATUS_OK;
+ }
+
+ OICFree(buf);
+ OICFree(addrInfo);
+ OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT FAILURE");
+ return CA_STATUS_FAILED;
+}
+
return CA_STATUS_OK;
}
-CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, CARemoteEndpoint_t** remoteEndpoint)
+CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, CARemoteEndpoint_t **remoteEndpoint)
{
OIC_LOG_V(DEBUG, TAG, "CACreateRemoteEndpoint");
- CARemoteEndpoint_t* remote = CACreateRemoteEndpointUriInternal(uri);
+ CARemoteEndpoint_t *remote = CACreateRemoteEndpointUriInternal(uri);
*remoteEndpoint = remote;
return CA_STATUS_OK;
}
-void CADestroyRemoteEndpoint(CARemoteEndpoint_t* rep)
+void CADestroyRemoteEndpoint(CARemoteEndpoint_t *rep)
{
OIC_LOG_V(DEBUG, TAG, "CADestroyRemoteEndpoint");
CADestroyRemoteEndpointInternal(rep);
}
-CAResult_t CAGenerateToken(CAToken_t* token)
+CAResult_t CAGenerateToken(CAToken_t *token)
{
OIC_LOG_V(DEBUG, TAG, "CAGenerateToken");
CADestroyTokenInternal(token);
}
-CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t* size)
+CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t *size)
{
OIC_LOG_V(DEBUG, TAG, "CAGetNetworkInformation");
}
-CAResult_t CASendRequest(const CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo)
+CAResult_t CASendRequest(const CARemoteEndpoint_t *object, CARequestInfo_t *requestInfo)
{
OIC_LOG_V(DEBUG, TAG, "CASendGetRequest");
return CADetachRequestMessage(object, requestInfo);
}
-CAResult_t CASendRequestToAll(const CAGroupEndpoint_t* object,
- const CARequestInfo_t* requestInfo)
+CAResult_t CASendRequestToAll(const CAGroupEndpoint_t *object,
+ const CARequestInfo_t *requestInfo)
{
OIC_LOG_V(DEBUG, TAG, "CASendRequestToAll");
return CADetachRequestToAllMessage(object, requestInfo);
}
-CAResult_t CASendNotification(const CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo)
+CAResult_t CASendNotification(const CARemoteEndpoint_t *object, CAResponseInfo_t *responseInfo)
{
OIC_LOG_V(DEBUG, TAG, "CASendNotification");
}
-CAResult_t CASendResponse(const CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo)
+CAResult_t CASendResponse(const CARemoteEndpoint_t *object, CAResponseInfo_t *responseInfo)
{
OIC_LOG_V(DEBUG, TAG, "CASendResponse");
}
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token,
- CAHeaderOption_t* options,uint8_t numOptions)
+CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token,
+ CAHeaderOption_t *options, uint8_t numOptions)
{
OIC_LOG_V(DEBUG, TAG, "CAAdvertiseResource");
return CADetachResponseMessage(object, responseInfo);
}
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token, CAHeaderOption_t* options,
- uint8_t numOptions)
+CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token,
+ CAHeaderOption_t *options,
+ uint8_t numOptions)
{
return CADetachMessageResourceUri(resourceUri, token, options, numOptions);
}
OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", cType);
}
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen)
+static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t dataLen)
{
OIC_LOG(DEBUG, TAG, "receivedPacketCallback in interface controller");
}
}
-static void CANetworkChangedCallback(CALocalConnectivity_t *info,
- CANetworkStatus_t status)
+static void CANetworkChangedCallback(CALocalConnectivity_t *info,
+ CANetworkStatus_t status)
{
OIC_LOG(DEBUG, TAG, "Network Changed callback");
#endif /* ETHERNET_ADAPTER */
#ifdef WIFI_ADAPTER
- CAInitializeWifi(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- handle);
+ CAInitializeWifi(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
+ handle);
#endif /* WIFI_ADAPTER */
#ifdef EDR_ADAPTER
- CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- handle);
+ CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
+ handle);
#endif /* EDR_ADAPTER */
#ifdef LE_ADAPTER
- CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
- handle);
+ CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback,
+ handle);
#endif /* LE_ADAPTER */
}
res = gAdapterHandler[index].GetnetInfo(&tempInfo[index], &tempSize[index]);
OIC_LOG_V(DEBUG, TAG, "%d adapter network info size is %d res:%d", index,
- tempSize[index], res);
+ tempSize[index], res);
}
}
return CA_MEMORY_ALLOC_FAILED;
}
-CAResult_t CASendUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t length)
+CAResult_t CASendUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t length)
{
OIC_LOG(DEBUG, TAG, "Send unicast data to enabled interface..");
for (i = 0; i < u_arraylist_length(list); i++)
{
- type = *(uint8_t*) u_arraylist_get(list, i);
+ type = *(uint8_t *) u_arraylist_get(list, i);
index = CAGetAdapterIndex(type);
if (gAdapterHandler[index].sendDataToAll != NULL)
{
- void* payload = (void*) OICMalloc(length);
+ void *payload = (void *) OICMalloc(length);
if (!payload)
{
OIC_LOG_V(ERROR, TAG, "Out of memory!");
for (i = 0; i < u_arraylist_length(list); i++)
{
- type = *(uint8_t*) u_arraylist_get(list, i);
+ type = *(uint8_t *) u_arraylist_get(list, i);
index = CAGetAdapterIndex(type);
for (i = 0; i < u_arraylist_length(list); i++)
{
- type = *(uint8_t*) u_arraylist_get(list, i);
+ type = *(uint8_t *) u_arraylist_get(list, i);
index = CAGetAdapterIndex(type);
{
if (gAdapterHandler[index].terminate != NULL)
{
- gAdapterHandler[index].stopAdapter();
- gAdapterHandler[index].terminate();
+ gAdapterHandler[index].stopAdapter();
+ gAdapterHandler[index].terminate();
}
}
}
#include <string.h>
#include <stdint.h>
-#include "cawifiadapter_singlethread.h"
-#include "caethernetadapter_singlethread.h"
-#include "caedradapter_singlethread.h"
-#include "caleadapter_singlethread.h"
+#include "cawifiadapter.h"
+#include "caethernetadapter.h"
+#include "caedradapter.h"
+#include "caleadapter.h"
#include "canetworkconfigurator.h"
#include "oic_malloc.h"
#define TAG "CAIFCNT_ST"
-#define MEMORY_ALLOCK_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "Out of memory"); goto memory_error_exit;} }
+#define MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "Out of memory"); goto memory_error_exit;} }
#define CA_CONNECTIVITY_TYPE_NUM 4
// #3. add data into result
// memory allocation
resInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * resSize);
- MEMORY_ALLOCK_CHECK(resInfo);
+ MEMORY_ALLOC_CHECK(resInfo);
memset(resInfo, 0, sizeof(CALocalConnectivity_t) * resSize);
i = 0;
return CA_STATUS_FAILED;
}
+ void *ptrType = NULL;
for (i = 0; i < u_arraylist_length(list); i++)
{
- type = *(uint8_t *) u_arraylist_get(list, i);
+ ptrType = u_arraylist_get(list, i);
+ if (NULL == ptrType)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+ type = *(uint8_t *) ptrType;
index = CAGetAdapterIndex(type);
return CA_STATUS_FAILED;
}
+ void *ptrType = NULL;
for (i = 0; i < u_arraylist_length(list); i++)
{
- type = *(uint8_t *) u_arraylist_get(list, i);
+ ptrType = u_arraylist_get(list, i);
+ if (NULL == ptrType)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+ type = *(uint8_t *) ptrType;
index = CAGetAdapterIndex(type);
return CA_STATUS_FAILED;
}
+ void *ptrType = NULL;
for (i = 0; i < u_arraylist_length(list); i++)
{
- type = *(uint8_t *) u_arraylist_get(list, i);
+ ptrType = u_arraylist_get(list, i);
+ if (NULL == ptrType)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+ type = *(uint8_t *) ptrType;
index = CAGetAdapterIndex(type);
OIC_LOG(DEBUG, TAG, "No selected network");
return CA_STATUS_FAILED;
}
-
+ void *ptrType = NULL;
for (i = 0; i < u_arraylist_length(list); i++)
{
- type = *(uint8_t *) u_arraylist_get(list, i);
+ ptrType = u_arraylist_get(list, i);
+ if (NULL == ptrType)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+ type = *(uint8_t *) ptrType;
index = CAGetAdapterIndex(type);
#include "coap.h"
#include "uthreadpool.h" /* for thread pool */
#include "caqueueingthread.h"
+#include "caretransmission.h"
#include "umutex.h"
#include "oic_malloc.h"
#define TAG PCF("CA")
-#define MEMORY_ALLOCK_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "memory error"); \
+#define MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "memory error"); \
goto memory_error_exit;} }
#define MAX_THREAD_POOL_SIZE 10
static CAQueueingThread_t gSendThread;
static CAQueueingThread_t gReceiveThread;
+static CARetransmission_t gRetransmissionContext;
+
// handler field
static CARequestCallback gRequestHandler = NULL;
static CAResponseCallback gResponseHandler = NULL;
OIC_LOG_V(DEBUG, TAG, "responseInfo is available..");
pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri,
- data->responseInfo->result, data->responseInfo->info);
+ data->responseInfo->result, data->responseInfo->info);
}
else
{
OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
- OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", pdu->hdr->id);
+ OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id));
OIC_LOG_V(DEBUG, TAG, "PDU Maker - token : %s", pdu->hdr->token);
res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
+ // for retransmission
+ CARetransmissionSentData(&gRetransmissionContext, data->remoteEndpoint, pdu->hdr,
+ pdu->length);
+
//For Unicast , data will be deleted by adapters
CADestroyRemoteEndpointInternal(data->remoteEndpoint);
}
OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
- OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", pdu->hdr->id);
+ OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", ntohs(pdu->hdr->id));
OIC_LOG_V(DEBUG, TAG, "PDU Maker - token : %s", pdu->hdr->token);
{
OIC_LOG(DEBUG, TAG, "unknown type!");
}
- OIC_LOG_V(DEBUG, TAG, " Result :%d",res);
+ OIC_LOG_V(DEBUG, TAG, " Result :%d", res);
}
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen)
+static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data,
+ uint32_t dataLen)
{
OIC_LOG(DEBUG, TAG, "receivedPacketCallback in message handler!!");
if (NULL != ReqInfo->info.payload)
{
OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
- }
- OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
+ }
+ OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
OIC_LOG_V(DEBUG, TAG, "Request- token : %s", ReqInfo->info.token);
if (NULL != endpoint)
cadata->responseInfo = ResInfo;
CAQueueingThreadAddData(&gReceiveThread, cadata, sizeof(CAData_t));
+
+ // for retransmission
+ CARetransmissionReceivedData(&gRetransmissionContext, endpoint, pdu->hdr, pdu->length);
}
}
OICFree(rep);
}
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object,
- const CARequestInfo_t *request)
+CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object,
+ const CARequestInfo_t *request)
{
OIC_LOG_V(DEBUG, TAG, "CADetachRequestMessage");
}
CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
- MEMORY_ALLOCK_CHECK(data);
+ MEMORY_ALLOC_CHECK(data);
// initialize
memset(data, 0, sizeof(CAData_t));
// clone remote endpoint
CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(object);
- MEMORY_ALLOCK_CHECK(remoteEndpoint);
+ MEMORY_ALLOC_CHECK(remoteEndpoint);
// clone request info
CARequestInfo_t *requestInfo = CACloneRequestInfo(request);
- MEMORY_ALLOCK_CHECK(requestInfo);
+ MEMORY_ALLOC_CHECK(requestInfo);
// save data
data->type = SEND_TYPE_UNICAST;
}
CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t* object,
- const CARequestInfo_t* request)
+ const CARequestInfo_t *request)
{
// ToDo
OIC_LOG_V(DEBUG, TAG, "CADetachRequestToAllMessage");
-
+
if (object == NULL || request == NULL)
{
return CA_STATUS_FAILED;
}
- CAData_t* data = (CAData_t*) OICMalloc(sizeof(CAData_t));
- MEMORY_ALLOCK_CHECK(data);
+ CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
+ MEMORY_ALLOC_CHECK(data);
// initialize
memset(data, 0, sizeof(CAData_t));
CAAddress_t addr;
memset(&addr, 0, sizeof(CAAddress_t));
CARemoteEndpoint_t* remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr,
- object->connectivityType);
+ object->connectivityType);
// clone request info
- CARequestInfo_t* requestInfo = CACloneRequestInfo(request);
- MEMORY_ALLOCK_CHECK(requestInfo);
+ CARequestInfo_t *requestInfo = CACloneRequestInfo(request);
+ MEMORY_ALLOC_CHECK(requestInfo);
// save data
data->type = SEND_TYPE_MULTICAST;
return CA_STATUS_OK;
// memory error label.
- memory_error_exit:
+memory_error_exit:
CADestroyRemoteEndpointInternal(remoteEndpoint);
}
CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
- MEMORY_ALLOCK_CHECK(data);
+ MEMORY_ALLOC_CHECK(data);
// initialize
memset(data, 0, sizeof(CAData_t));
// clone remote endpoint
CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(object);
- MEMORY_ALLOCK_CHECK(remoteEndpoint);
+ MEMORY_ALLOC_CHECK(remoteEndpoint);
// clone response info
CAResponseInfo_t *responseInfo = CACloneResponseInfo(response);
- MEMORY_ALLOCK_CHECK(responseInfo);
+ MEMORY_ALLOC_CHECK(responseInfo);
// save data
data->type = SEND_TYPE_UNICAST;
}
CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
- const CAHeaderOption_t* options, uint8_t numOptions)
+ const CAHeaderOption_t *options, uint8_t numOptions)
{
if (resourceUri == NULL)
{
return CA_STATUS_FAILED;
}
CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
- MEMORY_ALLOCK_CHECK(data);
+ MEMORY_ALLOC_CHECK(data);
// initialize
memset(data, 0, sizeof(CAData_t));
// save data
data->type = SEND_TYPE_MULTICAST;
data->remoteEndpoint = remoteEndpoint;
- CARequestInfo_t* ReqInfo;
- ReqInfo = (CARequestInfo_t*) OICMalloc(sizeof(CARequestInfo_t));
+ CARequestInfo_t *ReqInfo;
+ ReqInfo = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
if (ReqInfo == NULL)
{
OIC_LOG(DEBUG, TAG, "CADetachMessageResourceUri, Memory allocation failed !");
CAHeaderOption_t *temp = (CAHeaderOption_t *) OICMalloc(
sizeof(CAHeaderOption_t) * numOptions);
- MEMORY_ALLOCK_CHECK(temp);
+ MEMORY_ALLOC_CHECK(temp);
memset(temp, 0, sizeof(CAHeaderOption_t) * numOptions);
memcpy(temp, options, sizeof(CAHeaderOption_t) * numOptions);
return CA_MEMORY_ALLOC_FAILED;
}
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler,
- CAResponseCallback RespHandler)
+void CASetRequestResponseCallbacks(CARequestCallback ReqHandler,
+ CAResponseCallback RespHandler)
{
OIC_LOG_V(DEBUG, TAG, "set request, response handler callback.");
// return res;
// }
+ // retransmission initialize
+ CARetransmissionInitialize(&gRetransmissionContext, gThreadPoolHandle, CASendUnicastData, NULL);
+
+ // start retransmission
+ res = CARetransmissionStart(&gRetransmissionContext);
+
+ if (res != CA_STATUS_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "thread start error(retransmission thread).");
+ return res;
+ }
+
// initialize interface adapters by controller
CAInitializeAdapters(gThreadPoolHandle);
// terminate interface adapters by controller
CATerminateAdapters();
+ // stop retransmission
+ CARetransmissionStop(&gRetransmissionContext);
+ CARetransmissionDestroy(&gRetransmissionContext);
+
// stop thread
// delete thread data
CAQueueingThreadStop(&gSendThread);
#define TAG1 "CAMH_ST"
-#define MEMORY_ALLOCK_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG1, "Out of memory"); goto memory_error_exit;} }
+#define MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG1, "Out of memory"); goto memory_error_exit;} }
#define MAX_THREAD_POOL_SIZE 10
// message handler callback
static CAMessageHandlerCallback gHandlerCallback = NULL;
+static CARetransmission_t gRetransmissionContext;
+
// handler field
static CARequestCallback gRequestHandler = NULL;
static CAResponseCallback gResponseHandler = NULL;
OIC_LOG_V(DEBUG, TAG1, "buffer: %s", pdu->hdr);
res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
+
+ // for retransmission
+ CARetransmissionSentData(&gRetransmissionContext, data->remoteEndpoint, pdu->hdr,
+ pdu->length);
}
}
coap_delete_pdu(pdu);
return;
}
- VERIFY_NON_NULL_VOID(ReqInfo, TAG1, "reqInfo");
memset(ReqInfo, 0, sizeof(CARequestInfo_t));
CAGetRequestInfoFromPdu(pdu, ReqInfo, uri);
}
}
- if(NULL != ReqInfo->info.payload)
+ if (NULL != ReqInfo->info.payload)
{
OIC_LOG_V(DEBUG, TAG1, "Request- payload: %s", ReqInfo->info.payload);
}
coap_delete_pdu(pdu);
return;
}
- VERIFY_NON_NULL_VOID(ResInfo, TAG1, "ResInfo");
memset(ResInfo, 0, sizeof(CAResponseInfo_t));
CAGetResponseInfoFromPdu(pdu, ResInfo, uri);
OIC_LOG_V(DEBUG, TAG1, "list: %s", ResInfo->info.options[i].optionData);
}
- if(NULL != ResInfo->info.payload)
+ if (NULL != ResInfo->info.payload)
{
OIC_LOG_V(DEBUG, TAG1, "payload: %s", ResInfo->info.payload);
}
if (gResponseHandler)
{
gResponseHandler(endpoint, ResInfo);
+
+ // for retransmission
+ CARetransmissionReceivedData(&gRetransmissionContext, endpoint, pdu->hdr, pdu->length);
}
CADestroyResponseInfoInternal(ResInfo);
}
void CAHandleRequestResponseCallbacks()
{
CAReadData();
+ CARetransmissionBaseRoutine((void*)&gRetransmissionContext);
}
CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request)
VERIFY_NON_NULL(object, TAG1, "object");
VERIFY_NON_NULL(request, TAG1, "request");
+ CARemoteEndpoint_t *remoteEndpoint = NULL;
+ CARequestInfo_t *requestInfo = NULL;
CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
- MEMORY_ALLOCK_CHECK(data);
+ MEMORY_ALLOC_CHECK(data);
// initialize
memset(data, 0, sizeof(CAData_t));
// clone remote endpoint
- CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(object);
- MEMORY_ALLOCK_CHECK(remoteEndpoint);
+ remoteEndpoint = CACloneRemoteEndpoint(object);
+ MEMORY_ALLOC_CHECK(remoteEndpoint);
// clone request info
- CARequestInfo_t *requestInfo = CACloneRequestInfo(request);
- MEMORY_ALLOCK_CHECK(requestInfo);
+ requestInfo = CACloneRequestInfo(request);
+ MEMORY_ALLOC_CHECK(requestInfo);
// save data
data->type = SEND_TYPE_UNICAST;
OIC_LOG(DEBUG, TAG1, "IN");
VERIFY_NON_NULL(object, TAG1, "object");
VERIFY_NON_NULL(response, TAG1, "response");
-
+ CAResponseInfo_t *responseInfo = NULL;
+ CARemoteEndpoint_t *remoteEndpoint = NULL;
CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
- MEMORY_ALLOCK_CHECK(data);
+ MEMORY_ALLOC_CHECK(data);
// initialize
memset(data, 0, sizeof(CAData_t));
// clone remote endpoint
- CARemoteEndpoint_t *remoteEndpoint = CACloneRemoteEndpoint(object);
- MEMORY_ALLOCK_CHECK(remoteEndpoint);
+ remoteEndpoint = CACloneRemoteEndpoint(object);
+ MEMORY_ALLOC_CHECK(remoteEndpoint);
// clone response info
- CAResponseInfo_t *responseInfo = CACloneResponseInfo(response);
- MEMORY_ALLOCK_CHECK(responseInfo);
+ responseInfo = CACloneResponseInfo(response);
+ MEMORY_ALLOC_CHECK(responseInfo);
// save data
data->type = SEND_TYPE_UNICAST;
return CA_MEMORY_ALLOC_FAILED;
}
-CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token, const CAHeaderOption_t* options,
+CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
+ const CAHeaderOption_t *options,
uint8_t numOptions)
{
OIC_LOG(DEBUG, TAG1, "IN");
{
return CA_STATUS_FAILED;
}
-
+ CARemoteEndpoint_t *remoteEndpoint = NULL;
CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
- MEMORY_ALLOCK_CHECK(data);
+ MEMORY_ALLOC_CHECK(data);
// initialize
memset(data, 0, sizeof(CAData_t));
CAAddress_t addr;
memset(&addr, 0, sizeof(CAAddress_t));
- CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, addr,
- CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
+ remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, addr,
+ CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
// save data
data->type = SEND_TYPE_MULTICAST;
data->remoteEndpoint = remoteEndpoint;
- CARequestInfo_t* ReqInfo = (CARequestInfo_t*) OICMalloc(sizeof(CARequestInfo_t));
- if (ReqInfo == NULL)
- {
- OIC_LOG(DEBUG, TAG1, "CADetachMessageResourceUri, Memory allocation failed !");
- return CA_MEMORY_ALLOC_FAILED;
- }
+ CARequestInfo_t *ReqInfo = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
+ MEMORY_ALLOC_CHECK(ReqInfo);
memset(ReqInfo, 0, sizeof(CARequestInfo_t));
ReqInfo->method = CA_GET;
ReqInfo->info.token = token;
CAHeaderOption_t *temp = (CAHeaderOption_t *) OICMalloc(
sizeof(CAHeaderOption_t) * numOptions);
- MEMORY_ALLOCK_CHECK(temp);
+ MEMORY_ALLOC_CHECK(temp);
memset(temp, 0, sizeof(CAHeaderOption_t) * numOptions);
memcpy(temp, options, sizeof(CAHeaderOption_t) * numOptions);
CASetNetworkChangeCallback(CANetworkChangedCallback);
+ CAResult_t res;
+
+ // retransmission initialize
+ CARetransmissionInitialize(&gRetransmissionContext, CASendUnicastData, NULL);
+
CAInitializeAdapters();
OIC_LOG(DEBUG, TAG1, "OUT");
return CA_STATUS_OK;
// terminate interface adapters by controller
CATerminateAdapters();
+ // stop retransmission
+ CARetransmissionStop(&gRetransmissionContext);
+ CARetransmissionDestroy(&gRetransmissionContext);
+
OIC_LOG(DEBUG, TAG1, "OUT");
}
for (index = 0; index < u_arraylist_length(gSelectedNetworkList); index++)
{
- type = *(uint32_t*) u_arraylist_get(gSelectedNetworkList, index);
+ type = *(uint32_t *) u_arraylist_get(gSelectedNetworkList, index);
- if(ConnectivityType == type)
+ if (ConnectivityType == type)
{
switch (ConnectivityType)
{
return CA_STATUS_FAILED;
}
+ void *ptrType = NULL;
for (index = 0; index < u_arraylist_length(gSelectedNetworkList); index++)
{
- type = *(uint32_t*) u_arraylist_get(gSelectedNetworkList, index);
+ ptrType = u_arraylist_get(gSelectedNetworkList, index);
+ if (NULL == ptrType)
+ {
+ OIC_LOG(ERROR, TAG, "error");
+ return CA_STATUS_FAILED;
+ }
+ type = *(uint32_t *) ptrType;
- if(ConnectivityType == type)
+ if (ConnectivityType == type)
{
switch (ConnectivityType)
{
#include <time.h>\r
#endif //#ifdef __ARDUINO__\r
\r
-uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, \r
- char *outUri)\r
+uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo,\r
+ char *outUri)\r
{\r
OIC_LOG(DEBUG, TAG, "CAGetRequestInfoFromPdu IN");\r
\r
return 1;\r
}\r
\r
-uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, \r
- char *outUri)\r
+uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,\r
+ char *outUri)\r
{\r
OIC_LOG(DEBUG, TAG, "CAGetResponseInfoFromPdu IN");\r
if (NULL == pdu)\r
}\r
\r
coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *options,\r
- const char* payload, const CAInfo_t info)\r
+ const char *payload, const CAInfo_t info)\r
{\r
OIC_LOG(DEBUG, TAG, "CACreatePDUforRequestWithPayload IN");\r
\r
if (!(pdu = coap_new_pdu()))\r
return NULL;\r
\r
- /* initialize message id */\r
unsigned short message_id;\r
- prng((unsigned char * )&message_id, sizeof(unsigned short));\r
+\r
+ if (info.messageId == 0)\r
+ {\r
+ /* initialize message id */\r
+ prng((unsigned char * )&message_id, sizeof(unsigned short));\r
+ ++message_id;\r
+\r
+ OIC_LOG_V(DEBUG, TAG, "generate the message id(%d)", message_id);\r
+ }\r
+ else\r
+ {\r
+ /* use saved message id */\r
+ message_id = info.messageId;\r
+ }\r
\r
pdu->hdr->type = info.type;\r
- ++message_id;\r
pdu->hdr->id = htons(message_id);\r
pdu->hdr->code = code;\r
\r
if (info.token)\r
{\r
pdu->hdr->token_length = CA_MAX_TOKEN_LEN;\r
- if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token))\r
+ if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token))\r
{\r
OIC_LOG(DEBUG, TAG, "cannot add token to request");\r
}\r
return pdu;\r
}\r
\r
-coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options, \r
- const CAInfo_t info)\r
+coap_pdu_t *CACreatePDUforRequest(const code_t code, coap_list_t *options,\r
+ const CAInfo_t info)\r
{\r
OIC_LOG(DEBUG, TAG, "CACreatePDUforRequest IN");\r
\r
return NULL;\r
}\r
\r
- /* initialize message id */\r
unsigned short message_id;\r
- prng((unsigned char * )&message_id, sizeof(unsigned short));\r
+\r
+ if (info.messageId == 0)\r
+ {\r
+ /* initialize message id */\r
+ prng((unsigned char * )&message_id, sizeof(unsigned short));\r
+ ++message_id;\r
+\r
+ OIC_LOG_V(DEBUG, TAG, "generate the message id(%d)", message_id);\r
+ }\r
+ else\r
+ {\r
+ /* use saved message id */\r
+ message_id = info.messageId;\r
+ }\r
\r
pdu->hdr->type = info.type;\r
- ++message_id;\r
pdu->hdr->id = htons(message_id);\r
pdu->hdr->code = code;\r
\r
OIC_LOG_V(DEBUG, TAG, "token info : %s, %d", info.token, strlen(info.token));\r
pdu->hdr->token_length = CA_MAX_TOKEN_LEN;\r
\r
- if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token))\r
+ if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token))\r
{\r
OIC_LOG(DEBUG, TAG, "cannot add token to request");\r
}\r
{\r
coap_insert(optlist,\r
CACreateNewOptionNode(COAP_OPTION_URI_PORT,\r
- coap_encode_var_bytes(portbuf, uri.port), portbuf), \r
+ coap_encode_var_bytes(portbuf, uri.port), portbuf),\r
CAOrderOpts);\r
}\r
\r
OIC_LOG_V(DEBUG, TAG, "Head Option length: %d", info.options[i].optionLength);\r
\r
coap_insert(optlist,\r
- CACreateNewOptionNode(info.options[i].optionID, \r
+ CACreateNewOptionNode(info.options[i].optionID,\r
info.options[i].optionLength,\r
info.options[i].optionData), CAOrderOpts);\r
}\r
OIC_LOG(DEBUG, TAG, "CAParseHeadOption OUT");\r
}\r
\r
-coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length, \r
- const uint8_t *data)\r
+coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length,\r
+ const uint8_t *data)\r
{\r
OIC_LOG(DEBUG, TAG, "CACreateNewOptionNode IN");\r
coap_option *option;\r
OIC_LOG(DEBUG, TAG, "Out of memory");\r
return NULL;\r
}\r
- memset(option, 0, sizeof(coap_option)+length);\r
+ memset(option, 0, sizeof(coap_option) + length);\r
\r
COAP_OPTION_KEY(*option) = key;\r
COAP_OPTION_LENGTH(*option) = length;\r
if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)\r
{\r
\r
- } else {\r
+ }\r
+ else\r
+ {\r
count++;\r
}\r
}\r
return count;\r
}\r
\r
-void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, \r
- char *outUri)\r
+void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo,\r
+ char *outUri)\r
{\r
OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo IN");\r
char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */\r
// set type\r
outInfo->type = pdu->hdr->type;\r
\r
- if(count > 0)\r
+ // set message id\r
+ outInfo->messageId = ntohs(pdu->hdr->id);\r
+\r
+ if (count > 0)\r
{\r
outInfo->options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * count);\r
if (outInfo->options == NULL)\r
while ((option = coap_option_next(&opt_iter)))\r
{\r
\r
- if (CAGetOptionData((uint8_t*)(COAP_OPT_VALUE(option)), \r
- COAP_OPT_LENGTH(option), (uint8_t*)buf, sizeof(buf),\r
- encode))\r
+ if (CAGetOptionData((uint8_t *)(COAP_OPT_VALUE(option)),\r
+ COAP_OPT_LENGTH(option), (uint8_t *)buf, sizeof(buf),\r
+ encode))\r
{\r
if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)\r
{\r
memcpy(optionResult + optionLength, buf, strlen((const char *) buf));\r
optionLength += strlen((const char *) buf);\r
}\r
- } else {\r
+ }\r
+ else\r
+ {\r
\r
if (idx < count)\r
{\r
uint32_t length = (uint32_t) strlen((const char *) buf);\r
\r
- if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH)\r
- {\r
+ if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH)\r
+ {\r
outInfo->options[idx].optionID = opt_iter.type;\r
outInfo->options[idx].optionLength = length;\r
outInfo->options[idx].protocolID = CA_COAP_ID;\r
OIC_LOG(DEBUG, TAG, "inside pdu->hdr->token_length");\r
outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN);\r
if (outInfo->token == NULL)\r
- {\r
- OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !");\r
- OICFree(outInfo->options);\r
- return;\r
- }\r
+ {\r
+ OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !");\r
+ OICFree(outInfo->options);\r
+ return;\r
+ }\r
memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN);\r
}\r
\r
}\r
\r
uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result,\r
- uint32_t buflen, uint32_t encode_always)\r
+ uint32_t buflen, uint32_t encode_always)\r
{\r
const unsigned char hex[] = "0123456789ABCDEF";\r
uint32_t cnt = 0;\r
*result = '\0';\r
return cnt;\r
}\r
+\r
+CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void* pdu, uint32_t size)\r
+{\r
+ // pdu minimum size is 4 byte.\r
+ if (size < 4)\r
+ return CA_MSG_NONCONFIRM;\r
+\r
+ coap_hdr_t* hdr = (coap_hdr_t*) pdu;\r
+\r
+ return (CAMessageType_t) hdr->type;\r
+}\r
+\r
+uint16_t CAGetMessageIdFromPduBinaryData(const void* pdu, uint32_t size)\r
+{\r
+ // pdu minimum size is 4 byte.\r
+ if (size < 4)\r
+ return 0;\r
+\r
+ coap_hdr_t* hdr = (coap_hdr_t*) pdu;\r
+\r
+ return ntohs(hdr->id);\r
+}\r
if (u_queue_get_size(thread->dataQueue) <= 0)
{
OIC_LOG_V(DEBUG, TAG, "wait..");
-
+
// wait
u_cond_wait(thread->threadCond, thread->threadMutex);
thread->threadTask(data);
// free
+ OICFree(message);
}
u_cond_signal(thread->threadCond);
return CA_STATUS_FAILED;
}
+ thread->isStop = CA_FALSE;
CAResult_t res = u_thread_pool_add_task(thread->threadPool, CAQueueingThreadBaseRoutine,
thread);
-
if (res != CA_STATUS_OK)
{
OIC_LOG_V(DEBUG, TAG, "thread pool add task error(send thread).");
+ thread->isStop = CA_TRUE;
return res;
}
- thread->isStop = CA_FALSE;
-
return res;
}
#define COAP_PREFIX "coap://"
#define COAP_PREFIX_LEN 7
+#define COAPS_PREFIX "coaps://"
+#define COAPS_PREFIX_LEN 8
+
// return 1 : ip
// return 0 : mac
// parse uri
// #1. check prefix
int startIndex = 0;
-
+ CABool_t secured = 0;
if (strncmp(COAP_PREFIX, uri, COAP_PREFIX_LEN) == 0)
{
OIC_LOG_V(DEBUG, TAG, "uri has '%s' prefix.", COAP_PREFIX);
startIndex = COAP_PREFIX_LEN;
}
+ if (strncmp(COAPS_PREFIX, uri, COAPS_PREFIX_LEN) == 0)
+ {
+ OIC_LOG_V(DEBUG, TAG, "uri has '%s' prefix.", COAPS_PREFIX);
+ startIndex = COAPS_PREFIX_LEN;
+ secured = CA_TRUE;
+ }
+
// #2. copy uri for parse
char *cloneUri = NULL;
int32_t len = strlen(uri) - startIndex;
}
CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, address, type);
+ remoteEndpoint->isSecured = secured;
OICFree(cloneUri);
+ OIC_LOG_V(DEBUG, TAG, "Remote endpoint successfully created [%d]!", remoteEndpoint->isSecured);
return remoteEndpoint;
}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+
+#ifdef __ANDROID__
+#include <linux/time.h>
+#endif
+
+#include "caretransmission.h"
+#include "caremotehandler.h"
+#include "caprotocolmessage.h"
+#include "oic_malloc.h"
+#include "logger.h"
+
+#define TAG PCF("RET")
+
+typedef struct
+{
+ /** last sent time. microseconds **/
+ uint64_t timeStamp;
+ /** retransmission count **/
+ uint8_t triedCount;
+ /** coap PDU message id **/
+ uint16_t messageId;
+ /** remote endpoint **/
+ CARemoteEndpoint_t* endpoint;
+ /** coap PDU **/
+ void* pdu;
+ /** coap PDU size**/
+ uint32_t size;
+} CARetransmissionData_t;
+
+/**
+ * getCurrent monotonic time
+ *
+ * microseconds
+ */
+uint64_t getCurrentTimeInMicroSeconds();
+
+/**
+ * timeout routine
+ * 2sec -> 4sec -> 8sec -> 16sec
+ *
+ * microseconds
+ */
+static CABool_t CACheckTimeout(uint64_t currentTime, uint64_t timeStamp, uint8_t triedCount)
+{
+ // #1. calculate timeout
+ uint64_t timeOut = (2 << triedCount) * 1000000;
+
+ if (currentTime >= timeStamp + timeOut)
+ {
+ OIC_LOG_V(DEBUG, TAG, "%d seconds time out!!, tried count(%d)",
+ (2 << triedCount), triedCount);
+ return CA_TRUE;
+ }
+
+ return CA_FALSE;
+}
+
+static void CACheckRetransmissionList(CARetransmission_t *context)
+{
+ // mutex lock
+ u_mutex_lock(context->threadMutex);
+ uint64_t currentTime = 0;
+
+ uint32_t i = 0;
+ uint32_t len = u_arraylist_length(context->dataList);
+
+ for (i = 0; i < len; i++)
+ {
+ CARetransmissionData_t* retData = u_arraylist_get(context->dataList, i);
+
+ if (retData == NULL)
+ continue;
+
+ currentTime = getCurrentTimeInMicroSeconds();
+
+ if (CACheckTimeout(currentTime, retData->timeStamp, retData->triedCount))
+ {
+ // #2. if time's up, send the data.
+ if (context->dataSendMethod != NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "retransmission CON data!!, message id(%d)",
+ retData->messageId);
+ context->dataSendMethod(retData->endpoint, retData->pdu, retData->size);
+ }
+
+ // #3. increase the retransmission count and update timestamp.
+ retData->timeStamp = currentTime;
+ retData->triedCount++;
+ }
+
+ // #4. if tried count is max, remove the retransmission data from list.
+ if (retData->triedCount >= context->config.tryingCount)
+ {
+ CARetransmissionData_t* removedData = u_arraylist_remove(context->dataList, i);
+
+ OIC_LOG_V(DEBUG, TAG, "max trying count, remove retransmission CON data!!\
+ message id(%d)", removedData->messageId);
+
+ CADestroyRemoteEndpointInternal(removedData->endpoint);
+ OICFree(removedData->pdu);
+
+ OICFree(removedData);
+
+ // modify loop value.
+ len = u_arraylist_length(context->dataList);
+ --i;
+ }
+ }
+
+ // mutex unlock
+ u_mutex_unlock(context->threadMutex);
+}
+
+static void CARetransmissionBaseRoutine(void *threadValue)
+{
+ OIC_LOG_V(DEBUG, TAG, "retransmission main thread start..");
+
+ CARetransmission_t *context = (CARetransmission_t *) threadValue;
+
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "thread data passing error!!");
+
+ return;
+ }
+
+ while (!context->isStop)
+ {
+ // mutex lock
+ u_mutex_lock(context->threadMutex);
+
+ if (u_arraylist_length(context->dataList) <= 0)
+ {
+ // if list is empty, thread will wait
+ OIC_LOG_V(DEBUG, TAG, "wait..there is no retransmission data.");
+
+ // wait
+ u_cond_wait(context->threadCond, context->threadMutex);
+
+ OIC_LOG_V(DEBUG, TAG, "wake up..");
+ }
+ else
+ {
+ // check each RETRANSMISSION_CHECK_PERIOD time.
+ OIC_LOG_V(DEBUG, TAG, "wait..(%d)microseconds", RETRANSMISSION_CHECK_PERIOD);
+
+ // wait
+ u_cond_timed_wait(context->threadCond, context->threadMutex,
+ RETRANSMISSION_CHECK_PERIOD);
+ }
+
+ // mutex unlock
+ u_mutex_unlock(context->threadMutex);
+
+ // check stop flag
+ if (context->isStop)
+ continue;
+
+ CACheckRetransmissionList(context);
+ }
+
+ u_cond_signal(context->threadCond);
+
+ OIC_LOG_V(DEBUG, TAG, "retransmission main thread end..");
+
+}
+
+CAResult_t CARetransmissionInitialize(CARetransmission_t* context, u_thread_pool_t handle,
+ CADataSendMethod_t retransmissionSendMethod, CARetransmissionConfig_t* config)
+{
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "thread instance is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ if (handle == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "thread pool handle is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "thread initialize..");
+
+ memset(context, 0, sizeof(CARetransmission_t));
+
+ CARetransmissionConfig_t cfg;
+ memset(&cfg, 0, sizeof(CARetransmissionConfig_t));
+
+ if (config == NULL)
+ {
+ // setDefault
+ cfg.supportType = DEFAULT_RETRANSMISSION_TYPE;
+ cfg.tryingCount = DEFAULT_RETRANSMISSION_COUNT;
+ }
+ else
+ {
+ cfg = *config;
+ }
+
+ // mutex init
+ u_mutex_init();
+
+ // set send thread data
+ context->threadPool = handle;
+ context->threadMutex = u_mutex_new();
+ context->threadCond = u_cond_new();
+ context->dataSendMethod = retransmissionSendMethod;
+ context->config = cfg;
+ context->isStop = CA_FALSE;
+ context->dataList = u_arraylist_create();
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionStart(CARetransmission_t* context)
+{
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "context is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ if (context->threadPool == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "thread pool handle is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ CAResult_t res = u_thread_pool_add_task(context->threadPool, CARetransmissionBaseRoutine,
+ context);
+
+ if (res != CA_STATUS_OK)
+ {
+ OIC_LOG_V(DEBUG, TAG, "thread pool add task error(send thread).");
+ return res;
+ }
+
+ return res;
+}
+
+CAResult_t CARetransmissionSentData(CARetransmission_t* context,
+ const CARemoteEndpoint_t* endpoint,
+ const void* pdu, uint32_t size)
+{
+ if (context == NULL || endpoint == NULL || pdu == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "invalid parameter..");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ // #0. check support connectivity type
+ if (!(context->config.supportType & endpoint->connectivityType))
+ {
+ OIC_LOG_V(DEBUG, TAG, "not supported connectivity type for retransmission..(%d)",
+ endpoint->connectivityType);
+ return CA_STATUS_OK;
+ }
+
+ // #1. check PDU method type and get message id.
+ CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
+ uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
+
+ OIC_LOG_V(DEBUG, TAG, "sent pdu, message type(%d), message id(%d)", type, messageId);
+
+ if (type != CA_MSG_CONFIRM)
+ {
+ return CA_STATUS_OK;
+ }
+
+ // create retransmission data
+ CARetransmissionData_t* retData = (CARetransmissionData_t*) OICMalloc(
+ sizeof(CARetransmissionData_t));
+
+ if (retData == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "memory error!!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(retData, 0, sizeof(CARetransmissionData_t));
+
+ // copy PDU data
+ void* pduData = (void*) OICMalloc(sizeof(int8_t) * size);
+ if (pduData == NULL)
+ {
+ OICFree(retData);
+ OIC_LOG_V(DEBUG, TAG, "memory error!!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(pduData, 0, sizeof(int8_t) * size);
+ memcpy(pduData, pdu, sizeof(int8_t) * size);
+
+ // clone remote endpoint
+ CARemoteEndpoint_t* remoteEndpoint = CACloneRemoteEndpoint(endpoint);
+ if (remoteEndpoint == NULL)
+ {
+ OICFree(retData);
+ OICFree(pduData);
+ OIC_LOG_V(DEBUG, TAG, "memory error!!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ // #2. add additional information. (time stamp, retransmission count...)
+ retData->timeStamp = getCurrentTimeInMicroSeconds();
+ retData->triedCount = 0;
+ retData->messageId = messageId;
+ retData->endpoint = remoteEndpoint;
+ retData->pdu = pduData;
+ retData->size = size;
+
+ // mutex lock
+ u_mutex_lock(context->threadMutex);
+
+ // #3. add data into list
+ u_arraylist_add(context->dataList, (void*) retData);
+
+ // notity the thread
+ u_cond_signal(context->threadCond);
+
+ // mutex unlock
+ u_mutex_unlock(context->threadMutex);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionReceivedData(CARetransmission_t* context,
+ const CARemoteEndpoint_t* endpoint, const void* pdu, uint32_t size)
+{
+ if (context == NULL || endpoint == NULL || pdu == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "invalid parameter..");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ // #0. check support connectivity type
+ if (!(context->config.supportType & endpoint->connectivityType))
+ {
+ OIC_LOG_V(DEBUG, TAG, "not supported connectivity type for retransmission..(%d)",
+ endpoint->connectivityType);
+ return CA_STATUS_OK;
+ }
+
+ // #1. check PDU method type and get message id.
+ // ACK, RST --> remove the CON data
+ CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
+ uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
+
+ OIC_LOG_V(DEBUG, TAG, "received pdu, message type(%d), message id(%d)", type, messageId);
+
+ if (type != CA_MSG_ACKNOWLEDGE && type != CA_MSG_RESET)
+ {
+ return CA_STATUS_OK;
+ }
+
+ // mutex lock
+ u_mutex_lock(context->threadMutex);
+
+ uint32_t i = 0;
+ uint32_t len = u_arraylist_length(context->dataList);
+
+ // find index
+ for (i = 0; i < len; i++)
+ {
+ CARetransmissionData_t* retData = u_arraylist_get(context->dataList, i);
+
+ if (retData == NULL)
+ continue;
+
+ // found index
+ if ((retData->endpoint->connectivityType == endpoint->connectivityType)
+ && retData->messageId == messageId)
+ break;
+ }
+
+ // #2. remove data from list
+ if (i < len)
+ {
+ CARetransmissionData_t* removedData = u_arraylist_remove(context->dataList, i);
+
+ OIC_LOG_V(DEBUG, TAG, "remove retransmission CON data!!, message id(%d)", messageId);
+
+ CADestroyRemoteEndpointInternal(removedData->endpoint);
+ OICFree(removedData->pdu);
+
+ OICFree(removedData);
+ }
+
+ // mutex unlock
+ u_mutex_unlock(context->threadMutex);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionStop(CARetransmission_t* context)
+{
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "context is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "retransmission stop request!!");
+
+ // mutex lock
+ u_mutex_lock(context->threadMutex);
+
+ // set stop flag
+ context->isStop = CA_TRUE;
+
+ // notity the thread
+ u_cond_signal(context->threadCond);
+
+ u_cond_wait(context->threadCond, context->threadMutex);
+
+ // mutex unlock
+ u_mutex_unlock(context->threadMutex);
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionDestroy(CARetransmission_t* context)
+{
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "context is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "retransmission context destroy..");
+
+ u_mutex_free(context->threadMutex);
+ context->threadMutex = NULL;
+ u_cond_free(context->threadCond);
+ u_arraylist_free(context->dataList);
+
+ return CA_STATUS_OK;
+}
+
+uint64_t getCurrentTimeInMicroSeconds()
+{
+ uint64_t currentTime = 0;
+
+#ifdef __ANDROID__
+ struct timespec getTs;
+
+ memset(&getTs, 0, sizeof(getTs));
+ clock_gettime(CLOCK_MONOTONIC, &getTs);
+
+ currentTime = (getTs.tv_sec * 1000000000 + getTs.tv_nsec)/1000;
+ OIC_LOG_V(DEBUG, TAG, "current time = %d", currentTime);
+#else
+ currentTime = g_get_monotonic_time();
+#endif
+ return currentTime;
+}
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+#include "caretransmission_singlethread.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <TimedAction.h>
+
+#include "caremotehandler.h"
+#include "caprotocolmessage.h"
+#include "oic_malloc.h"
+#include "logger.h"
+
+#define TAG "RET"
+
+typedef struct
+{
+ /** last sent time. microseconds **/
+ uint64_t timeStamp;
+ /** retransmission count **/
+ uint8_t triedCount;
+ /** coap PDU message id **/
+ uint16_t messageId;
+ /** remote endpoint **/
+ CARemoteEndpoint_t* endpoint;
+ /** coap PDU **/
+ void* pdu;
+ /** coap PDU size**/
+ uint32_t size;
+} CARetransmissionData_t;
+
+static TimedAction gRcvAction = TimedAction(2000, CACheckRetransmissionList);
+static CARetransmission_t *gRetransmissionPtr = NULL;
+
+/**
+ * getCurrent monotonic time
+ *
+ * microseconds
+ */
+uint64_t getCurrentTimeInMicroSeconds();
+
+/**
+ * timeout routine
+ * 2sec -> 4sec -> 8sec -> 16sec
+ *
+ * microseconds
+ */
+static CABool_t CACheckTimeout(uint64_t currentTime, uint64_t timeStamp, uint8_t triedCount)
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ // #1. calculate timeout
+ uint64_t timeOut = (2 << triedCount) * 1000000;
+
+ if (currentTime >= timeStamp + timeOut)
+ {
+ OIC_LOG_V(DEBUG, TAG, "%d sec time out!!, tried count(%d)", (2 << triedCount), triedCount);
+ return CA_TRUE;
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return CA_FALSE;
+}
+
+void CACheckRetransmissionList()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ uint64_t currentTime = 0;
+
+ uint32_t i = 0;
+ uint32_t len = u_arraylist_length(gRetransmissionPtr->dataList);
+
+ OIC_LOG_V(DEBUG, TAG, "len=%d", len);
+ for (i = 0; i < len; i++)
+ {
+ CARetransmissionData_t* retData =
+ (CARetransmissionData_t*)u_arraylist_get(gRetransmissionPtr->dataList, i);
+
+ if (retData == NULL)
+ continue;
+
+ currentTime = getCurrentTimeInMicroSeconds();
+
+ OIC_LOG_V(DEBUG, TAG, "currtime=%lu", currentTime);
+ if (CACheckTimeout(currentTime, retData->timeStamp, retData->triedCount))
+ {
+
+ OIC_LOG(DEBUG, TAG, "CCT-Success, retransmit data");
+ // #2. if time's up, send the data.
+ if (gRetransmissionPtr->dataSendMethod != NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "retry CON data, msgid=%d", retData->messageId);
+ gRetransmissionPtr->dataSendMethod(retData->endpoint, retData->pdu, retData->size);
+ }
+
+ // #3. increase the retransmission count and update timestamp.
+ retData->timeStamp = currentTime;
+ retData->triedCount++;
+ }
+
+ // #4. if tried count is max, remove the retransmission data from list.
+ if (retData->triedCount >= gRetransmissionPtr->config.tryingCount)
+ {
+ CARetransmissionData_t* removedData =
+ (CARetransmissionData_t*)u_arraylist_remove(gRetransmissionPtr->dataList, i);
+
+ OIC_LOG_V(DEBUG, TAG, "max trycount, remove retransmission CON data!!, messageid=%d",
+ removedData->messageId);
+
+ CADestroyRemoteEndpointInternal(removedData->endpoint);
+ OICFree(removedData->pdu);
+
+ OICFree(removedData);
+
+ // modify loop value.
+ len = u_arraylist_length(gRetransmissionPtr->dataList);
+ --i;
+ }
+ }
+ OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CARetransmissionBaseRoutine(void *threadValue)
+{
+ CARetransmission_t *context = (CARetransmission_t *) threadValue;
+
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "error");
+ return;
+ }
+
+ if (CA_TRUE == context->isStop)
+ {
+ OIC_LOG(DEBUG, TAG, "Not reqd");
+ return;
+ }
+ gRetransmissionPtr = context;
+ gRcvAction.check();
+}
+
+CAResult_t CARetransmissionInitialize(CARetransmission_t* context,
+ CADataSendMethod_t retransmissionSendMethod,
+ CARetransmissionConfig_t* config)
+{
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "thread instance is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "thread initialize..");
+
+ memset(context, 0, sizeof(CARetransmission_t));
+
+ CARetransmissionConfig_t cfg;
+ memset(&cfg, 0, sizeof(CARetransmissionConfig_t));
+
+ if (config == NULL)
+ {
+ // setDefault
+ cfg.supportType = (CAConnectivityType_t)DEFAULT_RETRANSMISSION_TYPE;
+ cfg.tryingCount = DEFAULT_RETRANSMISSION_COUNT;
+ }
+ else
+ {
+ cfg = *config;
+ }
+
+ // set send thread data
+ context->dataSendMethod = retransmissionSendMethod;
+ context->config = cfg;
+ context->isStop = CA_FALSE;
+ context->dataList = u_arraylist_create();
+
+ // Enable TimedAction for CACheckRetransmissionList API
+ gRetransmissionPtr = context;
+ gRcvAction.enable();
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionSentData(CARetransmission_t* context,
+ const CARemoteEndpoint_t* endpoint,
+ const void* pdu, uint32_t size)
+{
+ if (context == NULL || endpoint == NULL || pdu == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "error");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ // #0. check support connectivity type
+ if (!(context->config.supportType & endpoint->connectivityType))
+ {
+ OIC_LOG_V(DEBUG, TAG, "not supported conntype=%d", endpoint->connectivityType);
+ return CA_STATUS_OK;
+ }
+
+ // #1. check PDU method type and get message id.
+ CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
+ uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
+
+ OIC_LOG_V(DEBUG, TAG, "sent pdu, msgtype=%d,msgid=%d", type, messageId);
+
+ if (type != CA_MSG_CONFIRM)
+ {
+ return CA_STATUS_OK;
+ }
+
+ // create retransmission data
+ CARetransmissionData_t* retData = (CARetransmissionData_t*) OICMalloc(
+ sizeof(CARetransmissionData_t));
+
+ if (retData == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "memory error!!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(retData, 0, sizeof(CARetransmissionData_t));
+
+ // copy PDU data
+ void* pduData = (void*) OICMalloc(sizeof(int8_t) * size);
+ if (pduData == NULL)
+ {
+ OICFree(retData);
+ OIC_LOG_V(DEBUG, TAG, "memory error!!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+ memset(pduData, 0, sizeof(int8_t) * size);
+ memcpy(pduData, pdu, sizeof(int8_t) * size);
+
+ // clone remote endpoint
+ CARemoteEndpoint_t* remoteEndpoint = CACloneRemoteEndpoint(endpoint);
+ if (remoteEndpoint == NULL)
+ {
+ OICFree(retData);
+ OICFree(pduData);
+ OIC_LOG_V(DEBUG, TAG, "memory error!!");
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ // #2. add additional information. (time stamp, retransmission count...)
+ retData->timeStamp = getCurrentTimeInMicroSeconds();
+ retData->triedCount = 0;
+ retData->messageId = messageId;
+ retData->endpoint = remoteEndpoint;
+ retData->pdu = pduData;
+ retData->size = size;
+
+ // #3. add data into list
+ u_arraylist_add(context->dataList, (void*) retData);
+
+ // #4. Initiate Re-transmission for added entry
+ gRetransmissionPtr = context;
+ CACheckRetransmissionList();
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionReceivedData(CARetransmission_t* context,
+ const CARemoteEndpoint_t* endpoint, const void* pdu, uint32_t size)
+{
+ if (context == NULL || endpoint == NULL || pdu == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "invalid parameter..");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ // #0. check support connectivity type
+ if (!(context->config.supportType & endpoint->connectivityType))
+ {
+ OIC_LOG_V(DEBUG, TAG, "not supported conntype=%d", endpoint->connectivityType);
+ return CA_STATUS_OK;
+ }
+
+ // #1. check PDU method type and get message id.
+ // ACK, RST --> remove the CON data
+ CAMessageType_t type = CAGetMessageTypeFromPduBinaryData(pdu, size);
+ uint16_t messageId = CAGetMessageIdFromPduBinaryData(pdu, size);
+
+ OIC_LOG_V(DEBUG, TAG, "recv pdu, msgtype=%d,msgid=%d", type, messageId);
+
+ if (type != CA_MSG_ACKNOWLEDGE && type != CA_MSG_RESET)
+ {
+ return CA_STATUS_OK;
+ }
+
+ uint32_t i = 0;
+ uint32_t len = u_arraylist_length(context->dataList);
+
+ // find index
+ for (i = 0; i < len; i++)
+ {
+ CARetransmissionData_t* retData =
+ (CARetransmissionData_t*)u_arraylist_get(context->dataList, i);
+
+ if (retData == NULL)
+ continue;
+
+ // found index
+ if ((retData->endpoint->connectivityType == endpoint->connectivityType)
+ && retData->messageId == messageId)
+ break;
+ }
+
+ // #2. remove data from list
+ if (i < len)
+ {
+ CARetransmissionData_t* removedData =
+ (CARetransmissionData_t*)u_arraylist_remove(context->dataList, i);
+
+ OIC_LOG_V(DEBUG, TAG, "remove retransmission CON data!!, message id(%d)", messageId);
+
+ CADestroyRemoteEndpointInternal(removedData->endpoint);
+ OICFree(removedData->pdu);
+
+ OICFree(removedData);
+ }
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionStop(CARetransmission_t* context)
+{
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "context is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "retransmission stop request!!");
+
+ // Disable TimedAction for CACheckRetransmissionList API
+ gRcvAction.disable();
+
+ // set stop flag
+ context->isStop = CA_TRUE;
+
+ return CA_STATUS_OK;
+}
+
+CAResult_t CARetransmissionDestroy(CARetransmission_t* context)
+{
+ if (context == NULL)
+ {
+ OIC_LOG_V(DEBUG, TAG, "context is empty..");
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG_V(DEBUG, TAG, "retransmission context destroy..");
+
+ u_arraylist_free(context->dataList);
+
+ return CA_STATUS_OK;
+}
+
+uint64_t getCurrentTimeInMicroSeconds()
+{
+ OIC_LOG(DEBUG, TAG, "IN");
+ uint64_t currentTime = 0;
+
+/*
+#ifdef __ANDROID__
+ struct timespec getTs;
+
+ memset(&getTs, 0, sizeof(getTs));
+ clock_gettime(CLOCK_MONOTONIC, &getTs);
+
+ currentTime = (getTs.tv_sec * 1000000000 + getTs.tv_nsec)/1000;
+ OIC_LOG_V(DEBUG, TAG, "current time = %d", currentTime);
+#else if __ARDUINO__
+ currentTime = micros();
+#else
+ currentTime = g_get_monotonic_time();
+*/
+#ifdef __ARDUINO__
+ currentTime = micros();
+
+ OIC_LOG_V(DEBUG, TAG, "currtime=%lu", currentTime);
+#else
+ currentTime = g_get_monotonic_time();
+#endif
+
+ OIC_LOG(DEBUG, TAG, "OUT");
+ return currentTime;
+}
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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.
- *
- ******************************************************************/
-
-#include "caethernetadapter_singlethread.h"
-
-#include <stdio.h>
-#include <stdint.h>
-#include "caadapterutils.h"
-#include "logger.h"
-
-#include "caethernetadapterutils.h"
-
-/**
- * @def ETHERNET_ADAPTER_TAG
- * @brief Logging tag for module name
- */
-#define ETHERNET_ADAPTER_TAG "EA"
-
-/**
- * @def CA_PORT
- * @brief Port to listen for incoming data
- */
-#define CA_PORT 5383
-
-#define CA_MCAST_PORT 5683
-
-/**
- * @def CA_MULTICAST_IP
- * @brief Multicast IP Address
- */
-#define CA_MULTICAST_IP "224.0.1.187"
-
-/**
- * @var gNetworkCallback
- * @brief Network callback
- */
-static CANetworkChangeCallback gNetworkCallback = NULL;
-
-/**
- * @var gIsMulticastServerStarted
- * @brief Flag to check if multicast server is started
- */
-static int gIsMulticastServerStarted = 0;
-
-int CAEthernetRegisterNetworkNotifications(CANetworkChangeCallback netCallback)
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-
- gNetworkCallback = netCallback;
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback networkPacketCallback, CANetworkChangeCallback netCallback)
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
- VERIFY_NON_NULL(registerCallback, ETHERNET_ADAPTER_TAG, "registercallback");
- VERIFY_NON_NULL(networkPacketCallback, ETHERNET_ADAPTER_TAG, "networkpacketcallback");
- VERIFY_NON_NULL(netCallback, ETHERNET_ADAPTER_TAG, "netcallback");
-
- CAConnectivityHandler_t ethernetHandler;
- ethernetHandler.startAdapter = CAStartEthernet;
- ethernetHandler.startListenServer = CAStartEthernetListeningServer;
- ethernetHandler.startDiscoverServer = CAStartEthernetDiscoveryServer;
- ethernetHandler.sendData = CASendEthernetUnicastData;
- ethernetHandler.sendDataToAll = CASendEthernetMulticastData;
- ethernetHandler.GetnetInfo = CAGetEthernetInterfaceInformation;
- ethernetHandler.readData = CAReadEthernetData;
- ethernetHandler.stopAdapter = CAStopEthernet;
- ethernetHandler.terminate = CATerminateEthernet;
- registerCallback(ethernetHandler, CA_ETHERNET);
-
- CASetEthernetNetworkPacketCallback(networkPacketCallback);
- CAEthernetRegisterNetworkNotifications(netCallback);
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAStartEthernet()
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
- int16_t unicastPort = CA_PORT;
- CAResult_t ret = CA_STATUS_OK;
-
- /*Address is hardcoded as we are using Single Interface*/
- ret = CAStartUnicastServer("0.0.0.0", &unicastPort);
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return ret;
-}
-
-CAResult_t CAStartEthernetListeningServer()
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-
- CAResult_t ret = CA_STATUS_OK;
- int16_t multicastPort = CA_MCAST_PORT;
-
- if (gIsMulticastServerStarted == 1)
- {
- OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Already started");
- return CA_SERVER_STARTED_ALREADY;
- }
-
- ret = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort);
- if (ret == CA_STATUS_OK)
- {
- OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "success");
- gIsMulticastServerStarted = 1;
- }
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return ret;
-}
-
-CAResult_t CAStartEthernetDiscoveryServer()
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return CAStartEthernetListeningServer();
-}
-
-uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLen)
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-
- uint32_t dataSize = 0;
-
- VERIFY_NON_NULL_RET(remoteEndpoint, ETHERNET_ADAPTER_TAG, "remoteEndpoint",
- dataSize);
- VERIFY_NON_NULL_RET(data, ETHERNET_ADAPTER_TAG, "data", dataSize);
-
- if (dataLen <= 0)
- {
- OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "data");
- return dataSize;
-
- }
-
- dataSize = CAEthernetSendData(remoteEndpoint->addressInfo.IP.ipAddress,
- remoteEndpoint->addressInfo.IP.port, data, dataLen, 0);
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return dataSize;
-}
-
-uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLength)
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-
- uint32_t dataSize = 0;
-
- VERIFY_NON_NULL_RET(data, ETHERNET_ADAPTER_TAG, "data", dataSize);
-
- if (dataLength <= 0)
- {
- OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "data");
- return 0;
-
- }
- dataSize = CAEthernetSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, 1);
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return dataSize;
-}
-
-CAResult_t CAStartEthernetNotifyRecvServers()
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-uint32_t CASendEthernetNotification(const CARemoteEndpoint_t *endpoint, void *data,
- uint32_t dataLen)
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(info, ETHERNET_ADAPTER_TAG, "info");
- char localIpAddress[CA_IPADDR_SIZE];
- int32_t localIpAddressLen = sizeof(localIpAddress);
-
- CAArduinoGetInterfaceAddress(localIpAddress, localIpAddressLen);
- /**
- * Create local endpoint using util function
- */
- (*info) = CAAdapterCreateLocalEndpoint(CA_ETHERNET, localIpAddress, "Ethernet");
- if (NULL == (*info))
- {
- OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- (*size) = 1;
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAReadEthernetData()
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
- CAArduoinoCheckServerData();
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAStopEthernet()
-{
- CAResult_t result = CA_STATUS_FAILED;
- result = CAStopUnicastServer();
- if (result != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "unicast");
- return result;
- }
-
- result = CAStopMulticastServer();
- if (result != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "multicast");
- return result;
- }
- else
- {
- gIsMulticastServerStarted = 0;
- }
- return CA_STATUS_OK;
-}
-
-void CATerminateEthernet()
-{
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
- CAResult_t result = CA_STATUS_FAILED;
-
- CASetEthernetNetworkPacketCallback(NULL);
- result = CAEthernetRegisterNetworkNotifications(NULL);
- if (result != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "register failed");
- }
-
- OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
- return;
-}
-
* limitations under the License.
*
******************************************************************/
-
#include "caethernetadapterutils.h"
#include <Arduino.h>
#include <w5100.h>
#include <EthernetUdp.h>
#include <IPAddress.h>
-#include <TimedAction.h>
#include "logger.h"
#include "cacommon.h"
-#include "cainterface.h"
#include "caadapterinterface.h"
+#include "caethernetadapter.h"
#include "caadapterutils.h"
-#include "oic_malloc.h"
-
-#define COAP_MAX_PDU_SIZE 320
-#define MOD_NAME "EAU"
-
-/// Length of the IP address decimal notation string
-#define IPNAMESIZE (16)
-static CANetworkPacketReceivedCallback gNetworkPacketCallback;
-static int32_t gUnicastSocket = 0;
-static int32_t gMulticastSocket = 0;
-static bool gServerRunning = false;
-static TimedAction gRcvAction = TimedAction(3000, CACheckData);
+#define MOD_NAME "EU"
-/**
- * @var gUnicastPort
- * @brief Unicast Port
- */
-static int16_t gUnicastPort = 0;
-
-// Retrieves a empty socket and bind it for UDP with the input port
-/**
- * @brief API to start unicast server.
- * @param localAddress - Local Unicast IP address to bind the socket.
- * @param port - Local port number where socket will listen for incoming request.
- * @return - Error Code
- */
-CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port)
+CAResult_t CAArduinoInitUdpSocket(int16_t *port, int32_t *socketID)
{
OIC_LOG(DEBUG, MOD_NAME, "IN");
VERIFY_NON_NULL(port, MOD_NAME, "port");
+ VERIFY_NON_NULL(socketID, MOD_NAME, "socketID");
- // Note: ****Update the MAC address here with your shield's MAC address****
- uint8_t ETHERNET_MAC[] = {0x90, 0xA2, 0xDA, 0x0E, 0xC4, 0x05};
- uint8_t error = Ethernet.begin(ETHERNET_MAC);
- if (error == 0)
- {
- OIC_LOG_V(ERROR, MOD_NAME, "cant connect:%d", error);
- return CA_STATUS_FAILED;
- }
- OIC_LOG(DEBUG, MOD_NAME, "success");
-
- uint8_t rawIPAddr[4];
- char address[16];
- W5100.getIPAddress(rawIPAddr);
- sprintf(address, "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
- OIC_LOG_V(DEBUG, MOD_NAME, "address:%s", address);
-
- if (CAArduinoInitUdpSocket(port, &gUnicastSocket) != CA_STATUS_OK)
- {
- OIC_LOG(DEBUG, MOD_NAME, "failed");
- return CA_STATUS_FAILED;
- }
-
- gUnicastPort = *port;
- OIC_LOG_V(DEBUG, MOD_NAME, "gUnicastPort: %d", gUnicastPort);
-
- // start thread to monitor socket here
- if (!gServerRunning)
- {
- gRcvAction.enable();
- gServerRunning = true;
- }
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return CA_STATUS_OK;
-}
-
-// Retrieves the IP address assigned to Arduino Ethernet shield
-CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- VERIFY_NON_NULL(address, MOD_NAME, "address");
-
- //TODO : Fix this for scenarios when this API is invoked when device is not connected
- uint8_t rawIPAddr[4];
- if (addrLen < IPNAMESIZE)
- {
- OIC_LOG(ERROR, MOD_NAME, "Invalid addrLen");
- return CA_STATUS_FAILED;
- }
-
- W5100.getIPAddress(rawIPAddr);
- sprintf(address, "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
-
- OIC_LOG_V(DEBUG, MOD_NAME, "address:%s", address);
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAArduinoInitUdpSocket(int16_t *port, int32_t *socketID)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- VERIFY_NON_NULL(socketID, MOD_NAME, "socket");
uint8_t state;
//Is any socket available to work with ?
int32_t sockID = 0;
int32_t sockID = 0;
//Is any socket available to work with ?
- sockID = -1;
for (int i = 1; i < MAX_SOCK_NUM; i++)
{
state = W5100.readSnSR(i);
return CA_STATUS_OK;
}
-/**
- * @brief API to start multicast server.
- * @param mcastAddress - IP address to join multicast group.
- * @param localAddress - Local Unicast IP address to bind the socket.
- * @param port - multicast port number where socket will listen for incoming request.
- * @return - Error Code
- */
-CAResult_t CAStartMulticastServer(const char *mcastAddress, const char *localAddress,
- const int16_t *port)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- if (CAArduinoInitMulticastUdpSocket(mcastAddress, port, port, &gMulticastSocket) != CA_STATUS_OK)
- {
- OIC_LOG(DEBUG, MOD_NAME, "failed");
- return CA_STATUS_FAILED;
- }
-
- // start thread to monitor socket here
- if (!gServerRunning)
- {
- gRcvAction.enable();
- gServerRunning = true;
- }
-
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAStopUnicastServer()
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- // terminate server thread
- // Stop thread if both server stopped
- if (gMulticastSocket == 0)
- {
- gRcvAction.disable();
- gServerRunning = false;
- }
-
- close(gUnicastSocket);
- gUnicastSocket = 0;
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return CA_STATUS_OK;
-}
-
-void CAArduoinoCheckServerData()
-{
- gRcvAction.check();
-}
-
-CAResult_t CAStopMulticastServer()
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- // terminate server thread
- // Stop thread if both server stopped
- if (gUnicastSocket == 0)
- {
- gRcvAction.disable();
- gServerRunning = false;
- }
-
- close(gMulticastSocket);
- gMulticastSocket = 0;
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return CA_STATUS_OK;
-}
-
-uint32_t CAEthernetSendData(const char *remoteIpAddress, const int16_t port, const char *buf,
- uint32_t bufLen,
- int16_t isMulticast)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- if(!isMulticast && 0 == gUnicastPort)
- {
- OIC_LOG(ERROR, MOD_NAME, "UnicastPort 0");
- return 0;
- }
-
- int32_t socketID = 0;
- if (isMulticast)
- {
- if (CAArduinoInitMulticastUdpSocket(remoteIpAddress, &port, &gUnicastPort, &socketID) != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, MOD_NAME, "multicast");
- return 0;
- }
- }
- else
- {
- if(0 == gUnicastSocket)
- {
- if (CAArduinoInitUdpSocket((int16_t *)&port, &socketID) != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, MOD_NAME, "unicast");
- return 0;
- }
- }
- else
- {
- socketID = gUnicastSocket;
- }
- }
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return CAArduinoSendData(socketID, (uint8_t *)buf, bufLen, remoteIpAddress, port);
-}
-
-/// Send data to requested end-point using UDP socket
-uint32_t CAArduinoSendData(int32_t sockFd, const uint8_t *buf, uint32_t bufLen,
- const char *ipAddress,
- int32_t port)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- uint32_t ret;
- VERIFY_NON_NULL_RET(buf, MOD_NAME, "buffer", 0);
- VERIFY_NON_NULL_RET(ipAddress, MOD_NAME, "address", 0);
-
- uint8_t ipAddr[4] = { 0 };
- uint16_t parsedPort = 0;
- if (!CAParseIPv4AddressLocal((unsigned char *) ipAddress, ipAddr, &parsedPort))
- {
- OIC_LOG(ERROR, MOD_NAME, "failed");
- return 0;
- }
-
- ret = sendto(sockFd, buf, bufLen, (uint8_t *)ipAddr, port);
- delay(10);
- if(gUnicastSocket != sockFd)
- {
- close(sockFd);
- }
-
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return ret;
-}
-
-void CACheckData()
-{
- void *data = OICMalloc(COAP_MAX_PDU_SIZE);
- memset(data, 0, COAP_MAX_PDU_SIZE);
- int32_t dataLen = 0;
- uint8_t senderAddr[4] = { 0 };
- char addr[IPNAMESIZE] = {0};
- uint16_t senderPort = 0;
-
- if (gUnicastSocket)
- {
- dataLen = CAArduinoRecvData(gUnicastSocket, (uint8_t *)data, COAP_MAX_PDU_SIZE, senderAddr,
- &senderPort);
- if (dataLen < 0)
- {
- OIC_LOG(ERROR, MOD_NAME, "unicast");
- CAStopUnicastServer();
- }
- else if (dataLen > 0)
- {
- OIC_LOG(DEBUG, MOD_NAME, "unicast data rcvd");
- sprintf(addr, "%d.%d.%d.%d", senderAddr[0], senderAddr[1], senderAddr[2], senderAddr[3]);
- CANotifyCallback(data, dataLen, addr, senderPort);
- }
- }
-
- if (gMulticastSocket)
- {
- dataLen = CAArduinoRecvData(gMulticastSocket, (uint8_t *)data, COAP_MAX_PDU_SIZE, senderAddr,
- &senderPort);
- if (dataLen < 0)
- {
- OIC_LOG(ERROR, MOD_NAME, "multicast");
- CAStopMulticastServer();
- }
- else if (dataLen > 0)
- {
- OIC_LOG(DEBUG, MOD_NAME, "multicast data recvd");
- sprintf(addr, "%d.%d.%d.%d", senderAddr[0], senderAddr[1], senderAddr[2], senderAddr[3]);
- CANotifyCallback(data, dataLen, addr, senderPort);
- }
- }
- OICFree(data);
-}
-
-void CANotifyCallback(void *data, int32_t dataLen, const char *senderIp, int32_t senderPort)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- if (gNetworkPacketCallback)
- {
- CARemoteEndpoint_t endPoint;
- endPoint.resourceUri = NULL; // will be filled by upper layer
- endPoint.connectivityType = CA_ETHERNET;
- strncpy(endPoint.addressInfo.IP.ipAddress, senderIp, strlen(senderIp));
- endPoint.addressInfo.IP.port = senderPort;
- gNetworkPacketCallback(&endPoint, data, dataLen);
- }
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
-}
-
-/// Retrieve any available data from UDP socket. This is a non-blocking call.
-int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen, uint8_t *senderAddr,
- uint16_t *senderPort)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- /**Bug : When there are multiple UDP packets in Wiznet buffer, W5100.getRXReceivedSize
- * will not return correct length of the first packet.
- * Fix : Use the patch provided for arduino/libraries/Ethernet/utility/socket.cpp
- */
- VERIFY_NON_NULL_RET(buf, MOD_NAME, "buffer", 0);
- VERIFY_NON_NULL_RET(senderAddr, MOD_NAME, "address", 0);
- VERIFY_NON_NULL_RET(senderPort, MOD_NAME, "port", 0);
- int32_t ret = 0;
- uint16_t recvLen = W5100.getRXReceivedSize(sockFd);
- if (recvLen == 0)
- {
- OIC_LOG_V(DEBUG, MOD_NAME, "rcvd %d", recvLen);
- return recvLen;
- }
-
- // Read available data.
- ret = recvfrom(sockFd, buf, bufLen, senderAddr, senderPort);
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return ret;
-}
-
-void CASetEthernetNetworkPacketCallback(CANetworkPacketReceivedCallback callback)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- gNetworkPacketCallback = callback;
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
-}
-
int16_t CAParseIPv4AddressLocal(unsigned char *ipAddrStr, uint8_t *ipAddr, uint16_t *port)
{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
size_t index = 0;
unsigned char *itr;
uint8_t dotCount = 0;
{
return 1;
}
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
return 0;
}
+
+
*
******************************************************************/
-#ifndef _ETHERNET_ADAPTER_ARDUINO_H_
-#define _ETHERNET_ADAPTER_ARDUINO_H_
+/**
+ * @file caethernetadapterutils.h
+ * @brief This file provides APIs ethernet client/server/network monitor modules
+ */
+
+#ifndef _CA_ETHERNET_ADAPTER_UTILS_
+#define _CA_ETHERNET_ADAPTER_UTILS_
+#include <Arduino.h>
+#include <Ethernet.h>
+#include <socket.h>
+#include <w5100.h>
+#include <EthernetUdp.h>
+#include <IPAddress.h>
+
+#include "logger.h"
+#include "cacommon.h"
#include "caadapterinterface.h"
+#include "caethernetadapter.h"
+#include "caadapterutils.h"
#ifdef __cplusplus
-extern "C" {
+extern "C"
+{
#endif
-CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port);
-
-// Retrieves the IP address assigned to Arduino Ethernet shield
-CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen);
-
CAResult_t CAArduinoInitUdpSocket(int16_t *port, int32_t *socketID);
CAResult_t CAArduinoInitMulticastUdpSocket(const char *mcastAddress, const int16_t *mport,
const int16_t *lport, int32_t *socketID);
-/**
- * @brief API to start multicast server.
- * @param mcastAddress - IP address to join multicast group.
- * @param localAddress - Local Unicast IP address to bind the socket.
- * @param port - multicast port number where socket will listen for incoming request.
- * @return - Error Code
- */
-CAResult_t CAStartMulticastServer(const char *mcastAddress, const char *localAddress,
- const int16_t *port);
-
-CAResult_t CAStopUnicastServer();
-
-void CAArduoinoCheckServerData();
-
-CAResult_t CAStopMulticastServer();
-
-uint32_t CAEthernetSendData(const char *remoteIpAddress, const int16_t port, const char *buf,
- uint32_t bufLen,
- int16_t isMulticast);
-
-/// Send data to requested end-point using UDP socket
-uint32_t CAArduinoSendData(int32_t sockFd, const uint8_t *buf, uint32_t bufLen,
- const char *ipAddress,
- int32_t port);
-
-void CACheckData();
-
-void CANotifyCallback(void *data, int32_t dataLen, const char *senderIp, int32_t senderPort);
-
-/// Retrieve any available data from UDP socket. This is a non-blocking call.
-int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen, uint8_t *senderAddr,
- uint16_t *senderPort);
-
-void CASetEthernetNetworkPacketCallback(CANetworkPacketReceivedCallback callback);
-
int16_t CAParseIPv4AddressLocal(unsigned char *ipAddrStr, uint8_t *ipAddr, uint16_t *port);
#ifdef __cplusplus
}
-#endif // __cplusplus
-
#endif
+#endif //_CA_ETHERNET_ADAPTER_UTILS_
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 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.
+*
+******************************************************************/
+#include "caethernetinterface.h"
+
+#include <Arduino.h>
+#include <Ethernet.h>
+#include <socket.h>
+#include <w5100.h>
+#include <EthernetUdp.h>
+#include <IPAddress.h>
+#include <TimedAction.h>
+
+#include "logger.h"
+#include "cacommon.h"
+#include "caadapterinterface.h"
+#include "caethernetadapter.h"
+#include "caethernetadapterutils.h"
+#include "caadapterutils.h"
+#include "oic_malloc.h"
+
+/// This is the max buffer size between Arduino and WiFi Shield
+#define ARDUINO_ETHERNET_SPI_RECV_BUFFERSIZE (64)
+
+#define MOD_NAME "EC"
+
+static int32_t gSockID = 0;
+
+/**
+ * @var gUnicastPort
+ * @brief Unicast Port
+ */
+static int16_t gUnicastPort = 0;
+
+void CAEthernetSetUnicastSocket(const int32_t socketID)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ if (0 < socketID)
+ {
+ gSockID = socketID;
+ return;
+ }
+
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return;
+}
+
+void CAEthernetSetUnicastPort(const int32_t port)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ if (0 < port)
+ {
+ gUnicastPort = port;
+ return;
+ }
+
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return;
+}
+
+uint32_t CAEthernetSendData(const char *remoteAddress, const int16_t port,
+ const char *buf, const uint32_t bufLen, bool isMulticast)
+{
+ if (!isMulticast && 0 == gUnicastPort)
+ {
+ OIC_LOG(ERROR, MOD_NAME, "Failed");
+ return 0;
+ }
+
+ int32_t socketID = 0;
+ if (isMulticast)
+ {
+ if (CAArduinoInitMulticastUdpSocket(remoteAddress, &port, &gUnicastPort, &socketID) != CA_STATUS_OK)
+ {
+ OIC_LOG(ERROR, MOD_NAME, "multicast");
+ return 0;
+ }
+ OIC_LOG_V(DEBUG, MOD_NAME, "MPORT:%d", port);
+ OIC_LOG_V(DEBUG, MOD_NAME, "LPORT:%d", gUnicastPort);
+ OIC_LOG_V(DEBUG, MOD_NAME, "SOCKET ID:%d", socketID);
+ }
+ else
+ {
+ if (0 == gSockID)
+ {
+ if (CAArduinoInitUdpSocket((int16_t *)&port, &socketID) != CA_STATUS_OK)
+ {
+ OIC_LOG(ERROR, MOD_NAME, "unicast");
+ return 0;
+ }
+ }
+ else
+ {
+ socketID = gSockID;
+ }
+ }
+
+ uint32_t ret;
+ VERIFY_NON_NULL(buf, MOD_NAME, "buf");
+ VERIFY_NON_NULL(remoteAddress, MOD_NAME, "address");
+
+ uint8_t ipAddr[4] = { 0 };
+ uint16_t parsedPort = 0;
+ if (!CAParseIPv4AddressLocal((unsigned char *) remoteAddress, ipAddr, &parsedPort))
+ {
+ OIC_LOG(ERROR, MOD_NAME, "failed");
+ return 0;
+ }
+
+ ret = sendto(socketID, (const uint8_t *)buf, (uint16_t)bufLen, (uint8_t *)ipAddr, port);
+ delay(10);
+ if (gSockID != socketID)
+ {
+ close(socketID);
+ }
+
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return ret;
+}
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 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.
+*
+******************************************************************/
+
+#include "caethernetinterface.h"
+
+#include <Arduino.h>
+#include <Ethernet.h>
+#include <socket.h>
+#include <w5100.h>
+#include <EthernetUdp.h>
+#include <IPAddress.h>
+#include "logger.h"
+#include "caadapterutils.h"
+#include "caethernetadapter.h"
+
+#define ETHERNET_MONITOR_TAG "ETHERNET_MONITOR"
+
+CAResult_t CAEthernetInitializeNetworkMonitor(void)
+{
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStartNetworkMonitor(void)
+{
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress)
+{
+ return CA_STATUS_OK;
+}
+
+bool CAEthernetIsConnected(void)
+{
+ return CA_TRUE;
+}
+
+void CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateChangeCallback callback)
+{
+ return;
+}
+
+CAResult_t CAEthernetStopNetworkMonitor(void)
+{
+ return CA_STATUS_OK;
+}
+
+void CAEthernetTerminateNetworkMonitor(void)
+{
+ return;
+}
\ No newline at end of file
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 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.
+*
+******************************************************************/
+
+#include "caethernetinterface.h"
+
+#include <Arduino.h>
+#include <Ethernet.h>
+#include <socket.h>
+#include <w5100.h>
+#include <EthernetUdp.h>
+#include <IPAddress.h>
+#include <TimedAction.h>
+
+#include "logger.h"
+#include "cacommon.h"
+#include "cainterface.h"
+#include "caadapterinterface.h"
+#include "caethernetadapter.h"
+#include "caethernetadapterutils.h"
+#include "caadapterutils.h"
+#include "oic_malloc.h"
+
+#define COAP_MAX_PDU_SIZE 320
+#define MOD_NAME "ES"
+
+// Length of the IP address decimal notation string
+#define IPNAMESIZE (16)
+
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, int32_t *serverFD);
+static int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen,
+ uint8_t *senderAddr, uint16_t *senderPort);
+static CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen);
+static void CAArduinoCheckData();
+void CAPacketReceivedCallback(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength);
+
+static CAEthernetPacketReceivedCallback gPacketReceivedCallback = NULL;
+static int32_t gUnicastSocket = 0;
+static int32_t gMulticastSocket = 0;
+static bool gServerRunning = false;
+static TimedAction gRcvAction = TimedAction(3000, CAArduinoCheckData);
+
+/**
+ * @var gUnicastPort
+ * @brief Unicast Port
+ */
+int16_t gUnicastPort = 0;
+
+CAResult_t CAEthernetInitializeServer(void)
+{
+ return CA_STATUS_OK;
+}
+
+void CAEthernetTerminateServer(void)
+{
+ return;
+}
+
+CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int *port, int32_t *serverID)
+{
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, int32_t *serverFD)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ VERIFY_NON_NULL(port, MOD_NAME, "port");
+
+ // Note: ****Update the MAC address here with your shield's MAC address****
+ uint8_t ETHERNET_MAC[] = {0x90, 0xA2, 0xDA, 0x0E, 0xC4, 0x05};
+ uint8_t error = Ethernet.begin(ETHERNET_MAC);
+ if (error == 0)
+ {
+ OIC_LOG_V(ERROR, MOD_NAME, "FAILED:%d", error);
+ return CA_STATUS_FAILED;
+ }
+ OIC_LOG(DEBUG, MOD_NAME, "success");
+
+ uint8_t rawIPAddr[4];
+ char address[16];
+ W5100.getIPAddress(rawIPAddr);
+ sprintf(address, "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
+ OIC_LOG_V(DEBUG, MOD_NAME, "address:%s", address);
+
+ //if (CAArduinoInitUdpSocket(port, serverFD) != CA_STATUS_OK)
+ if (CAArduinoInitUdpSocket(port, serverFD) != CA_STATUS_OK)
+ {
+ OIC_LOG(DEBUG, MOD_NAME, "failed");
+ return CA_STATUS_FAILED;
+ }
+
+ gUnicastPort = *port;
+ gUnicastSocket = *serverFD;
+ OIC_LOG_V(DEBUG, MOD_NAME, "gUnicastPort: %d", gUnicastPort);
+ OIC_LOG_V(DEBUG, MOD_NAME, "gUnicastSocket: %d", gUnicastSocket);
+
+ // start thread to monitor socket here
+ if (!gServerRunning)
+ {
+ gRcvAction.enable();
+ gServerRunning = true;
+ }
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
+ const int16_t multicastPort, int32_t *serverFD)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ if (CAArduinoInitMulticastUdpSocket(multicastAddress, &multicastPort, &multicastPort,
+ serverFD) != CA_STATUS_OK)
+ {
+ OIC_LOG(DEBUG, MOD_NAME, "failed");
+ return CA_STATUS_FAILED;
+ }
+
+ gMulticastSocket = *serverFD;
+ OIC_LOG_V(DEBUG, MOD_NAME, "gMulticastPort: %d", multicastPort);
+ OIC_LOG_V(DEBUG, MOD_NAME, "gMulticastSocket: %d", gMulticastSocket);
+ // start thread to monitor socket here
+ if (!gServerRunning)
+ {
+ gRcvAction.enable();
+ gServerRunning = true;
+ }
+
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStopUnicastServer()
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ // terminate server thread
+ // Stop thread if both server stopped
+ if (gMulticastSocket == 0)
+ {
+ gRcvAction.disable();
+ gServerRunning = false;
+ }
+
+ close(gUnicastSocket);
+ gUnicastSocket = 0;
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStopMulticastServer()
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ // terminate server thread
+ // Stop thread if both server stopped
+ if (gUnicastSocket == 0)
+ {
+ gRcvAction.disable();
+ gServerRunning = false;
+ }
+
+ close(gMulticastSocket);
+ gMulticastSocket = 0;
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAPacketReceivedCallback(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ if (gPacketReceivedCallback)
+ {
+ gPacketReceivedCallback(ipAddress, port, data, dataLength);
+ OIC_LOG(DEBUG, MOD_NAME, "NNP");
+ }
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+}
+
+void CAArduinoCheckData()
+{
+ void *data = malloc(COAP_MAX_PDU_SIZE);
+ memset(data, 0, COAP_MAX_PDU_SIZE);
+ int32_t dataLen = 0;
+ uint8_t senderAddr[4] = { 0 };
+ char addr[IPNAMESIZE] = {0};
+ uint16_t senderPort = 0;
+
+ if (gUnicastSocket)
+ {
+ dataLen = CAArduinoRecvData(gUnicastSocket, (uint8_t *)data, COAP_MAX_PDU_SIZE, senderAddr,
+ &senderPort);
+ if (dataLen < 0)
+ {
+ OIC_LOG(ERROR, MOD_NAME, "FAILED");
+ CAEthernetStopUnicastServer();
+ }
+ else if (dataLen > 0)
+ {
+ OIC_LOG(DEBUG, MOD_NAME, "Data recvd on unicast server");
+ sprintf(addr, "%d.%d.%d.%d", senderAddr[0], senderAddr[1], senderAddr[2], senderAddr[3]);
+ CAPacketReceivedCallback(addr, senderPort, data, dataLen);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, MOD_NAME, "No data");
+ }
+ }
+
+ if (gMulticastSocket)
+ {
+ dataLen = CAArduinoRecvData(gMulticastSocket, (uint8_t *)data, COAP_MAX_PDU_SIZE, senderAddr,
+ &senderPort);
+ if (dataLen < 0)
+ {
+ CAEthernetStopMulticastServer();
+ }
+ else if (dataLen > 0)
+ {
+ OIC_LOG(DEBUG, MOD_NAME, "multicast data recvd");
+ sprintf(addr, "%d.%d.%d.%d", senderAddr[0], senderAddr[1], senderAddr[2], senderAddr[3]);
+ CAPacketReceivedCallback(addr, senderPort, data, dataLen);
+ }
+ }
+ OICFree(data);
+}
+
+/// Retrieve any available data from UDP socket. This is a non-blocking call.
+int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen, uint8_t *senderAddr,
+ uint16_t *senderPort)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ /**Bug : When there are multiple UDP packets in Wiznet buffer, W5100.getRXReceivedSize
+ * will not return correct length of the first packet.
+ * Fix : Use the patch provided for arduino/libraries/Ethernet/utility/socket.cpp
+ */
+
+ VERIFY_NON_NULL(buf, MOD_NAME, "Invalid buf");
+ VERIFY_NON_NULL(senderAddr, MOD_NAME, "Invalid senderAddr");
+ VERIFY_NON_NULL(senderPort, MOD_NAME, "Invalid senderPort");
+ int32_t ret = 0;
+ uint16_t recvLen = W5100.getRXReceivedSize(sockFd);
+ if (recvLen == 0)
+ {
+ OIC_LOG_V(DEBUG, MOD_NAME, "rcvd %d", recvLen);
+ return recvLen;
+ }
+
+ // Read available data.
+ ret = recvfrom(sockFd, buf, bufLen, senderAddr, senderPort);
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return ret;
+}
+
+void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ gPacketReceivedCallback = callback;
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+}
+
+void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback)
+{
+ // TODO
+}
+
+void CAEthernetPullData()
+{
+ gRcvAction.check();
+}
+
+/// Retrieves the IP address assigned to Arduino Ethernet shield
+CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ VERIFY_NON_NULL(address, MOD_NAME, "address");
+
+ //TODO : Fix this for scenarios when this API is invoked when device is not connected
+ uint8_t rawIPAddr[4];
+ if (addrLen < IPNAMESIZE)
+ {
+ OIC_LOG(ERROR, MOD_NAME, "Invalid addrLen");
+ return CA_STATUS_FAILED;
+ }
+
+ W5100.getIPAddress(rawIPAddr);
+ sprintf(address, "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
+
+ OIC_LOG_V(DEBUG, MOD_NAME, "address:%s", address);
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return CA_STATUS_OK;
+}
static CAResult_t CAEthernetInitializeQueueHandles();
static void CAEthernetDeinitializeQueueHandles();
static void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
- const CANetworkStatus_t status);
+ const CANetworkStatus_t status);
static void CAEthernetConnectionStateCB(const char *ipAddress,
- const CANetworkStatus_t status);
+ const CANetworkStatus_t status);
static void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
- const void *data, const uint32_t dataLength);
+ const void *data, const uint32_t dataLength);
static CAResult_t CAEthernetStopServers();
static void CAEthernetSendDataThread(void *threadData);
static CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength);
+ uint32_t dataLength);
void CAFreeEthernetData(CAEthernetData *ethernetData);
CAEthernetSendDataThread))
{
OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Initialize send queue thread");
+ OICFree(gSendQueueHandle);
+ gSendQueueHandle = NULL;
return CA_STATUS_FAILED;
}
}
void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
- const CANetworkStatus_t status)
+ const CANetworkStatus_t status)
{
- CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_ETHERNET, address, "Ethernet");
+ CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_ETHERNET, address);
if (!localEndpoint)
{
OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
}
void CAEthernetConnectionStateCB(const char *ipAddress,
- const CANetworkStatus_t status)
+ const CANetworkStatus_t status)
{
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
/* Start Unicast server if requested earlier */
if (gStartUnicastServerRequested)
{
- ret = CAEthernetStartUnicastServer("0.0.0.0", &port, false, &serverFd);
+ ret = CAEthernetStartUnicastServer("0.0.0.0", &port, false, false, &serverFd);
if (CA_STATUS_OK == ret)
{
OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Unicast server started on %d port", port);
int16_t multicastPort = CA_MCAST_PORT;
int32_t multicastFd = 0;
ret = CAEthernetStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort,
- &multicastFd);
+ &multicastFd);
if (CA_STATUS_OK == ret)
{
OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Multicast server started on %d port",
- multicastPort);
+ multicastPort);
gIsMulticastServerStarted = true;
}
else
}
void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
- const void *data, const uint32_t dataLength)
+ const void *data, const uint32_t dataLength)
{
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
}
CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback networkPacketCallback,
- CANetworkChangeCallback netCallback, u_thread_pool_t handle)
+ CANetworkPacketReceivedCallback networkPacketCallback,
+ CANetworkChangeCallback netCallback, u_thread_pool_t handle)
{
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
VERIFY_NON_NULL(registerCallback, ETHERNET_ADAPTER_TAG, "registerCallback");
int16_t unicastPort = CA_PORT;
int32_t serverFd = 0;
// Address is hardcoded as we are using Single Interface
- ret = CAEthernetStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
+ ret = CAEthernetStartUnicastServer("0.0.0.0", &unicastPort, false, false, &serverFd);
if (CA_STATUS_OK == ret)
{
OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
}
uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength)
+ uint32_t dataLength)
{
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
}
// Create local endpoint using util function
- (*info) = CAAdapterCreateLocalEndpoint(CA_ETHERNET, ipAddress, ifcName);
+ (*info) = CAAdapterCreateLocalEndpoint(CA_ETHERNET, ipAddress);
if (NULL == (*info))
{
OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to create Local Endpoint!",
{
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Send Unicast Data is called");
CAEthernetSendData(ethernetData->remoteEndpoint->addressInfo.IP.ipAddress,
- ethernetData->remoteEndpoint->addressInfo.IP.port, ethernetData->data,
- ethernetData->dataLen, false);
+ ethernetData->remoteEndpoint->addressInfo.IP.port, ethernetData->data,
+ ethernetData->dataLen, false, false);
}
else
{
OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Send Multicast Data is called");
- CAEthernetSendData(CA_MULTICAST_IP, CA_MCAST_PORT, ethernetData->data, ethernetData->dataLen, true);
+ CAEthernetSendData(CA_MULTICAST_IP, CA_MCAST_PORT, ethernetData->data, ethernetData->dataLen, true
+ , false);
}
//Free Ethernet data
}
CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLength)
+ uint32_t dataLength)
{
CAEthernetData *ethernetData = (CAEthernetData *) OICMalloc(sizeof(CAEthernetData));
if (!ethernetData)
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+
+#include "caethernetadapter.h"
+
+#include <stdio.h>
+#include <stdint.h>
+#include "caadapterutils.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "caethernetinterface.h"
+
+/**
+ * @def ETHERNET_ADAPTER_TAG
+ * @brief Logging tag for module name
+ */
+#define ETHERNET_ADAPTER_TAG "EA"
+
+/**
+ * @def CA_PORT
+ * @brief Port to listen for incoming data
+ */
+#define CA_PORT 5283
+
+#define CA_MCAST_PORT 5298
+
+/**
+ * @def CA_MULTICAST_IP
+ * @brief Multicast IP Address
+ */
+#define CA_MULTICAST_IP "224.0.1.187"
+
+/* Skip Queue */
+/**
+ * @var gNetworkPacketCallback
+ * @brief Network Packet Received Callback to CA
+ */
+static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
+
+/**
+ * @var gNetworkChangeCb
+ * @brief Network Changed Callback to CA
+ */
+
+CANetworkChangeCallback gNetworkChangeCallback = NULL;
+
+/**
+ * @var gIsMulticastServerStarted
+ * @brief Flag to check if multicast server is started
+ */
+static int gIsMulticastServerStarted = 0;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartUnicastServerRequested = false;
+
+/**
+ * @var gUnicastServerport
+ * @brief port number on which unicast server is running.
+ */
+static int16_t gUnicastServerport = 0;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartMulticastServerRequested = false;
+
+
+static void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
+ const CANetworkStatus_t status);
+static void CAEthernetConnectionStateCB(const char *ipAddress,
+ const CANetworkStatus_t status);
+static void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength);
+static CAResult_t CAEthernetStopServers();
+
+void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
+ const CANetworkStatus_t status)
+{
+ CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_ETHERNET, address);
+ if (!localEndpoint)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
+ return;
+ }
+ localEndpoint->addressInfo.IP.port = port;
+
+ if (NULL != gNetworkChangeCallback)
+ {
+ gNetworkChangeCallback(localEndpoint, status);
+ }
+
+ CAAdapterFreeLocalEndpoint(localEndpoint);
+}
+
+void CAEthernetConnectionStateCB(const char *ipAddress,
+ const CANetworkStatus_t status)
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+ CAResult_t ret = CA_STATUS_FAILED;
+ /* If Ethernet is connected, then get the latest IP from the Ethernet Interface
+ * and start unicast and multicast servers if requested earlier */
+ if (CA_INTERFACE_UP == status)
+ {
+ char *ipAddress = NULL;
+ int16_t port = CA_PORT;
+ int32_t serverFd = -1;
+ /* Start Unicast server if requested earlier */
+ if (gStartUnicastServerRequested)
+ {
+ ret = CAEthernetStartUnicastServer("0.0.0.0", &port, false, &serverFd);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Unicast server started on %d port", port);
+ CAEthernetSetUnicastSocket(serverFd);
+ CAEthernetSetUnicastPort(port);
+ gUnicastServerport = port;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to start Unicast server [%d]", ret);
+ }
+ }
+
+ /* Start Multicast server if requested earlier */
+ if (gStartMulticastServerRequested)
+ {
+ int16_t multicastPort = CA_MCAST_PORT;
+ ret = CAEthernetStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFd);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Multicast server started on %d port", multicastPort);
+ gIsMulticastServerStarted = true;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to start Multicast server [%d]", ret);
+ }
+ }
+
+ /* Notify network change to CA */
+ CAEthernetNotifyNetworkChange(ipAddress, port, status);
+ OICFree(ipAddress);
+ }
+ else
+ {
+ CAEthernetNotifyNetworkChange("", 0, status);
+ /* Stop both Unicast and Multicast servers */
+ ret = CAEthernetStopServers();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
+ return;
+ }
+ }
+
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+}
+
+void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength)
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+ OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
+
+ /* CA is freeing this memory */
+ CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_ETHERNET, ipAddress, NULL);
+ if (NULL == endPoint)
+ {
+ OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
+ return;
+ }
+ endPoint->addressInfo.IP.port = port;
+
+ void *buf = OICMalloc(dataLength + 1);
+ if (NULL == buf)
+ {
+ OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
+ CAAdapterFreeRemoteEndpoint(endPoint);
+ return;
+ }
+ memcpy(buf, data, dataLength);
+ memset(buf + dataLength, 0, 1);
+ if (gNetworkPacketCallback)
+ {
+ gNetworkPacketCallback(endPoint, buf, dataLength);
+ }
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback networkPacketCallback,
+ CANetworkChangeCallback netCallback)
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+ VERIFY_NON_NULL(registerCallback, ETHERNET_ADAPTER_TAG, "registerCallback");
+ VERIFY_NON_NULL(networkPacketCallback, ETHERNET_ADAPTER_TAG, "networkPacketCallback");
+ VERIFY_NON_NULL(netCallback, ETHERNET_ADAPTER_TAG, "netCallback");
+
+ gNetworkChangeCallback = netCallback;
+ gNetworkPacketCallback = networkPacketCallback;
+
+ CAResult_t ret = CAEthernetInitializeNetworkMonitor();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
+ return ret;
+ }
+ CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateCB);
+
+ ret = CAEthernetInitializeServer();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
+ CATerminateEthernet();
+ return ret;
+ }
+ CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCB);
+
+ CAConnectivityHandler_t EthernetHandler;
+ EthernetHandler.startAdapter = CAStartEthernet;
+ EthernetHandler.startListenServer = CAStartEthernetListeningServer;
+ EthernetHandler.startDiscoverServer = CAStartEthernetDiscoveryServer;
+ EthernetHandler.sendData = CASendEthernetUnicastData;
+ EthernetHandler.sendDataToAll = CASendEthernetMulticastData;
+ EthernetHandler.GetnetInfo = CAGetEthernetInterfaceInformation;
+ EthernetHandler.readData = CAReadEthernetData;
+ EthernetHandler.stopAdapter = CAStopEthernet;
+ EthernetHandler.terminate = CATerminateEthernet;
+ registerCallback(EthernetHandler, CA_ETHERNET);
+
+ OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "IntializeEthernet is Success");
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAStartEthernet()
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+ /* Start monitoring Ethernet network */
+ CAResult_t ret = CAEthernetStartNetworkMonitor();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Start n/w monitor");
+ }
+
+ gStartUnicastServerRequested = true;
+ bool retVal = CAEthernetIsConnected();
+ if (false == retVal)
+ {
+ OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Ethernet is not Connected");
+ return ret;
+ }
+
+ int16_t unicastPort = CA_PORT;
+ int32_t serverFd = 0;
+ // Address is hardcoded as we are using Single Interface
+ ret = CAEthernetStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
+ CAEthernetSetUnicastSocket(serverFd);
+ CAEthernetSetUnicastPort(unicastPort);
+ gUnicastServerport = unicastPort;
+ }
+
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return ret;
+}
+
+CAResult_t CAStartEthernetListeningServer()
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+ CAResult_t ret = CA_STATUS_OK;
+ int16_t multicastPort = CA_MCAST_PORT;
+ int32_t serverFD = 1;
+ if (gIsMulticastServerStarted == true)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Already Started!");
+ return CA_SERVER_STARTED_ALREADY;
+ }
+
+ gStartMulticastServerRequested = true;
+ bool retVal = CAEthernetIsConnected();
+ if (false == retVal)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG,
+ "Failed to Start Multicast Server, Ethernet not Connected");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ ret = CAEthernetStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFD);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "Multicast Server is Started Successfully");
+ gIsMulticastServerStarted = true;
+ }
+
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return ret;
+}
+
+CAResult_t CAStartEthernetDiscoveryServer()
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+ /* Both listening and discovery server are same */
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return CAStartEthernetListeningServer();
+}
+
+uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength)
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+ uint32_t dataSize = 0;
+ VERIFY_NON_NULL_RET(remoteEndpoint, ETHERNET_ADAPTER_TAG, "remoteEndpoint", dataSize);
+ VERIFY_NON_NULL_RET(data, ETHERNET_ADAPTER_TAG, "data", dataSize);
+ if (dataLength == 0)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Invalid Data Length");
+ return dataSize;
+ }
+
+ CAEthernetSendData(remoteEndpoint->addressInfo.IP.ipAddress,
+ remoteEndpoint->addressInfo.IP.port, data, dataLength, false);
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return dataLength;
+}
+
+uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLength)
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+ uint32_t dataSize = 0;
+ VERIFY_NON_NULL_RET(data, ETHERNET_ADAPTER_TAG, "data", dataSize);
+ if (dataLength == 0)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Invalid Data Length");
+ return dataSize;
+ }
+
+ CAEthernetSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, true);
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return dataLength;
+}
+
+CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+ VERIFY_NON_NULL(info, ETHERNET_ADAPTER_TAG, "info");
+ VERIFY_NON_NULL(size, ETHERNET_ADAPTER_TAG, "size");
+
+ bool retVal = CAEthernetIsConnected();
+ if (false == retVal)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG,
+ "Failed to get interface address, Ethernet not Connected", CA_ADAPTER_NOT_ENABLED);
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ char *ipAddress = NULL;
+ char *ifcName = NULL;
+ CAResult_t ret = CAEthernetGetInterfaceInfo(&ipAddress, &ifcName);
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+ return ret;
+ }
+
+ // Create local endpoint using util function
+ (*info) = CAAdapterCreateLocalEndpoint(CA_ETHERNET, ipAddress);
+ if (NULL == (*info))
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to create Local Endpoint!",
+ CA_MEMORY_ALLOC_FAILED);
+ OICFree(ipAddress);
+ OICFree(ifcName);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ (*info)->addressInfo.IP.port = gUnicastServerport;
+ (*size) = 1;
+
+ OICFree(ipAddress);
+ OICFree(ifcName);
+
+ OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "GetEthernetInterfaceInformation success");
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAReadEthernetData()
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+ CAEthernetPullData();
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStopServers()
+{
+ CAResult_t result = CAEthernetStopUnicastServer();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
+ return result;
+ }
+ CAEthernetSetUnicastSocket(-1);
+ CAEthernetSetUnicastPort(-1);
+ gUnicastServerport = -1;
+
+ result = CAEthernetStopMulticastServer();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
+ return result;
+ }
+ gIsMulticastServerStarted = false;
+
+ return result;
+}
+
+CAResult_t CAStopEthernet()
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+ gStartUnicastServerRequested = false;
+ gStartMulticastServerRequested = false;
+ CAEthernetStopNetworkMonitor();
+ CAResult_t result = CAEthernetStopServers();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
+ }
+
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return result;
+}
+
+void CATerminateEthernet()
+{
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+ CAEthernetSetConnectionStateChangeCallback(NULL);
+ CAEthernetTerminateNetworkMonitor();
+ OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "nw monitor terminated");
+ CAEthernetSetPacketReceiveCallback(NULL);
+ OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "TerminateEthernet Success");
+ OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+ return;
+}
+
}
uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
- const void *data, const uint32_t dataLength, bool isMulticast)
+ const void *data, const uint32_t dataLength,
+ CABool_t isMulticast, CABool_t isSecure)
{
OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "IN");
*/
static void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress);
-static void CANetworkMonitorThread(void* threadData);
+static void CANetworkMonitorThread(void *threadData);
CAResult_t CAEthernetInitializeNetworkMonitor(const u_thread_pool_t threadPool)
{
if (gEthernetInterfaceName && strlen(gEthernetInterfaceName))
{
- *interfaceName = (gEthernetInterfaceName) ? strndup(gEthernetInterfaceName, strlen(gEthernetInterfaceName)) :
- NULL;
+ *interfaceName = (gEthernetInterfaceName) ? strndup(gEthernetInterfaceName,
+ strlen(gEthernetInterfaceName)) :
+ NULL;
}
if (gEthernetIPAddress && strlen(gEthernetIPAddress))
{
*ipAddress = (gEthernetIPAddress) ? strndup(gEthernetIPAddress, strlen(gEthernetIPAddress)) :
- NULL;
+ NULL;
}
u_mutex_unlock(gEthernetNetInfoMutex);
freeifaddrs(ifp);
}
-void CANetworkMonitorThread(void* threadData)
+void CANetworkMonitorThread(void *threadData)
{
while (!gStopNetworkMonitor)
{
}
CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
- const int16_t multicastPort, int32_t *serverFD)
+ const int16_t multicastPort, int32_t *serverFD)
{
OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
}
CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
- const bool forceStart, int32_t *serverFD)
+ const bool forceStart, const bool secured, int32_t *serverFD)
{
OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
return CA_STATUS_OK;
}
-CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD)
+CAResult_t CAEthernetGetUnicastServerInfo(const bool secure, char **ipAddress, int16_t *port,
+ int32_t *serverFD)
{
OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+++ /dev/null
-/******************************************************************
- *
- * Copyright 2014 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.
- *
- ******************************************************************/
-
-#include "cawifiadapter_singlethread.h"
-
-#include <stdio.h>
-#include <stdint.h>
-#include "caadapterutils.h"
-#include "logger.h"
-
-#include "cawifiadapterutils.h"
-
-/**
- * @def WIFI_ETHERNET_ADAPTER_TAG
- * @brief Logging tag for module name
- */
-#define WIFI_ADAPTER_TAG "WIFIADAP"
-
-/**
- * @def CA_PORT
- * @brief Port to listen for incoming data
- */
-#define CA_PORT 5383
-
-#define CA_MCAST_PORT 5683
-
-/**
- * @def CA_MULTICAST_IP
- * @brief Multicast IP Address
- */
-#define CA_MULTICAST_IP "224.0.1.187"
-
-/**
- * @var gNetworkCallback
- * @brief Network callback
- */
-static CANetworkChangeCallback gNetworkCallback = NULL;
-
-/**
- * @var gIsMulticastServerStarted
- * @brief Flag to check if multicast server is started
- */
-static bool gIsMulticastServerStarted = false;
-
-CAResult_t CAWIFIRegisterNetworkNotifications(CANetworkChangeCallback netCallback)
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- gNetworkCallback = netCallback;
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
- CANetworkPacketReceivedCallback networkPacketCallback, CANetworkChangeCallback netCallback)
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
- VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG, "registerCallback");
- VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG, "networkPacketCallback");
- VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "netCallback");
-
- CAConnectivityHandler_t wifiHandler;
- wifiHandler.startAdapter = CAStartWIFI;
- wifiHandler.startListenServer = CAStartWIFIListeningServer;
- wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer;
- wifiHandler.sendData = CASendWIFIUnicastData;
- wifiHandler.sendDataToAll = CASendWIFIMulticastData;
- wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation;
- wifiHandler.readData = CAReadWIFIData;
- wifiHandler.stopAdapter = CAStopWIFI;
- wifiHandler.terminate = CATerminateWIfI;
- registerCallback(wifiHandler, CA_WIFI);
-
- CASetWIFINetworkPacketCallback(networkPacketCallback);
- CAWIFIRegisterNetworkNotifications(netCallback);
-
- OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAStartWIFI()
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
- int16_t unicastPort = CA_PORT;
- CAResult_t ret = CA_STATUS_OK;
-
- /*Address is hardcoded as we are using Single Interface*/
- ret = CAStartUnicastServer("0.0.0.0", &unicastPort);
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return ret;
-}
-
-CAResult_t CAStartWIFIListeningServer()
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- CAResult_t ret = CA_STATUS_OK;
- int16_t multicastPort = CA_MCAST_PORT;
-
- if (gIsMulticastServerStarted == true)
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Server is already Started");
- return CA_SERVER_STARTED_ALREADY;
- }
-
- ret = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort);
- if (ret == CA_STATUS_OK)
- {
- OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
- gIsMulticastServerStarted = true;
- }
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return ret;
-}
-
-CAResult_t CAStartWIFIDiscoveryServer()
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- CAResult_t ret = CA_STATUS_OK;
- int16_t multicastPort = CA_MCAST_PORT;
-
- if (gIsMulticastServerStarted == true)
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Server is already Started");
- return CA_SERVER_STARTED_ALREADY;
- }
-
- ret = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort);
- if (ret == CA_STATUS_OK)
- {
- OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
- gIsMulticastServerStarted = true;
- }
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return ret;
-}
-
-uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
- uint32_t dataLen)
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- uint32_t dataSize = 0;
-
- VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ADAPTER_TAG, "remoteEndpoint",
- dataSize);
- VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
-
- if (dataLen == 0)
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "DataLen is 0");
- return dataSize;
-
- }
-
- dataSize = CAWIFISendData(remoteEndpoint->addressInfo.IP.ipAddress,
- remoteEndpoint->addressInfo.IP.port, data, dataLen, 0);
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return dataSize;
-}
-
-uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
- VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", 0);
-
- uint32_t dataSize = 0;
- if (dataLength == 0)
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "DataLen is 0");
- return 0;
-
- }
- dataSize = CAWIFISendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, 1);
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return dataSize;
-}
-
-CAResult_t CAStartWIFINotifyRecvServers()
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-uint32_t CASendWIFINotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "info");
- char localIpAddress[CA_IPADDR_SIZE];
- int32_t localIpAddressLen = sizeof(localIpAddress);
-
- CAArduinoGetInterfaceAddress(localIpAddress, localIpAddressLen);
- /**
- * Create local endpoint using util function
- */
- (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, localIpAddress, "WiFi");
- if (NULL == (*info))
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
- return CA_MEMORY_ALLOC_FAILED;
- }
-
- (*size) = 1;
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAReadWIFIData()
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
- CAArduoinoCheckServerData();
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAStopWIFI()
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
- CAResult_t result = CA_STATUS_FAILED;
- result = CAStopUnicastServer();
- if (result != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Error");
- return result;
- }
-
- result = CAStopMulticastServer();
- if (result != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Error");
- return result;
- }
- else
- {
- gIsMulticastServerStarted = false;
- }
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return CA_STATUS_OK;
-}
-
-void CATerminateWIfI()
-{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
- CASetWIFINetworkPacketCallback(NULL);
- CAResult_t result = CAWIFIRegisterNetworkNotifications(NULL);
- if (result != CA_STATUS_OK)
- {
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Error");
- }
-
- OIC_LOG(INFO, WIFI_ADAPTER_TAG, "TerminateWifi Success");
-
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return;
-}
+++ /dev/null
-/******************************************************************
-*
-* Copyright 2014 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.
-*
-******************************************************************/
-
-#ifndef _WIFI_ADAPTER_ARDUINO_H_
-#define _WIFI_ADAPTER_ARDUINO_H_
-
-#include "caadapterinterface.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-CAResult_t CAStartUnicastServer(const char *localAddress, const int16_t *port);
-
-// Retrieves the IP address assigned to Arduino Ethernet shield
-CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen);
-
-CAResult_t CAArduinoInitUdpSocket(const int16_t *port, int32_t *socketID);
-
-CAResult_t CAArduinoInitMulticastUdpSocket(const char *mcastAddress, const int16_t *port,
- int32_t *socketID);
-
-/**
- * @brief API to start multicast server.
- * @param mcastAddress - IP address to join multicast group.
- * @param localAddress - Local Unicast IP address to bind the socket.
- * @param port - multicast port number where socket will listen for incoming request.
- * @return - Error Code
- */
-CAResult_t CAStartMulticastServer(const char *mcastAddress, const char *localAddress,
- int16_t *port);
-
-CAResult_t CAStopUnicastServer();
-
-void CAArduoinoCheckServerData();
-
-CAResult_t CAStopMulticastServer();
-
-/**
- * @brief API to send data.
- * @param remoteIpAddress - IP address to send wifi data.
- * @param port - port on which remote device will be listening for data.
- * @param buf - data buffer to be sent.
- * @param bufLen - Length of buffer.
- * @param isMulticast - flag to check if it's a multicast send.
- * @return - Error Code
- */
-uint32_t CAWIFISendData(const char *remoteIpAddress, const int16_t port, const char *buf,
- uint32_t bufLen,
- int16_t isMulticast);
-
-/// Send data to requested end-point using UDP socket
-/**
- * @brief API to arduino send data.
- * @param sockFd - socket ID.
- * @param buf - data buffer to be sent.
- * @param bufLen - Length of buffer.
- * @param ipAddress - Ip of remote device.
- * @param port - Port of remote device.
- * @return - Error Code
- */
-uint32_t CAArduinoSendData(int32_t sockFd, const uint8_t *buf, uint32_t bufLen,
- const char *ipAddress,
- int32_t port);
-
-void CACheckData();
-
-void CANotifyCallback(void *data, int32_t dataLen, char *senderIp, int32_t senderPort);
-
-/// Retrieve any available data from UDP socket. This is a non-blocking call.
-/**
- * @brief API to arduino receive data.
- * @param sockFd - socket ID.
- * @param buf - data buffer to read.
- * @param bufLen - Length of buffer.
- * @param senderAddr - Ip of remote device.
- * @param senderPort - Port of remote device.
- * @return - Error Code
- */
-int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen, uint8_t *senderAddr,
- uint16_t *senderPort);
-
-void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback);
-
-int16_t CAParseIPv4AddressLocal(unsigned char *ipAddrStr, uint8_t *ipAddr, uint16_t *port);
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif
-
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 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.
+*
+******************************************************************/
+#include "cawifiinterface.h"
+
+#include <Arduino.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#include <SPI.h>
+#include <utility/server_drv.h>
+#include <utility/wifi_drv.h>
+#include <IPAddress.h>
+#include <TimedAction.h>
+
+#include "logger.h"
+#include "cacommon.h"
+#include "caadapterinterface.h"
+#include "cawifiadapter.h"
+#include "caadapterutils.h"
+
+/// This is the max buffer size between Arduino and WiFi Shield
+#define ARDUINO_WIFI_SPI_RECV_BUFFERSIZE (64)
+
+#define MOD_NAME "WC"
+
+static int16_t CAParseIPv4AddressLocal(unsigned char *ipAddrStr, uint8_t *ipAddr, uint16_t *port);
+
+static int32_t gSockID = 0;
+
+static WiFiUDP Udp;
+
+void CAWiFiSetUnicastSocket(const int32_t socketID)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ if (0 < socketID)
+ {
+ gSockID = socketID;
+ return;
+ }
+
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return;
+}
+
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength, bool isMulticast)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+
+ uint32_t ip;
+ uint16_t rem, send;
+
+ VERIFY_NON_NULL(data, MOD_NAME, "data");
+ VERIFY_NON_NULL(remoteAddress, MOD_NAME, "address");
+
+ int32_t ret = 1;
+ OIC_LOG_V(DEBUG, MOD_NAME, "remoteip: %s", remoteAddress);
+ OIC_LOG_V(DEBUG, MOD_NAME, "sending to port: %d", port);
+ Udp.beginPacket(remoteAddress, port);
+ ret = (int32_t)Udp.write((char *)data);
+ Udp.endPacket();
+ OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ return ret;
+}
+
+int16_t CAParseIPv4AddressLocal(unsigned char *ipAddrStr, uint8_t *ipAddr, uint16_t *port)
+{
+ size_t index = 0;
+ unsigned char *itr;
+ uint8_t dotCount = 0;
+
+ ipAddr[index] = 0;
+ *port = 0;
+ itr = ipAddrStr;
+ if (!isdigit((unsigned char) *ipAddrStr))
+ {
+ return -1;
+ }
+ ipAddrStr = itr;
+
+ while (*ipAddrStr)
+ {
+ if (isdigit((unsigned char) *ipAddrStr))
+ {
+ ipAddr[index] *= 10;
+ ipAddr[index] += *ipAddrStr - '0';
+ }
+ else if ((unsigned char) *ipAddrStr == '.')
+ {
+ index++;
+ dotCount++;
+ ipAddr[index] = 0;
+ }
+ else
+ {
+ break;
+ }
+ ipAddrStr++;
+ }
+ if (*ipAddrStr == ':')
+ {
+ ipAddrStr++;
+ while (*ipAddrStr)
+ {
+ if (isdigit((unsigned char) *ipAddrStr))
+ {
+ *port *= 10;
+ *port += *ipAddrStr - '0';
+ }
+ else
+ {
+ break;
+ }
+ ipAddrStr++;
+ }
+ }
+ if (ipAddr[0] < 255 && ipAddr[1] < 255 && ipAddr[2] < 255 && ipAddr[3] < 255
+ && dotCount == 3)
+ {
+ return 1;
+ }
+ return 0;
+}
+
--- /dev/null
+/******************************************************************
+*
+* Copyright 2014 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.
+*
+******************************************************************/
+
+#include "cawifiinterface.h"
+
+#include <Arduino.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#include <SPI.h>
+#include <utility/server_drv.h>
+#include <utility/wifi_drv.h>
+#include <IPAddress.h>
+#include "logger.h"
+#include "caadapterutils.h"
+#include "cawifiadapter.h"
+
+#define WIFI_MONITOR_TAG "WIFI_MONITOR"
+
+CAResult_t CAWiFiInitializeNetworkMonitor(void)
+{
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStartNetworkMonitor(void)
+{
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
+{
+ return CA_STATUS_OK;
+}
+
+bool CAWiFiIsConnected(void)
+{
+ return CA_TRUE;
+}
+
+void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
+{
+ return;
+}
+
+CAResult_t CAWiFiStopNetworkMonitor(void)
+{
+ return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateNetworkMonitor(void)
+{
+ return;
+}
\ No newline at end of file
*
******************************************************************/
-#include "cawifiadapterutils.h"
+#include "cawifiinterface.h"
#include <Arduino.h>
#include <WiFi.h>
+#include <WiFiUdp.h>
#include <SPI.h>
#include <utility/server_drv.h>
#include <utility/wifi_drv.h>
#include "cacommon.h"
#include "cainterface.h"
#include "caadapterinterface.h"
+#include "cawifiadapter.h"
#include "caadapterutils.h"
#include "oic_malloc.h"
#define COAP_MAX_PDU_SIZE 320
-#define MOD_NAME "WAU"
+#define MOD_NAME "WiFiServer"
-char ssid[] = "network_ssid"; // your network SSID (name)
-char pass[] = "network_pswd"; // your network password
+char ssid[] = "NETGEAR99"; // your network SSID (name)
+char pass[] = "jollysky325"; // your network password
+int16_t status = WL_IDLE_STATUS; // the Wifi radio's status
-int16_t status = WL_IDLE_STATUS; // the Wifi radio's status
-
-/// Length of the IP address decimal notation string
+// Length of the IP address decimal notation string
#define IPNAMESIZE (16)
-/// This is the max buffer size between Arduino and WiFi Shield
-#define ARDUINO_WIFI_SPI_RECV_BUFFERSIZE (64)
// Start offsets based on end of received data buffer
#define WIFI_RECBUF_IPADDR_OFFSET (6)
#define WIFI_RECBUF_PORT_SIZE (WIFI_RECBUF_PORT_OFFSET - 0)
#define WIFI_RECBUF_FOOTER_SIZE (WIFI_RECBUF_IPADDR_SIZE + WIFI_RECBUF_PORT_SIZE)
-static CANetworkPacketReceivedCallback gNetworkPacketCallback;
+static CAResult_t CAArduinoInitUdpSocket(int16_t *port, int32_t *socketID);
+static int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen,
+ uint8_t *senderAddr, uint16_t *senderPort);
+static CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen);
+static void CAArduinoCheckData();
+void CAPacketReceivedCallback(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength);
+
+static CAWiFiPacketReceivedCallback gPacketReceivedCallback = NULL;
static int32_t gUnicastSocket = 0;
static bool gServerRunning = false;
-static TimedAction gRcvAction = TimedAction(3000, CACheckData);
+static TimedAction gRcvAction = TimedAction(3000, CAArduinoCheckData);
static WiFiUDP Udp;
-CAResult_t CAArduinoInitUdpSocket(const int16_t *port, int32_t *socketID)
+CAResult_t CAWiFiInitializeServer(void)
+{
+ return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateServer(void)
+{
+
+}
+
+CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int *port, int32_t *serverID)
+{
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAArduinoInitUdpSocket(int16_t *port, int32_t *socketID)
{
- uint8_t sock;
OIC_LOG(DEBUG, MOD_NAME, "IN");
VERIFY_NON_NULL(port, MOD_NAME, "port");
- VERIFY_NON_NULL(socketID, MOD_NAME, "socket");
+ VERIFY_NON_NULL(socketID, MOD_NAME, "socketID");
+ uint8_t sock;
//Is any socket available to work with ?
*socketID = -1;
if (sock != NO_SOCKET_AVAIL)
{
*socketID = (int32_t)sock;
- OIC_LOG_V(ERROR, MOD_NAME, "Set SOCKETID=%d", *socketID);
+ OIC_LOG_V(ERROR, MOD_NAME, "socket: %d", *socketID);
}
else
{
return CA_STATUS_OK;
}
-CAResult_t CAStartUnicastServer(const char *localAddress, const int16_t *port)
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, int32_t *serverFD)
{
OIC_LOG(DEBUG, MOD_NAME, "IN");
VERIFY_NON_NULL(port, MOD_NAME, "port");
}
OIC_LOG_V(DEBUG, MOD_NAME, "port: %d", *port);
- Udp.begin((unsigned int16_t)*port);
+ Udp.begin((uint16_t ) *port);
// start thread to monitor socket here
if (!gServerRunning)
return CA_STATUS_OK;
}
-/// Retrieves the IP address assigned to Arduino Ethernet shield
-CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- VERIFY_NON_NULL(address, MOD_NAME, "address");
- if (addrLen < IPNAMESIZE)
- {
- OIC_LOG_V(ERROR, MOD_NAME, "min addrLen %d", IPNAMESIZE);
- return CA_STATUS_FAILED;
- }
-
- IPAddress ip = WiFi.localIP();
- sprintf(address, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
-
- OIC_LOG_V(DEBUG, MOD_NAME, "address: %s", address);
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAStartMulticastServer(const char *mcastAddress, const char *localAddress, int16_t *port)
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+ const int16_t multicastPort, int32_t *serverFD)
{
// wifi shield do not support multicast
OIC_LOG(DEBUG, MOD_NAME, "IN");
- if (gServerRunning)
- {
- // already running
- OIC_LOG(DEBUG, MOD_NAME, "failed");
- return CA_STATUS_FAILED;
- }
- return CAStartUnicastServer(localAddress, port);
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ return CA_NOT_SUPPORTED;
}
-CAResult_t CAStopUnicastServer()
+CAResult_t CAWiFiStopUnicastServer()
{
OIC_LOG(DEBUG, MOD_NAME, "IN");
if (gUnicastSocket >= MAX_SOCK_NUM)
return CA_STATUS_OK;
}
-void CAArduoinoCheckServerData()
-{
- gRcvAction.check();
-}
-
-CAResult_t CAStopMulticastServer()
+CAResult_t CAWiFiStopMulticastServer()
{
- return CAStopUnicastServer();
+ return CAWiFiStopUnicastServer();
}
-uint32_t CAWIFISendData(const char *remoteIpAddress, const int16_t port, const char *buf,
- uint32_t bufLen,
- int16_t isMulticast)
+void CAPacketReceivedCallback(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength)
{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- int32_t ret = 1;
- OIC_LOG_V(DEBUG, MOD_NAME, "remoteip: %s, port: %d", remoteIpAddress, port);
- Udp.beginPacket(remoteIpAddress, port);
- ret = (int32_t)Udp.write((char *)buf);
- Udp.endPacket();
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
- return ret;
+ OIC_LOG(DEBUG, MOD_NAME, "notifyCallback Entry");
+ if (gPacketReceivedCallback)
+ {
+ gPacketReceivedCallback(ipAddress, port, data, dataLength);
+ OIC_LOG(DEBUG, MOD_NAME, "Notified network packet");
+ }
+ OIC_LOG(DEBUG, MOD_NAME, "notifyCallback Exit");
}
-void CACheckData()
+void CAArduinoCheckData()
{
+ OIC_LOG(DEBUG, MOD_NAME, "CAACD Being called");
char *data = (char *)OICMalloc(COAP_MAX_PDU_SIZE);
int32_t dataLen = 0;
char addr[IPNAMESIZE] = {0};
uint16_t senderPort = 0;
int16_t packetSize = Udp.parsePacket();
OIC_LOG_V(DEBUG, MOD_NAME, "Rcv packet of size:%d ", packetSize);
+ senderPort = Udp.remotePort();
+ OIC_LOG_V(DEBUG, MOD_NAME, "senderport: %d", senderPort);
if (packetSize)
{
IPAddress remoteIp = Udp.remoteIP();
senderPort = Udp.remotePort();
+ OIC_LOG_V(DEBUG, MOD_NAME, "senderport: %d", senderPort);
sprintf(addr, "%d.%d.%d.%d", remoteIp[0], remoteIp[1], remoteIp[2], remoteIp[3]);
OIC_LOG_V(DEBUG, MOD_NAME, "remoteip: %s, port: %d", addr, senderPort);
// read the packet into packetBufffer
{
data[len] = 0;
}
- CANotifyCallback(data, len, addr, senderPort);
+ CAPacketReceivedCallback(addr, senderPort, data, dataLen);
}
OICFree(data);
}
-void CANotifyCallback(void *data, int32_t dataLen, char *senderIp, int32_t senderPort)
-{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- if (gNetworkPacketCallback)
- {
- CARemoteEndpoint_t endPoint;
- endPoint.resourceUri = NULL; // will be filled by upper layer
- endPoint.connectivityType = CA_WIFI;
- strncpy(endPoint.addressInfo.IP.ipAddress, senderIp, strlen(senderIp));
- endPoint.addressInfo.IP.port = senderPort;
- gNetworkPacketCallback(&endPoint, data, dataLen);
- }
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
-}
-
/// Retrieve any available data from UDP socket. This is a non-blocking call.
int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen, uint8_t *senderAddr,
uint16_t *senderPort)
{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- VERIFY_NON_NULL(buf, MOD_NAME, "buf");
- VERIFY_NON_NULL(senderAddr, MOD_NAME, "senderAddr");
- VERIFY_NON_NULL(senderPort, MOD_NAME, "senderPort");
-
+ OIC_LOG(DEBUG, MOD_NAME, "arduinoRecvData Entry");
+ /**Bug : When there are multiple UDP packets in Wiznet buffer, W5100.getRXReceivedSize
+ * will not return correct length of the first packet.
+ * Fix : Use the patch provided for arduino/libraries/Ethernet/utility/socket.cpp
+ */
+ //int32_t ret = 0;
uint16_t recvLen = 0;
+
+ VERIFY_NON_NULL(buf, MOD_NAME, "Invalid buf");
+ VERIFY_NON_NULL(senderAddr, MOD_NAME, "Invalid senderAddr");
+ VERIFY_NON_NULL(senderPort, MOD_NAME, "Invalid senderPort");
+
+ OIC_LOG(DEBUG, MOD_NAME, "arduinoRecvData Begin");
if (sockFd >= MAX_SOCK_NUM)
{
OIC_LOG(ERROR, MOD_NAME, "Invalid sockfd");
*((uint8_t *)senderPort + 1) = buf[recvLen - (WIFI_RECBUF_PORT_OFFSET)];
recvLen -= WIFI_RECBUF_FOOTER_SIZE;
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ OIC_LOG(DEBUG, MOD_NAME, "arduinoRecvData End");
return (int32_t)recvLen;
}
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "CAWSPRC Entry");
+ gPacketReceivedCallback = callback;
+ OIC_LOG(DEBUG, MOD_NAME, "CAWSPRC Exit");
+}
-void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback)
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
{
- OIC_LOG(DEBUG, MOD_NAME, "IN");
- gNetworkPacketCallback = callback;
- OIC_LOG(DEBUG, MOD_NAME, "OUT");
+ // TODO
}
-int16_t CAParseIPv4AddressLocal(unsigned char *ipAddrStr, uint8_t *ipAddr, uint16_t *port)
+void CAWiFiPullData()
{
- size_t index = 0;
- unsigned char *itr;
- uint8_t dotCount = 0;
-
- ipAddr[index] = 0;
- *port = 0;
- itr = ipAddrStr;
- if (!isdigit((unsigned char) *ipAddrStr))
- {
- return -1;
- }
- ipAddrStr = itr;
+ gRcvAction.check();
+}
- while (*ipAddrStr)
+/// Retrieves the IP address assigned to Arduino Ethernet shield
+CAResult_t CAArduinoGetInterfaceAddress(char *address, int32_t addrLen)
+{
+ OIC_LOG(DEBUG, MOD_NAME, "IN");
+ // WiFiClass WiFi;
+ if (WiFi.status() == WL_NO_SHIELD)
{
- if (isdigit((unsigned char) *ipAddrStr))
- {
- ipAddr[index] *= 10;
- ipAddr[index] += *ipAddrStr - '0';
- }
- else if ((unsigned char) *ipAddrStr == '.')
- {
- index++;
- dotCount++;
- ipAddr[index] = 0;
- }
- else
- {
- break;
- }
- ipAddrStr++;
+ OIC_LOG(DEBUG, MOD_NAME, "WIFI SHIELD NOT PRESENT");
+ return CA_STATUS_FAILED;
}
- if (*ipAddrStr == ':')
+
+ while ( status != WL_CONNECTED)
{
- ipAddrStr++;
- while (*ipAddrStr)
- {
- if (isdigit((unsigned char) *ipAddrStr))
- {
- *port *= 10;
- *port += *ipAddrStr - '0';
- }
- else
- {
- break;
- }
- ipAddrStr++;
- }
+ OIC_LOG_V(ERROR, MOD_NAME, "Attempting to connect to WPA SSID: %s", ssid);
+ status = WiFi.begin(ssid, pass); // Connect to WPA/WPA2 network:
+
+ // wait 10 seconds for connection:
+ delay(10000);
+ OIC_LOG(DEBUG, MOD_NAME, "Attempting connection again");
}
- if (ipAddr[0] < 255 && ipAddr[1] < 255 && ipAddr[2] < 255 && ipAddr[3] < 255
- && dotCount == 3)
+
+ VERIFY_NON_NULL(address, MOD_NAME, "Invalid address");
+ if (addrLen < IPNAMESIZE)
{
- return 1;
+ OIC_LOG_V(ERROR, MOD_NAME, "arduinoGetInterfaceAddress: addrLen MUST be atleast %d", IPNAMESIZE);
+ return CA_STATUS_FAILED;
}
- return 0;
+
+ IPAddress ip = WiFi.localIP();
+ sprintf((char *)address, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
+
+ OIC_LOG_V(DEBUG, MOD_NAME, "Wifi shield address is: %s", address);
+ OIC_LOG(DEBUG, MOD_NAME, "arduinoGetInterfaceAddress::Exit");
+ return CA_STATUS_OK;
}
+
+
#include "cawifiinterface.h"
#include "caqueueingthread.h"
#include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
#include "umutex.h"
#include "logger.h"
#include "oic_malloc.h"
* @def CA_PORT
* @brief Port to listen for incoming data
*/
-#define CA_PORT 5283
+#define CA_PORT 5683
+
+/**
+ * @def CA_SECURE_PORT
+ * @brief Secure port to listen for incoming data
+ */
+#define CA_SECURE_PORT 5684
/**
* @def CA_MCAST_PORT
*/
static int16_t gUnicastServerport = 0;
+#ifdef __WITH_DTLS__
+/**
+ * @var gSecureUnicastServerport
+ * @brief port number on which secure unicast server is running.
+ */
+static int16_t gSecureUnicastServerport = 0;
+#endif
/**
* @var gIsStartServerCalled
* @brief Flag to check if server start requested by CA.
static void CAWiFiConnectionStateCB(const char *ipAddress,
const CANetworkStatus_t status);
static void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
- const void *data, const uint32_t dataLength);
+ const void *data, const uint32_t dataLength,
+ const CABool_t isSecured);
static CAResult_t CAWiFiStopServers();
static void CAWiFiSendDataThread(void *threadData);
static CAWiFiData *CACreateWiFiData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
const CANetworkStatus_t status)
{
- CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address, "WiFi");
+ CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address);
if (!localEndpoint)
{
OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
return;
}
- localEndpoint->addressInfo.IP.port = port;
+ localEndpoint->addressInfo.IP.port = port;
if (NULL != gNetworkChangeCallback)
{
gNetworkChangeCallback(localEndpoint, status);
{
int16_t port = CA_PORT;
int32_t serverFd = -1;
-
+
// Start Unicast server if requested earlier
if (gStartUnicastServerRequested)
{
- ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, &serverFd);
+ ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, false, &serverFd);
if (CA_STATUS_OK == ret)
{
OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", port);
{
OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start Unicast server [%d]", ret);
}
+
+#ifdef __WITH_DTLS__
+ port = CA_SECURE_PORT;
+ ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, true, &serverFd);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Secure Unicast server started on %d", port);
+ CAWiFiSetSecureUnicastSocket(serverFd);
+ gSecureUnicastServerport = port;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start secure Unicast server [%d]",
+ ret);
+ }
+#endif
}
// Start Multicast server if requested earlier
{
int16_t multicastPort = CA_MCAST_PORT;
int32_t multicastFd = 0;
- ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort,
- &multicastFd);
+ ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort,
+ &multicastFd);
if (CA_STATUS_OK == ret)
{
- OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Multicast server started on %d port",
- multicastPort);
+ OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Multicast server started on %d port",
+ multicastPort);
gIsMulticastServerStarted = true;
}
else
}
}
- char *ipAddress = NULL;
+ char *address = NULL;
char *ifcName = NULL;
- ret = CAWiFiGetInterfaceInfo(&ifcName, &ipAddress);
- if (CA_STATUS_OK != ret)
+ ret = CAWiFiGetInterfaceInfo(&ifcName, &address);
+ if (CA_STATUS_OK != ret || NULL == address)
{
OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+ OICFree(address);
+ OICFree(ifcName);
return;
}
// Notify network change to CA
- CAWiFiNotifyNetworkChange(ipAddress, port, status);
- OICFree(ipAddress);
+ CAWiFiNotifyNetworkChange(address, port, status);
+ OICFree(address);
OICFree(ifcName);
}
else
{
CAWiFiNotifyNetworkChange("", 0, status);
- // Stop both Unicast and Multicast servers
- ret = CAWiFiStopServers();
- if (CA_STATUS_OK != ret)
- {
- OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
- return;
- }
+ // Stop Unicast, Secured unicast and Multicast servers
+ CAWiFiStopServers();
}
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
}
void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
- const void *data, const uint32_t dataLength)
+ const void *data, const uint32_t dataLength, const CABool_t isSecured)
{
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
return;
}
endPoint->addressInfo.IP.port = port;
+ endPoint->isSecured = isSecured;
void *buf = OICMalloc(dataLength + 1);
if (NULL == buf)
CATerminateWIfI();
return ret;
}
+
CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
+#ifdef __WITH_DTLS__
+ CAAdapterNetDtlsInit();
+ CADTLSSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
+#endif
CAConnectivityHandler_t wifiHandler;
wifiHandler.startAdapter = CAStartWIFI;
OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start n/w monitor");
}
+ // Start send queue thread
+ if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+ {
+ OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start Send Data Thread");
+ return CA_STATUS_FAILED;
+ }
+
gStartUnicastServerRequested = true;
bool retVal = CAWiFiIsConnected();
if (false == retVal)
{
OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "WIFI is not Connected");
- return ret;
+ return CA_STATUS_OK;
}
int16_t unicastPort = CA_PORT;
int32_t serverFd = 0;
// Address is hardcoded as we are using Single Interface
- ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
+ ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, false, &serverFd);
if (CA_STATUS_OK == ret)
{
OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
gUnicastServerport = unicastPort;
}
- // Start send queue thread
- if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+#ifdef __WITH_DTLS__
+ // Address is hardcoded as we are using Single Interface
+ unicastPort = CA_SECURE_PORT;
+ ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, true, &serverFd);
+ if (CA_STATUS_OK == ret)
{
- OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start Send Data Thread");
- CAStopWIFI();
- return CA_STATUS_FAILED;
+ OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Secure Unicast server started on %d port", unicastPort);
+ CAWiFiSetSecureUnicastSocket(serverFd);
+ gSecureUnicastServerport = unicastPort;
}
+#endif
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return ret;
+ return ret;;
}
CAResult_t CAStartWIFIListeningServer()
{
OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
"Failed to Start Multicast Server, WIFI not Connected");
- return CA_ADAPTER_NOT_ENABLED;
+ return CA_STATUS_OK;
}
int32_t multicastFd = 0;
VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "info");
VERIFY_NON_NULL(size, WIFI_ADAPTER_TAG, "size");
+ CALocalConnectivity_t *netInfo = NULL;
bool retVal = CAWiFiIsConnected();
if (false == retVal)
{
return CA_ADAPTER_NOT_ENABLED;
}
+ int32_t netInfoSize = 1;
+#ifdef __WITH_DTLS__
+ if (gSecureUnicastServerport)
+ {
+ netInfoSize = 2;
+ }
+#endif
+ netInfo = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t) * netInfoSize);
+ VERIFY_NON_NULL_RET(netInfo, WIFI_ADAPTER_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
+ memset(netInfo, 0, sizeof(CALocalConnectivity_t) * netInfoSize);
+
char *ipAddress = NULL;
char *ifcName = NULL;
CAResult_t ret = CAWiFiGetInterfaceInfo(&ifcName, &ipAddress);
- if (CA_STATUS_OK != ret)
+ if (CA_STATUS_OK != ret || NULL == ipAddress)
{
OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+
+ OICFree(netInfo);
+ OICFree(ipAddress);
+ OICFree(ifcName);
return ret;
}
// Create local endpoint using util function
- (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress, ifcName);
- if (NULL == (*info))
+ CALocalConnectivity_t *endpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress);
+ if (NULL == endpoint)
{
OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint!",
CA_MEMORY_ALLOC_FAILED);
+ OICFree(netInfo);
OICFree(ipAddress);
OICFree(ifcName);
return CA_MEMORY_ALLOC_FAILED;
}
- (*info)->addressInfo.IP.port = gUnicastServerport;
- (*size) = 1;
+ // copy unciast server information
+ endpoint->isSecured = CA_FALSE;
+ endpoint->addressInfo.IP.port = gUnicastServerport;
+ memcpy(&netInfo[0], endpoint, sizeof(CALocalConnectivity_t));
+ *size = 1;
+#ifdef __WITH_DTLS__
+ // copy sevure unicast server information
+ if (gSecureUnicastServerport)
+ {
+ endpoint->isSecured = CA_TRUE;
+ endpoint->addressInfo.IP.port = gSecureUnicastServerport;
+ memcpy(&netInfo[1], endpoint, sizeof(CALocalConnectivity_t));
+ *size = 2;
+ }
+#endif
+ *info = netInfo;
OICFree(ipAddress);
OICFree(ifcName);
+ CAAdapterFreeLocalEndpoint(endpoint);
OIC_LOG(INFO, WIFI_ADAPTER_TAG, "GetWIFIInterfaceInformation success");
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
CAResult_t CAWiFiStopServers()
{
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
- CAResult_t result = CAWiFiStopUnicastServer();
- if (CA_STATUS_OK != result)
+
+ // Stop unicast server and set client socket accordingly
+ if (CA_STATUS_OK == CAWiFiStopUnicastServer())
+ {
+ CAWiFiSetUnicastSocket(-1);
+ gUnicastServerport = -1;
+ }
+#ifdef __WITH_DTLS__
+ // Stop secure unicast server and set client socket accordingly
+ if (CA_STATUS_OK == CAWiFiStopSecureUnicastServer())
{
- OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
- return result;
+ CAWiFiSetSecureUnicastSocket(-1);
+ gSecureUnicastServerport = -1;
}
- CAWiFiSetUnicastSocket(-1);
- gUnicastServerport = -1;
+#endif
- result = CAWiFiStopMulticastServer();
- if (CA_STATUS_OK != result)
+ //Stop multicast server and set the state accordingly
+ if (CA_STATUS_OK != CAWiFiStopMulticastServer())
{
- OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
- return result;
+ gIsMulticastServerStarted = false;
}
- gIsMulticastServerStarted = false;
+
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return result;
+ return CA_STATUS_OK;
}
CAResult_t CAStopWIFI()
CAWiFiStopNetworkMonitor();
//Stop send queue thread
- CAQueueingThreadStop(gSendQueueHandle);
-
- // Stop unicast/multicast servers running
- CAResult_t result = CAWiFiStopServers();
- if (CA_STATUS_OK != result)
+ if (gSendQueueHandle && CA_FALSE == gSendQueueHandle->isStop)
{
- OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
+ CAQueueingThreadStop(gSendQueueHandle);
}
+ // Stop Unicast, Secured unicast and Multicast servers running
+ CAWiFiStopServers();
+
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
- return result;
+ return CA_STATUS_OK;
}
void CATerminateWIfI()
{
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+#ifdef __WITH_DTLS__
+ CADTLSSetPacketReceiveCallback(NULL);
+ CAAdapterNetDtlsDeInit();
+#endif
+
+ // Stop wifi adapter
+ CAStopWIFI();
+
+ // Terminate network monitor
CAWiFiSetConnectionStateChangeCallback(NULL);
CAWiFiTerminateNetworkMonitor();
- OIC_LOG(INFO, WIFI_ADAPTER_TAG, "nw monitor terminated");
+
+ // Terminate message queue handler
CAWiFiDeinitializeQueueHandles();
- OIC_LOG(INFO, WIFI_ADAPTER_TAG, "sendQueue terminated");
CAWiFiSetPacketReceiveCallback(NULL);
- OIC_LOG(INFO, WIFI_ADAPTER_TAG, "TerminateWifi Success");
+
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
return;
}
if (NULL != wifiData->remoteEndpoint)
{
- OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Send Unicast Data is called");
- CAWiFiSendData(wifiData->remoteEndpoint->addressInfo.IP.ipAddress,
- wifiData->remoteEndpoint->addressInfo.IP.port, wifiData->data,
- wifiData->dataLen, false);
+ char *address = wifiData->remoteEndpoint->addressInfo.IP.ipAddress;
+ uint32_t port = wifiData->remoteEndpoint->addressInfo.IP.port;
+
+#ifdef __WITH_DTLS__
+ if (!wifiData->remoteEndpoint->isSecured)
+ {
+ CAWiFiSendData(address, port, wifiData->data, wifiData->dataLen, false,
+ wifiData->remoteEndpoint->isSecured);
+ }
+ else
+ {
+ OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt called!");
+ uint8_t cacheFalg = 0;
+ CAResult_t result = CAAdapterNetDtlsEncrypt(address, port, wifiData->data,
+ wifiData->dataLen, &cacheFalg);
+
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt failed!");
+ }
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "CAAdapterNetDtlsEncrypt returned with cache[%d]",
+ cacheFalg);
+ }
+#else
+ CAWiFiSendData(address, port, wifiData->data, wifiData->dataLen, false,
+ wifiData->remoteEndpoint->isSecured);
+#endif
}
else
{
OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Send Multicast Data is called");
- CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, wifiData->data, wifiData->dataLen, true);
+ CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, wifiData->data,
+ wifiData->dataLen, true, false);
}
//Free wifi data
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2014 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.
+ *
+ ******************************************************************/
+#include "cawifiadapter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "caadapterutils.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "cawifiinterface.h"
+
+/**
+ * @def WIFI_ETHERNET_ADAPTER_TAG
+ * @brief Logging tag for module name
+ */
+#define WIFI_ADAPTER_TAG "WA"
+
+/**
+ * @def CA_PORT
+ * @brief Port to listen for incoming data
+ */
+#define CA_PORT 5683
+
+/**
+ * @def CA_MCAST_PORT
+ * @brief Multicast Port Number
+ */
+#define CA_MCAST_PORT 5298
+
+/**
+ * @def CA_MULTICAST_IP
+ * @brief Multicast IP Address
+ */
+#define CA_MULTICAST_IP "224.0.1.187"
+
+/* Skip Queue */
+/**
+ * @var gNetworkPacketCallback
+ * @brief Network Packet Received Callback to CA
+ */
+static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
+
+/**
+ * @var gNetworkChangeCb
+ * @brief Network Changed Callback to CA
+ */
+
+CANetworkChangeCallback gNetworkChangeCallback = NULL;
+
+/**
+ * @var gIsMulticastServerStarted
+ * @brief Flag to check if multicast server is started
+ */
+static bool gIsMulticastServerStarted = false;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartUnicastServerRequested = false;
+
+/**
+ * @var gUnicastServerport
+ * @brief port number on which unicast server is running.
+ */
+static int16_t gUnicastServerport = 0;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartMulticastServerRequested = false;
+
+
+static void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
+ const CANetworkStatus_t status);
+static void CAWiFiConnectionStateCB(const char *ipAddress,
+ const CANetworkStatus_t status);
+static void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength);
+static CAResult_t CAWiFiStopServers();
+
+void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
+ const CANetworkStatus_t status)
+{
+ CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address);
+ if (!localEndpoint)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
+ return;
+ }
+ localEndpoint->addressInfo.IP.port = port;
+
+ if (NULL != gNetworkChangeCallback)
+ {
+ gNetworkChangeCallback(localEndpoint, status);
+ }
+
+ CAAdapterFreeLocalEndpoint(localEndpoint);
+}
+
+void CAWiFiConnectionStateCB(const char *ipAddress,
+ const CANetworkStatus_t status)
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+ CAResult_t ret = CA_STATUS_FAILED;
+ /* If Wifi is connected, then get the latest IP from the WIFI Interface
+ * and start unicast and multicast servers if requested earlier */
+ if (CA_INTERFACE_UP == status)
+ {
+ char *ipAddress = NULL;
+ int16_t port = CA_PORT;
+ int32_t serverFd = -1;
+ /* Start Unicast server if requested earlier */
+ if (gStartUnicastServerRequested)
+ {
+ ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, &serverFd);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", port);
+ CAWiFiSetUnicastSocket(serverFd);
+ gUnicastServerport = port;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start Unicast server [%d]", ret);
+ }
+ }
+
+ /* Start Multicast server if requested earlier */
+ if (gStartMulticastServerRequested)
+ {
+ int16_t multicastPort = CA_MCAST_PORT;
+ ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &serverFd);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Multicast server started on %d port", multicastPort);
+ gIsMulticastServerStarted = true;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start Multicast server [%d]", ret);
+ }
+ }
+
+ /* Notify network change to CA */
+ CAWiFiNotifyNetworkChange(ipAddress, port, status);
+ OICFree(ipAddress);
+ }
+ else
+ {
+ CAWiFiNotifyNetworkChange("", 0, status);
+ /* Stop both Unicast and Multicast servers */
+ ret = CAWiFiStopServers();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
+ return;
+ }
+ }
+
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+}
+
+void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength)
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+ OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
+
+ /* CA is freeing this memory */
+ CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_WIFI, ipAddress, NULL);
+ if (NULL == endPoint)
+ {
+ OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
+ return;
+ }
+ endPoint->addressInfo.IP.port = port;
+
+ void *buf = OICMalloc(dataLength + 1);
+ if (NULL == buf)
+ {
+ OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
+ CAAdapterFreeRemoteEndpoint(endPoint);
+ return;
+ }
+ memcpy(buf, data, dataLength);
+ memset(buf + dataLength, 0, 1);
+ if (gNetworkPacketCallback)
+ {
+ gNetworkPacketCallback(endPoint, buf, dataLength);
+ }
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
+ CANetworkPacketReceivedCallback networkPacketCallback,
+ CANetworkChangeCallback netCallback)
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+ VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG, "registerCallback");
+ VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG, "networkPacketCallback");
+ VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "netCallback");
+
+ gNetworkChangeCallback = netCallback;
+ gNetworkPacketCallback = networkPacketCallback;
+
+ CAResult_t ret = CAWiFiInitializeNetworkMonitor();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
+ return ret;
+ }
+ CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateCB);
+
+ ret = CAWiFiInitializeServer();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
+ CATerminateWIfI();
+ return ret;
+ }
+ CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
+
+ CAConnectivityHandler_t wifiHandler;
+ wifiHandler.startAdapter = CAStartWIFI;
+ wifiHandler.startListenServer = CAStartWIFIListeningServer;
+ wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer;
+ wifiHandler.sendData = CASendWIFIUnicastData;
+ wifiHandler.sendDataToAll = CASendWIFIMulticastData;
+ wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation;
+ wifiHandler.readData = CAReadWIFIData;
+ wifiHandler.stopAdapter = CAStopWIFI;
+ wifiHandler.terminate = CATerminateWIfI;
+ registerCallback(wifiHandler, CA_WIFI);
+
+ OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAStartWIFI()
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+ /* Start monitoring wifi network */
+ CAResult_t ret = CAWiFiStartNetworkMonitor();
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start n/w monitor");
+ }
+
+ gStartUnicastServerRequested = true;
+ bool retVal = CAWiFiIsConnected();
+ if (false == retVal)
+ {
+ OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "WIFI is not Connected");
+ return ret;
+ }
+
+ int16_t unicastPort = CA_PORT;
+ int32_t serverFd = 0;
+ // Address is hardcoded as we are using Single Interface
+ ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
+ CAWiFiSetUnicastSocket(serverFd);
+ gUnicastServerport = unicastPort;
+ }
+
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return ret;
+}
+
+CAResult_t CAStartWIFIListeningServer()
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+ CAResult_t ret = CA_STATUS_OK;
+ int16_t multicastPort = CA_MCAST_PORT;
+
+ if (gIsMulticastServerStarted == true)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
+ "Failed to Start Multicast Server, Already Started!");
+ return CA_SERVER_STARTED_ALREADY;
+ }
+
+ gStartMulticastServerRequested = true;
+ bool retVal = CAWiFiIsConnected();
+ if (false == retVal)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
+ "Failed to Start Multicast Server, WIFI not Connected");
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, NULL);
+ if (CA_STATUS_OK == ret)
+ {
+ OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
+ gIsMulticastServerStarted = true;
+ }
+
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return ret;
+}
+
+CAResult_t CAStartWIFIDiscoveryServer()
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+ /* Both listening and discovery server are same */
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return CAStartWIFIListeningServer();
+}
+
+uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+ uint32_t dataLength)
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+ uint32_t dataSize = 0;
+ VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ADAPTER_TAG, "remoteEndpoint", dataSize);
+ VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
+ if (dataLength == 0)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
+ return dataSize;
+ }
+
+ CAWiFiSendData(remoteEndpoint->addressInfo.IP.ipAddress,
+ remoteEndpoint->addressInfo.IP.port, data, dataLength, false);
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return dataLength;
+}
+
+uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+ uint32_t dataSize = 0;
+ VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
+ if (dataLength == 0)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
+ return dataSize;
+ }
+
+ CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, true);
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return dataLength;
+}
+
+CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+ VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "info");
+ VERIFY_NON_NULL(size, WIFI_ADAPTER_TAG, "size");
+
+ bool retVal = CAWiFiIsConnected();
+ if (false == retVal)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
+ "Failed to get interface address, WIFI not Connected", CA_ADAPTER_NOT_ENABLED);
+ return CA_ADAPTER_NOT_ENABLED;
+ }
+
+ char *ipAddress = NULL;
+ char *ifcName = NULL;
+ CAResult_t ret = CAWiFiGetInterfaceInfo(&ipAddress, &ifcName);
+ if (CA_STATUS_OK != ret)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+ return ret;
+ }
+
+ // Create local endpoint using util function
+ (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress);
+ if (NULL == (*info))
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint!",
+ CA_MEMORY_ALLOC_FAILED);
+ OICFree(ipAddress);
+ OICFree(ifcName);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
+
+ (*info)->addressInfo.IP.port = gUnicastServerport;
+ (*size) = 1;
+
+ OICFree(ipAddress);
+ OICFree(ifcName);
+
+ OIC_LOG(INFO, WIFI_ADAPTER_TAG, "GetWIFIInterfaceInformation success");
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAReadWIFIData()
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+ CAWiFiPullData();
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopServers()
+{
+ CAResult_t result = CAWiFiStopUnicastServer();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
+ return result;
+ }
+ CAWiFiSetUnicastSocket(-1);
+ gUnicastServerport = -1;
+
+ result = CAWiFiStopMulticastServer();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
+ return result;
+ }
+ gIsMulticastServerStarted = false;
+
+ return result;
+}
+
+CAResult_t CAStopWIFI()
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+ gStartUnicastServerRequested = false;
+ gStartMulticastServerRequested = false;
+ CAWiFiStopNetworkMonitor();
+ CAResult_t result = CAWiFiStopServers();
+ if (CA_STATUS_OK != result)
+ {
+ OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
+ }
+
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return result;
+}
+
+void CATerminateWIfI()
+{
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+ CAWiFiSetConnectionStateChangeCallback(NULL);
+ CAWiFiTerminateNetworkMonitor();
+ OIC_LOG(INFO, WIFI_ADAPTER_TAG, "nw monitor terminated");
+ CAWiFiSetPacketReceiveCallback(NULL);
+ OIC_LOG(INFO, WIFI_ADAPTER_TAG, "TerminateWifi Success");
+ OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+ return;
+}
+
*/
static int32_t gUnicastServerSocketDescClient = -1;
-void CAWiFiSetUnicastSocket(const int32_t socketFD)
-{
- OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
-
- gUnicastServerSocketDescClient = socketFD;
-}
+#ifdef __WITH_DTLS__
+/**
+ * @var gUnicastServerSocketDescClient
+ * @brief socket descriptor for secure unicast server
+ */
+static int32_t gUnicastServerSecureSocketDescClient = -1;
+#endif
-uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
- const void *data, const uint32_t dataLength, bool isMulticast)
+static uint32_t CASendData(const char *remoteAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength, int32_t sockfd)
{
OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
return 0;
}
- if (0 > gUnicastServerSocketDescClient)
+ if (0 > sockfd)
{
OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running !");
return 0;
return 0;
}
- int32_t sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLength, 0,
+ int32_t sendDataLength = sendto(sockfd, data, dataLength, 0,
(struct sockaddr *)&destAddr, sizeof(destAddr));
if (sendDataLength == -1)
{
return sendDataLength;
}
+void CAWiFiSetUnicastSocket(const int32_t socketFD)
+{
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+ gUnicastServerSocketDescClient = socketFD;
+
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
+}
+
+#ifdef __WITH_DTLS__
+void CAWiFiSetSecureUnicastSocket(const int32_t socketFD)
+{
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+ gUnicastServerSecureSocketDescClient = socketFD;
+
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
+}
+#endif
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength,
+ CABool_t isMulticast, CABool_t isSecured)
+{
+ uint32_t len = 0;
+
+#ifdef __WITH_DTLS__
+ if (CA_TRUE == isSecured)
+ {
+ len = CASendData(remoteAddress, port,
+ data, dataLength, gUnicastServerSecureSocketDescClient);
+ }
+ else
+ {
+#endif
+ len = CASendData(remoteAddress, port,
+ data, dataLength, gUnicastServerSocketDescClient);
+#ifdef __WITH_DTLS__
+ }
+#endif
+ return len;
+}
+
+
#include "cawifiinterface.h"
-#include <string.h>
+#include <sys/types.h>
#include <ifaddrs.h>
+#include <net/if.h>
+#include <sys/socket.h>
#include <netdb.h>
-
-#include "caadapterutils.h"
-#include "umutex.h"
+#include <string.h>
+#include <errno.h>
#include "logger.h"
#include "oic_malloc.h"
+#include "umutex.h"
+#include "caadapterutils.h"
#define WIFI_MONITOR_TAG "WIFI_MONITOR"
*/
static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
-static void CANetworkMonitorThread(void* threadData);
+static void CANetworkMonitorThread(void *threadData);
CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
{
if (gStopNetworkMonitor)
{
- OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Network Monitor Thread is already running!");
+ OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Stop network monitor requested!");
return CA_SERVER_STARTED_ALREADY;
}
{
OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
- VERIFY_NON_NULL(interfaceName, WIFI_MONITOR_TAG, "interface name holder is NULL");
- VERIFY_NON_NULL(ipAddress, WIFI_MONITOR_TAG, "IP address holder is NULL");
+ VERIFY_NON_NULL(interfaceName, WIFI_MONITOR_TAG, "interface name");
+ VERIFY_NON_NULL(ipAddress, WIFI_MONITOR_TAG, "ip address");
+ // Get the interface and ipaddress information from cache
u_mutex_lock(gWifiNetInfoMutex);
- if (gWifiInterfaceName && strlen(gWifiInterfaceName))
- {
- *interfaceName = (gWifiInterfaceName) ? strndup(gWifiInterfaceName, strlen(gWifiInterfaceName)) :
- NULL;
- }
-
- if (gWifiIPAddress && strlen(gWifiIPAddress))
- {
- *ipAddress = (gWifiIPAddress) ? strndup(gWifiIPAddress, strlen(gWifiIPAddress)) :
- NULL;
- }
+ *interfaceName = (gWifiInterfaceName) ? strndup(gWifiInterfaceName,strlen(gWifiInterfaceName))
+ : NULL;
+ *ipAddress = (gWifiIPAddress) ? strndup(gWifiIPAddress,strlen(gWifiIPAddress))
+ : NULL;
u_mutex_unlock(gWifiNetInfoMutex);
- OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+ OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
return CA_STATUS_OK;
}
return true;
}
-void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
+void CAWiFiSetConnectionStateChangeCallback(
+ CAWiFiConnectionStateChangeCallback callback)
{
OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
struct ifaddrs *ifa = NULL;
struct ifaddrs *ifp = NULL;
- if (getifaddrs(&ifp) < 0)
+ if (!interfaceName || !ipAddress)
{
- OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Get network interface list error");
+ OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Invalid input: interface/ipaddress holder is NULL!");
+ return;
+ }
+
+ if (-1 == getifaddrs(&ifp))
+ {
+ OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface list!, Error code: %s",
+ strerror(errno));
+ return;
}
for (ifa = ifp; ifa; ifa = ifa->ifa_next)
{
char localIPAddress[CA_IPADDR_SIZE];
- socklen_t len;
+ socklen_t len = sizeof(struct sockaddr_in);
if (ifa->ifa_addr == NULL)
continue;
- if (ifa->ifa_addr->sa_family == AF_INET)
- len = sizeof(struct sockaddr_in);
- else if (ifa->ifa_addr->sa_family == AF_INET6)
- continue;
- else
+ int type = ifa->ifa_addr->sa_family;
+ if (ifa->ifa_flags & IFF_LOOPBACK
+ || !((ifa->ifa_flags & IFF_UP) && (ifa->ifa_flags & IFF_RUNNING)))
+ {
continue;
+ }
- if (getnameinfo(ifa->ifa_addr, len, localIPAddress,
- sizeof(localIPAddress), NULL, 0, NI_NUMERICHOST) < 0)
+ if (AF_INET != type)
{
- OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Get IPAddress fail");
+ continue;
}
- // except loopback address
- if (strcmp(localIPAddress, "127.0.0.1") == 0)
- continue;
+ if (0 != getnameinfo(ifa->ifa_addr, len, localIPAddress,
+ sizeof(localIPAddress), NULL, 0, NI_NUMERICHOST))
+ {
+ OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
+ strerror(errno));
+ freeifaddrs(ifp);
+ return;
+ }
// set interface name
*interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
freeifaddrs(ifp);
}
-void CANetworkMonitorThread(void* threadData)
+void CANetworkMonitorThread(void *threadData)
{
+ OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
while (!gStopNetworkMonitor)
{
- if (gStopNetworkMonitor)
- {
- OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Stop Network Monitor Thread is called");
- break;
- }
-
// Get network information
CANetworkStatus_t currNetworkStatus;
char *interfaceName = NULL;
OICFree(interfaceName);
OICFree(ipAddress);
}
+
+ OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
}
#include "pdu.h"
#include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "caadapternetdtls.h"
+#endif
#include "umutex.h"
/**
#define CA_UDP_BIND_RETRY_COUNT 10
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gUnicastServerSocketFD
+ * @brief Unicast server socket descriptor
*/
-static int32_t gUnicastServerSocketDescriptor = -1;
+static int32_t gUnicastServerSocketFD = -1;
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gMutexUnicastServer
+ * @brief Mutex to synchronize unicast server
*/
-static char *gUnicastServerAddress = NULL;
+static u_mutex gMutexUnicastServer = NULL;
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gStopUnicast
+ * @brief Flag to control the Receive Unicast Data Thread
*/
-static int16_t gUnicastServerPort = -1;
+static bool gStopUnicast = false;
/**
- * @var gMutexUnicastServerSocketDescriptor
- * @brief Mutex for socket descriptor for unicast server
- */
-static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
-/**
- * @var gMulticastServerSocketDescriptor
+ * @var gMulticastServerSocketFD
* @brief socket descriptor for multicast server
*/
-static int32_t gMulticastServerSocketDescriptor = -1;
+static int32_t gMulticastServerSocketFD = -1;
/**
- * @var gMutexMulticastServerSocketDescriptor
- * @brief Mutex for socket descriptor for Multicast server
+ * @var gMutexMulticastServer
+ * @brief Mutex to synchronize secure multicast server
*/
-static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
+static u_mutex gMutexMulticastServer = NULL;
/**
- * @var gThreadPool
- * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ * @var gStopMulticast
+ * @brief Flag to control the Receive Multicast Data Thread
*/
-static u_thread_pool_t gThreadPool = NULL;
+static bool gStopMulticast = false;
+#ifdef __WITH_DTLS__
/**
- * @var gMReq
- * @brief ip_mreq structure passed to join a multicast group
+ * @var gSecureUnicastServerSocketFD
+ * @brief Secure unicast server socket descriptor
*/
-static struct ip_mreq gMReq;
+static int32_t gSecureUnicastServerSocketFD = -1;
/**
- * @var gStopUnicast
- * @brief Flag to control the Receive Unicast Data Thread
+ * @var gMutexSecureUnicastServer
+ * @brief Mutex to synchronize secure unicast server
*/
-static bool gStopUnicast = false;
+static u_mutex gMutexSecureUnicastServer = NULL;
/**
- * @var gMutexStopUnicast
- * @brief Mutex for gStopUnicast
+ * @var gStopSecureUnicast
+ * @brief Flag to control the unicast secure data receive thread
*/
-static u_mutex gMutexStopUnicast = NULL;
+static bool gStopSecureUnicast = false;
+#endif
/**
- * @var gStopMulticast
- * @brief Flag to control the Receive Multicast Data Thread
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
*/
-static bool gStopMulticast = false;
+static u_thread_pool_t gThreadPool = NULL;
/**
- * @var gMutexStopMulticast
- * @brief Mutex for gStopMulticast
+ * @var gMulticastMemberReq
+ * @brief ip_mreq structure passed to join a multicast group
*/
-static u_mutex gMutexStopMulticast = NULL;
+static struct ip_mreq gMulticastMemberReq;
/**
* @var gPacketReceivedCallback
static CAWiFiExceptionCallback gExceptionCallback = NULL;
/**
- * @var gUnicastRecvBuffer
- * @brief Character buffer used for receiving unicast data from network
- */
-static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
-
-/**
- * @var gMulticastRecvBuffer
- * @brief Character buffer used for receiving multicast data from network
- */
-static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
-
-/**
- * @fn CAWiFiServerCreateMutex
- * @brief Creates and initializes mutex
+ @brief Thread context information for unicast, multicast and secured unicast server
*/
-static CAResult_t CAWiFiServerCreateMutex(void);
-
-/**
- * @fn CAWiFiServerDestroyMutex
- * @brief Releases all created mutex
- */
-static void CAWiFiServerDestroyMutex(void);
-
-/**
- * @fn CAReceiveThreadForMulticast
- * @brief Handler thread for receiving data on multicast server
- */
-static void *CAReceiveThreadForMulticast(void *data);
-
-/**
- * @fn CAWiFiReceiveThreadForUnicast
- * @brief Handler thread for receiving data on unicast server
- */
-static void *CAWiFiReceiveThreadForUnicast(void *data);
-
-CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiInitializeServer, IN");
-
- // Input validation
- VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
-
- // Initialize mutex
- if (CA_STATUS_OK != CAWiFiServerCreateMutex())
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
- return CA_STATUS_FAILED;
- }
-
- gThreadPool = threadPool;
-
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiInitializeServer, OUT");
- return CA_STATUS_OK;
-}
-
-void CAWiFiTerminateServer(void)
+typedef struct
{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiTerminateServer, IN");
-
- gThreadPool = NULL;
-
- // Destroy mutex
- CAWiFiServerDestroyMutex();
-
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiTerminateServer, OUT");
-}
+ bool *stopFlag;
+ int32_t socket_fd;
+ CAAdapterServerType_t type;
+}CAAdapterReceiveThreadContext_t;
-CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
- const int16_t multicastPort, int32_t *serverFD)
+static void CAReceiveHandler(void *data)
{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiStartMulticastServer, IN");
-
- if (gMulticastServerSocketDescriptor != -1)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
- return CA_SERVER_STARTED_ALREADY;
- }
-
- VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
- VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
-
- if (0 >= multicastPort)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
- return CA_STATUS_INVALID_PARAM;
- }
-
- // Create a datagram socket on which to recv/send.
- u_mutex_lock(gMutexStopMulticast);
- gStopMulticast = false;
- u_mutex_unlock(gMutexStopMulticast);
-
- u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ // Input validation
+ VERIFY_NON_NULL_VOID(data, WIFI_SERVER_TAG, "Invalid thread context");
- // create a UDP socket
- if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
- strerror(errno));
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
- }
+ CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)data;
+ fd_set reads;
+ struct timeval timeout;
+ char recvBuffer[COAP_MAX_PDU_SIZE] = {0};
- // Make the socket non-blocking
- if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+ while (*(ctx->stopFlag) == false)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
- strerror(errno));
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_STATUS_FAILED;
- }
-
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
- int32_t setOptionOn = 1;
- if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
- (char *) &setOptionOn,
- sizeof(setOptionOn)))
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
- strerror(errno));
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
- }
+ FD_ZERO(&reads);
+ FD_SET(ctx->socket_fd, &reads);
- struct sockaddr_in sockAddr;
- memset((char *) &sockAddr, 0, sizeof(sockAddr));
+ int32_t ret = select(ctx->socket_fd + 1, &reads, NULL, NULL, &timeout);
+ if (*(ctx->stopFlag) == true)
+ {
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Stop request received for [%d] server", ctx->type);
+ break;
+ }
+ if (ret < 0)
+ {
+ OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+ continue;
+ }
+ if (!FD_ISSET(ctx->socket_fd, &reads))
+ {
+ continue;
+ }
- sockAddr.sin_family = AF_INET;
- sockAddr.sin_port = htons(multicastPort);
- sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ memset(recvBuffer, 0, sizeof(recvBuffer));
- // bind socket to multicast port
- if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
- sizeof(sockAddr)))
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
- CA_SOCKET_OPERATION_FAILED);
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
- }
+ // Read data from socket
+ struct sockaddr_in srcSockAddress;
+ int32_t recvLen;
+ socklen_t srcAddressLen = sizeof(srcSockAddress);
+ if (-1 == (recvLen = recvfrom(ctx->socket_fd, recvBuffer,
+ sizeof(recvBuffer), 0, (struct sockaddr *) &srcSockAddress,
+ &srcAddressLen)))
+ {
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+ continue;
+ }
+ else if (0 == recvLen)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Server socket shutdown [%d]!", ctx->type);
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+ // Notify upper layer this exception
+ if (gExceptionCallback)
+ {
+ gExceptionCallback(ctx->type);
+ }
+ OICFree(ctx);
+ return;
+ }
- // Add membership to receiving socket (join group)
- memset(&gMReq, 0, sizeof(struct ip_mreq));
- gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
- inet_aton(multicastAddress, &gMReq.imr_multiaddr);
+ const char *srcIPAddress = NULL;
+ int32_t srcPort = -1;
- if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (char *) &gMReq,
- sizeof(struct ip_mreq)))
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
- strerror(errno));
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
- }
+ srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+ srcPort = ntohs(srcSockAddress.sin_port);
- /**
- * The task to listen to data from multicastcast socket is added to the thread pool.
- * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
- * This task will be terminated when thread pool is freed on stopping the adapters.
- */
- if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
- (void *)NULL))
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+ srcIPAddress, srcPort);
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+ recvBuffer, recvLen);
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_STATUS_FAILED;
+ switch(ctx->type)
+ {
+ case CA_UNICAST_SERVER:
+ case CA_MULTICAST_SERVER:
+ // Notify data to upper layer
+ if (gPacketReceivedCallback)
+ {
+ gPacketReceivedCallback(srcIPAddress, srcPort, recvBuffer, recvLen, false);
+ }
+ break;
+#ifdef __WITH_DTLS__
+ case CA_SECURED_UNICAST_SERVER:
+ {
+ CAResult_t ret = CAAdapterNetDtlsDecrypt(srcIPAddress,
+ srcPort,
+ (uint8_t *)recvBuffer,
+ recvLen);
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "CAAdapterNetDtlsDecrypt returns [%d]", ret);
+ }
+ break;
+#endif //__WITH_DTLS__
+ default:
+ // Should never occur
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Invalid server type");
+ OICFree(ctx);
+ return;
+ }
}
- *serverFD = gMulticastServerSocketDescriptor;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-
- OIC_LOG(INFO, WIFI_SERVER_TAG, "thread_pool_add_task done");
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Started Successfully");
-
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiStartMulticastServer, OUT");
- return CA_STATUS_OK;
-
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
}
-CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
- const bool forceStart, int32_t *serverFD)
+static CAResult_t CAWiFiCreateSocket(int32_t* socketFD, int16_t *port, const bool forceStart)
{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiStartUnicastServer, IN");
-
- if (gUnicastServerSocketDescriptor != -1)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
- CA_SERVER_STARTED_ALREADY);
- return CA_SERVER_STARTED_ALREADY;
- }
-
- VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Invalid argument : localAddress is NULL");
- VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Invalid argument : port is NULL");
-
- if (*port < 0)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
- return CA_STATUS_INVALID_PARAM;
- }
-
- u_mutex_lock(gMutexStopUnicast);
- gStopUnicast = false;
- u_mutex_unlock(gMutexStopUnicast);
-
- u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+ int32_t sock = -1;
// Create a UDP socket
- if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ if (-1 == (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to create Socket, Error code: %s",
strerror(errno));
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
+ return CA_STATUS_FAILED;
}
// Make the socket non-blocking
- if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+ if (-1 == fcntl(sock, F_SETFL, O_NONBLOCK))
{
OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
strerror(errno));
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+ close(sock);
return CA_STATUS_FAILED;
}
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
-
if (true == forceStart)
{
int32_t setOptionOn = 1;
- if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+ if (-1 == setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *) &setOptionOn,
sizeof(setOptionOn)))
{
OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
strerror(errno));
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
+
+ close(sock);
+ return CA_STATUS_FAILED;
}
}
sockAddr.sin_port = htons(serverPort);
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- // Trying for bind in a loop
int16_t i;
for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
{
- if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+ if (-1 == bind(sock, (struct sockaddr *) &sockAddr,
sizeof(sockAddr)))
{
if (false == forceStart)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ",
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again..",
strerror(errno));
- // Set the port to next one
+ //Set the port to next one
serverPort += 1;
sockAddr.sin_port = htons(serverPort);
continue;
if (false == isBound)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
- CA_SOCKET_OPERATION_FAILED);
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
+ close(sock);
+ return CA_STATUS_FAILED;
}
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+ *port = serverPort;
+ *socketFD = sock;
+ return CA_STATUS_OK;
+}
+
+static CAResult_t CAWiFiCloseSocket(int32_t *socketFD)
+{
+ if (-1 == *socketFD)
+ {
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Server not running");
+ return CA_SERVER_NOT_STARTED;
+ }
- socklen_t len = 0;
- char *serverAddress = NULL;
- if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
+ // close the socket
+ if (-1 == close(*socketFD))
{
- serverPort = ntohs(sockAddr.sin_port);
- serverAddress = inet_ntoa(sockAddr.sin_addr);
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
+ strerror(errno));
+ return CA_STATUS_FAILED;
+ }
+
+ *socketFD = -1;
+ return CA_STATUS_OK;
+}
+
+static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, bool isSecured, int32_t *serverFD)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ CAResult_t ret = CAWiFiCreateSocket(serverFD, port, forceStart);
+ if(ret != CA_STATUS_OK)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create unicast socket");
+ return ret;
}
/**
* This is a blocking call is made where we try to receive some data..
* We will keep waiting until some data is received.
* This task will be terminated when thread pool is freed on stopping the adapters.
+ * Thread context will be freed by thread on exit.
*/
- if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAWiFiReceiveThreadForUnicast,
- (void *) NULL))
+ CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
+ OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
+ if(!ctx)
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Out of memory!");
+ close(*serverFD);
+ return CA_MEMORY_ALLOC_FAILED;
+ }
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+ ctx->stopFlag = &gStopUnicast;
+ ctx->socket_fd = *serverFD;
+ ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER:CA_UNICAST_SERVER;
+ if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAReceiveHandler, (void *)ctx))
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create read thread!");
+ OICFree((void *)ctx);
+ close(*serverFD);
return CA_STATUS_FAILED;
}
- // Free the server address previously stored
- OICFree(gUnicastServerAddress);
- gUnicastServerAddress = NULL;
- gUnicastServerPort = serverPort;
- gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
- NULL;
- *port = serverPort;
- *serverFD = gUnicastServerSocketDescriptor;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-
- OIC_LOG(INFO, WIFI_SERVER_TAG, "CAWiFiStartUnicastServer, OUT");
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
return CA_STATUS_OK;
}
-CAResult_t CAWiFiStopMulticastServer(void)
+static void CAWiFiServerDestroyMutex(void)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- u_mutex_lock(gMutexMulticastServerSocketDescriptor);
-
- if (gMulticastServerSocketDescriptor == -1)
+ if (gMutexUnicastServer)
{
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server is not yet Started");
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SERVER_NOT_STARTED;
+ u_mutex_free(gMutexUnicastServer);
+ gMutexUnicastServer = NULL;
}
- u_mutex_lock(gMutexStopMulticast);
- gStopMulticast = true;
-
- // leave the group after you are done
- if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
- (char *)&gMReq,
- sizeof(struct ip_mreq)))
+#ifdef __WITH_DTLS__
+ if (gMutexSecureUnicastServer)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
- strerror(errno));
+ u_mutex_free(gMutexSecureUnicastServer);
+ gMutexSecureUnicastServer = NULL;
}
+#endif
- // close the socket
- if (-1 == close(gMulticastServerSocketDescriptor))
+ if (gMutexMulticastServer)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
- strerror(errno));
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- u_mutex_unlock(gMutexStopMulticast);
- return CA_SOCKET_OPERATION_FAILED;
+ u_mutex_free(gMutexMulticastServer);
+ gMutexMulticastServer = NULL;
}
- u_mutex_unlock(gMutexStopMulticast);
-
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Stopped Successfully");
-
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
- return CA_STATUS_OK;
-
}
-CAResult_t CAWiFiStopUnicastServer()
+static CAResult_t CAWiFiServerCreateMutex(void)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- u_mutex_lock(gMutexUnicastServerSocketDescriptor);
- if (gUnicastServerSocketDescriptor == -1)
+ gMutexUnicastServer = u_mutex_new();
+ if (!gMutexUnicastServer)
{
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server is not yet Started");
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- return CA_SERVER_NOT_STARTED;
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+ return CA_STATUS_FAILED;
}
- u_mutex_lock(gMutexStopUnicast);
- gStopUnicast = true;
- // close the socket
- if (-1 == close(gUnicastServerSocketDescriptor))
+#ifdef __WITH_DTLS__
+ gMutexSecureUnicastServer = u_mutex_new();
+ if (!gMutexSecureUnicastServer)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
- strerror(errno));
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- u_mutex_unlock(gMutexStopUnicast);
- return CA_SOCKET_OPERATION_FAILED;
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+ return CA_STATUS_FAILED;
}
+#endif
- u_mutex_unlock(gMutexStopUnicast);
- gUnicastServerSocketDescriptor = -1;
+ gMutexMulticastServer = u_mutex_new();
+ if (!gMutexMulticastServer)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+ CAWiFiServerDestroyMutex();
+ return CA_STATUS_FAILED;
+ }
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Stopped Successfully");
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
return CA_STATUS_OK;
}
-CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD)
+CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
// Input validation
- VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "ipAddress holder is NULL");
- VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port holder is NULL");
- VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "serverID holder is NULL");
+ VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
- *ipAddress = gUnicastServerAddress;
- *port = gUnicastServerPort;
- *serverFD = gUnicastServerSocketDescriptor;
+ // Initialize mutex
+ if (CA_STATUS_OK != CAWiFiServerCreateMutex())
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
+ return CA_STATUS_FAILED;
+ }
+
+ gThreadPool = threadPool;
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
return CA_STATUS_OK;
}
-void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
+void CAWiFiTerminateServer(void)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- gPacketReceivedCallback = callback;
-}
+ gThreadPool = NULL;
-void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ // Destroy mutex
+ CAWiFiServerDestroyMutex();
- gExceptionCallback = callback;
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
}
-CAResult_t CAWiFiServerCreateMutex(void)
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, const CABool_t isSecured,
+ int32_t *serverFD)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- gMutexUnicastServerSocketDescriptor = u_mutex_new();
- if (!gMutexUnicastServerSocketDescriptor)
+ // Input validation
+ VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "localAddress");
+ VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port");
+ VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "server socket FD");
+
+ if (0 >= *port)
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
- return CA_STATUS_FAILED;
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
+ return CA_STATUS_INVALID_PARAM;
}
- gMutexMulticastServerSocketDescriptor = u_mutex_new();
- if (!gMutexMulticastServerSocketDescriptor)
+ *serverFD = -1;
+ if (CA_FALSE == isSecured)
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+ u_mutex_lock(gMutexUnicastServer);
+ if (-1 != gUnicastServerSocketFD)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already!",
+ CA_SERVER_STARTED_ALREADY);
- CAWiFiServerDestroyMutex();
- return CA_STATUS_FAILED;
- }
+ *serverFD = gUnicastServerSocketFD;
+ u_mutex_unlock(gMutexUnicastServer);
+ return CA_SERVER_STARTED_ALREADY;
+ }
- gMutexStopUnicast = u_mutex_new();
- if (!gMutexStopUnicast)
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+ gStopUnicast = false;
+ if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
+ &gUnicastServerSocketFD))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
+ gUnicastServerSocketFD = -1;
+ u_mutex_unlock(gMutexUnicastServer);
+ return CA_STATUS_FAILED;
+ }
- CAWiFiServerDestroyMutex();
- return CA_STATUS_FAILED;
+ *serverFD = gUnicastServerSocketFD;
+ u_mutex_unlock(gMutexUnicastServer);
}
-
- gMutexStopMulticast = u_mutex_new();
- if (!gMutexStopMulticast)
+#ifdef __WITH_DTLS__
+ else // Start unicast server for secured communication
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+ u_mutex_lock(gMutexSecureUnicastServer);
+ if (-1 != gSecureUnicastServerSocketFD)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already!",
+ CA_SERVER_STARTED_ALREADY);
- CAWiFiServerDestroyMutex();
- return CA_STATUS_FAILED;
- }
+ *serverFD = gSecureUnicastServerSocketFD;
+ u_mutex_unlock(gMutexSecureUnicastServer);
+ return CA_SERVER_STARTED_ALREADY;
+ }
+
+ gStopSecureUnicast = false;
+ if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart, isSecured,
+ &gSecureUnicastServerSocketFD))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
+ gSecureUnicastServerSocketFD = -1;
+ u_mutex_unlock(gMutexSecureUnicastServer);
+ return CA_STATUS_FAILED;
+ }
+ *serverFD = gSecureUnicastServerSocketFD;
+ u_mutex_unlock(gMutexSecureUnicastServer);
+ }
+#endif
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
return CA_STATUS_OK;
}
-void CAWiFiServerDestroyMutex(void)
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+ const int16_t multicastPort, int32_t *serverFD)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- if (gMutexUnicastServerSocketDescriptor)
+ // Input validation
+ VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
+ VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
+
+ int16_t port = multicastPort;
+ if (0 >= port)
{
- u_mutex_free(gMutexUnicastServerSocketDescriptor);
- gMutexUnicastServerSocketDescriptor = NULL;
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
+ return CA_STATUS_INVALID_PARAM;
}
- if (gMutexMulticastServerSocketDescriptor)
+ u_mutex_lock(gMutexMulticastServer);
+
+ if (gMulticastServerSocketFD != -1)
{
- u_mutex_free(gMutexMulticastServerSocketDescriptor);
- gMutexMulticastServerSocketDescriptor = NULL;
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_SERVER_STARTED_ALREADY;
}
- if (gMutexStopUnicast)
+ CAResult_t ret = CAWiFiCreateSocket(&gMulticastServerSocketFD, &port, true);
+ if(ret != CA_STATUS_OK)
{
- u_mutex_free(gMutexStopUnicast);
- gMutexStopUnicast = NULL;
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create multicast socket");
+ u_mutex_unlock(gMutexMulticastServer);
+ return ret;
}
- if (gMutexStopMulticast)
+ // Add membership to receiving socket (join group)
+ memset(&gMulticastMemberReq, 0, sizeof(struct ip_mreq));
+ gMulticastMemberReq.imr_interface.s_addr = htonl(INADDR_ANY);
+ inet_aton(multicastAddress, &gMulticastMemberReq.imr_multiaddr);
+
+ if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *) &gMulticastMemberReq,
+ sizeof(struct ip_mreq)))
{
- u_mutex_free(gMutexStopMulticast);
- gMutexStopMulticast = NULL;
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
+ strerror(errno));
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_STATUS_FAILED;
}
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
-}
-
-void *CAWiFiReceiveThreadForUnicast(void *data)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ /**
+ * The task to listen to data from multicastcast socket is added to the thread pool.
+ * This is a blocking call is made where we try to receive some data.
+ * We will keep waiting until some data is received.
+ * This task will be terminated when thread pool is freed on stopping the adapters.
+ * Thread context will be freed by thread on exit.
+ */
+ CAAdapterReceiveThreadContext_t *ctx = (CAAdapterReceiveThreadContext_t *)
+ OICMalloc(sizeof(CAAdapterReceiveThreadContext_t));
+ if(!ctx)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Out of memory!");
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ return CA_MEMORY_ALLOC_FAILED;
+ }
- fd_set reads;
- struct timeval timeout;
+ ctx->stopFlag = &gStopMulticast;
+ ctx->socket_fd = gMulticastServerSocketFD;
+ ctx->type = CA_MULTICAST_SERVER;
- // keep listening for data
- while (!gStopUnicast)
+ gStopMulticast = false;
+ if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAReceiveHandler, (void *)ctx))
{
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "thread_pool_add_task failed!");
- FD_ZERO(&reads);
- FD_SET(gUnicastServerSocketDescriptor, &reads);
-
- int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
- if (gStopUnicast)
- {
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Unicast is called");
- break;
- }
- if (ret < 0)
- {
- OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
- continue;
- }
- if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
- {
- continue;
- }
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ gStopMulticast = true;
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_STATUS_FAILED;
+ }
- memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+ *serverFD = gMulticastServerSocketFD;
+ u_mutex_unlock(gMutexMulticastServer);
- // Read data from socket
- struct sockaddr_in srcSockAddress;
- int32_t recvLen;
- socklen_t srcAddressLen = sizeof(srcSockAddress);
- if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
- COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
- &srcAddressLen)))
- {
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
- continue;
- }
- else if (0 == recvLen)
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
- // Notify upper layer this exception
- if (gExceptionCallback)
- {
- gExceptionCallback(CA_UNICAST_SERVER);
- }
- return NULL;
- }
+CAResult_t CAWiFiStopUnicastServer()
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- const char *srcIPAddress = NULL;
- int32_t srcPort = -1;
+ u_mutex_lock(gMutexUnicastServer);
+ gStopUnicast = true;
+ CAResult_t ret = CAWiFiCloseSocket(&gUnicastServerSocketFD);
+ u_mutex_unlock(gMutexUnicastServer);
- srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
- srcPort = ntohs(srcSockAddress.sin_port);
+ OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Unicast server stopped [%d]", ret);
+ return ret;
+}
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
- srcIPAddress, srcPort);
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
- gUnicastRecvBuffer, recvLen);
+#ifdef __WITH_DTLS__
+CAResult_t CAWiFiStopSecureUnicastServer()
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- // Notify data to upper layer
- if (gPacketReceivedCallback)
- {
- gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
- }
- }
+ u_mutex_lock(gMutexSecureUnicastServer);
+ gStopSecureUnicast = true;
+ CAResult_t ret = CAWiFiCloseSocket(&gSecureUnicastServerSocketFD);
+ u_mutex_unlock(gMutexSecureUnicastServer);
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
- return NULL;
+ OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Secured unicast server stopped [%d]", ret);
+ return ret;
}
+#endif
-void *CAReceiveThreadForMulticast(void *data)
+CAResult_t CAWiFiStopMulticastServer(void)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- fd_set reads;
- struct timeval timeout;
+ u_mutex_lock(gMutexMulticastServer);
- // keep listening for data
- while (!gStopMulticast)
+ if (gMulticastServerSocketFD == -1)
{
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast server is not yet started");
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_SERVER_NOT_STARTED;
+ }
- FD_ZERO(&reads);
- FD_SET(gMulticastServerSocketDescriptor, &reads);
+ gStopMulticast = true;
- int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
- if (gStopMulticast)
- {
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Multicast is called");
- break;
- }
- if ( ret < 0)
- {
- OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
- continue;
- }
- if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
- {
- continue;
- }
+ // leave the group after you are done
+ if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (char *)&gMulticastMemberReq,
+ sizeof(struct ip_mreq)))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to leave multicast group, Error code: %s\n",
+ strerror(errno));
+ }
- memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+ CAResult_t ret = CAWiFiCloseSocket(&gMulticastServerSocketFD);
+ u_mutex_unlock(gMutexMulticastServer);
- // Read data from socket
- struct sockaddr_in srcSockAddress;
- int32_t recvLen;
- socklen_t srcAddressLen = sizeof(srcSockAddress);
- if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
- COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
- &srcAddressLen)))
- {
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
- continue;
- }
- else if (0 == recvLen)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown, returning from \
- thread\n");
+ OIC_LOG_V(INFO, WIFI_SERVER_TAG, "Multicast server stopped [%d]", ret);
+ return ret;
+}
- // Notify upper layer this exception
- if (gExceptionCallback)
- {
- gExceptionCallback(CA_MULTICAST_SERVER);
- }
- return NULL;
- }
+CAResult_t CAWiFiGetUnicastServerInfo(const CABool_t isSecured, char **ipAddress,
+ int16_t *port, int32_t *serverFD)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- const char *srcIPAddress = NULL;
- int32_t srcPort = -1;
+ // Input validation
+ VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "IP address");
+ VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Port");
+ VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "Server ID");
- srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
- srcPort = ntohs(srcSockAddress.sin_port);
+ struct sockaddr_in sockAddr;
+ socklen_t len = sizeof(struct sockaddr_in);
+ if (-1 == getsockname(gUnicastServerSocketFD, (struct sockaddr *)&sockAddr, &len))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed in getsockname [%s]!", strerror(errno));
+ return CA_STATUS_FAILED;
+ }
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
- srcIPAddress, srcPort);
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
- gMulticastRecvBuffer, recvLen);
+ const char *serverAddress = inet_ntoa(sockAddr.sin_addr);
+ *ipAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) : NULL;
+ *port = ntohs(sockAddr.sin_port);
+#ifdef __WITH_DTLS__
+ *serverFD = (CA_TRUE == isSecured) ? gSecureUnicastServerSocketFD : gUnicastServerSocketFD;
+#else
+ *serverFD = gUnicastServerSocketFD;
+#endif
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
- // Notify data to upper layer
- if (gPacketReceivedCallback)
- {
- gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
- }
- }
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
- return NULL;
+ gPacketReceivedCallback = callback;
+}
+
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ gExceptionCallback = callback;
}
* @var gUnicastServerSocketDescClient
* @brief socket descriptor for unicast server
*/
-static int gUnicastServerSocketDescClient = -1;
+static int32_t gUnicastServerSocketDescClient = -1;
-void CAWiFiSetUnicastSocket(const int32_t socketFD)
-{
- OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
-
- gUnicastServerSocketDescClient = socketFD;
-}
+#ifdef __WITH_DTLS__
+/**
+ * @var gUnicastServerSocketDescClient
+ * @brief socket descriptor for secure unicast server
+ */
+static int32_t gUnicastServerSecureSocketDescClient = -1;
+#endif
-uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
- const void *data, const uint32_t dataLength, bool isMulticast)
+static uint32_t CASendData(const char *remoteAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength, int32_t sockfd)
{
OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
return 0;
}
- if (0 > gUnicastServerSocketDescClient)
+ if (0 > sockfd)
{
OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running !");
return 0;
return 0;
}
- int32_t sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLength, 0,
+ int32_t sendDataLength = sendto(sockfd, data, dataLength, 0,
(struct sockaddr *)&destAddr, sizeof(destAddr));
if (sendDataLength == -1)
{
return sendDataLength;
}
+void CAWiFiSetUnicastSocket(const int32_t socketFD)
+{
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+ gUnicastServerSocketDescClient = socketFD;
+
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
+}
+
+#ifdef __WITH_DTLS__
+void CAWiFiSetSecureUnicastSocket(const int32_t socketFD)
+{
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+ gUnicastServerSecureSocketDescClient = socketFD;
+
+ OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
+}
+#endif
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+ const void *data, const uint32_t dataLength,
+ CABool_t isMulticast, CABool_t isSecured)
+{
+ uint32_t len = 0;
+
+#ifdef __WITH_DTLS__
+ if (CA_TRUE == isSecured)
+ {
+ len = CASendData(remoteAddress, port,
+ data, dataLength, gUnicastServerSecureSocketDescClient);
+ }
+ else
+ {
+#endif
+ len = CASendData(remoteAddress, port,
+ data, dataLength, gUnicastServerSocketDescClient);
+#ifdef __WITH_DTLS__
+ }
+#endif
+ return len;
+}
+
+
return true;
}
-void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
+void CAWiFiSetConnectionStateChangeCallback(
+ CAWiFiConnectionStateChangeCallback callback)
{
OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
gNetworkChangeCb = callback;
}
-void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap, void *userData)
+void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
+ void *userData)
{
OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
wifi_ap_h accessPoint = NULL;
if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
{
- OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get connected access point! error num [%d]",
+ OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get access point! error num [%d]",
ret);
OICFree(interfaceName);
if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
ipAddress)))
{
- OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]", ret);
+ OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]",
+ ret);
OICFree(interfaceName);
u_mutex_unlock(gWifiNetInfoMutex);
#define CA_UDP_BIND_RETRY_COUNT 10
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gUnicastServerSocketFD
+ * @brief Unicast server socket descriptor
*/
-static int32_t gUnicastServerSocketDescriptor = -1;
+static int32_t gUnicastServerSocketFD = -1;
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gMutexUnicastServer
+ * @brief Mutex to synchronize unicast server
*/
-static char *gUnicastServerAddress = NULL;
+static u_mutex gMutexUnicastServer = NULL;
/**
- * @var gUnicastServerSocketDescriptor
- * @brief socket descriptor for unicast server
+ * @var gStopUnicast
+ * @brief Flag to control the Receive Unicast Data Thread
*/
-static int16_t gUnicastServerPort = -1;
+static bool gStopUnicast = false;
/**
- * @var gMutexUnicastServerSocketDescriptor
- * @brief Mutex for socket descriptor for unicast server
+ * @var gMulticastServerSocketFD
+ * @brief socket descriptor for multicast server
*/
-static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
+static int32_t gMulticastServerSocketFD = -1;
+
/**
- * @var gMulticastServerSocketDescriptor
- * @brief socket descriptor for multicast server
+ * @var gMutexMulticastServer
+ * @brief Mutex to synchronize secure multicast server
*/
-static int32_t gMulticastServerSocketDescriptor = -1;
+static u_mutex gMutexMulticastServer = NULL;
/**
- * @var gMutexMulticastServerSocketDescriptor
- * @brief Mutex for socket descriptor for Multicast server
+ * @var gStopMulticast
+ * @brief Flag to control the Receive Multicast Data Thread
*/
-static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
+static bool gStopMulticast = false;
+#ifdef __WITH_DTLS__
/**
- * @var gThreadPool
- * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ * @var gSecureUnicastServerSocketFD
+ * @brief Secure unicast server socket descriptor
*/
-static u_thread_pool_t gThreadPool = NULL;
+static int32_t gSecureUnicastServerSocketFD = -1;
/**
- * @var gMReq
- * @brief ip_mreq structure passed to join a multicast group
+ * @var gMutexUnicastServer
+ * @brief Mutex to synchronize secure unicast server
*/
-static struct ip_mreq gMReq;
+static u_mutex gMutexSecureUnicastServer = NULL;
/**
- * @var gStopUnicast
- * @brief Flag to control the Receive Unicast Data Thread
+ * @var gStopSecureUnicast
+ * @brief Flag to control the unicast secure data receive thread
*/
-static bool gStopUnicast = false;
+static bool gStopSecureUnicast = false;
/**
- * @var gMutexStopUnicast
- * @brief Mutex for gStopUnicast
+ * @var gSecureUnicastRecvBuffer
+ * @brief Character buffer used for receiving unicast data from network
*/
-static u_mutex gMutexStopUnicast = NULL;
+static char gSecureUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+#endif
/**
- * @var gStopMulticast
- * @brief Flag to control the Receive Multicast Data Thread
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
*/
-static bool gStopMulticast = false;
+static u_thread_pool_t gThreadPool = NULL;
/**
- * @var gMutexStopMulticast
- * @brief Mutex for gStopMulticast
+ * @var gMulticastMemberReq
+ * @brief ip_mreq structure passed to join a multicast group
*/
-static u_mutex gMutexStopMulticast = NULL;
+static struct ip_mreq gMulticastMemberReq;
/**
* @var gPacketReceivedCallback
*/
static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
-/**
- * @fn CAWiFiServerCreateMutex
- * @brief Creates and initializes mutex
- */
-static CAResult_t CAWiFiServerCreateMutex(void);
+static void CAUnicastReceiveHandler(void *data)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CAUnicastReceiveHandler] IN");
-/**
- * @fn CAWiFiServerDestroyMutex
- * @brief Releases all created mutex
- */
-static void CAWiFiServerDestroyMutex(void);
+ fd_set reads;
+ struct timeval timeout;
-/**
- * @fn CAReceiveThreadForMulticast
- * @brief Handler thread for receiving data on multicast server
- */
-static void *CAReceiveThreadForMulticast(void *data);
+ while (!gStopUnicast)
+ {
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
-/**
- * @fn CAWiFiReceiveThreadForUnicast
- * @brief Handler thread for receiving data on unicast server
- */
-static void *CAWiFiReceiveThreadForUnicast(void *data);
+ FD_ZERO(&reads);
+ FD_SET(gUnicastServerSocketFD, &reads);
-CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ int32_t ret = select(gUnicastServerSocketFD + 1, &reads, NULL, NULL, &timeout);
+ if (gStopUnicast)
+ {
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop request already received for unicast server");
+ break;
+ }
+ if (ret < 0)
+ {
+ OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+ continue;
+ }
+ if (!FD_ISSET(gUnicastServerSocketFD, &reads))
+ {
+ continue;
+ }
- // Input validation
- VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
+ memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
- // Initialize mutex
- if (CA_STATUS_OK != CAWiFiServerCreateMutex())
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
- return CA_STATUS_FAILED;
- }
+ // Read data from socket
+ struct sockaddr_in srcSockAddress;
+ int32_t recvLen;
+ socklen_t srcAddressLen = sizeof(srcSockAddress);
+ if (-1 == (recvLen = recvfrom(gUnicastServerSocketFD, gUnicastRecvBuffer,
+ COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+ &srcAddressLen)))
+ {
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+ continue;
+ }
+ else if (0 == recvLen)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
- gThreadPool = threadPool;
+ // Notify upper layer this exception
+ if (gExceptionCallback)
+ {
+ gExceptionCallback(CA_UNICAST_SERVER);
+ }
+ return;
+ }
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
- return CA_STATUS_OK;
-}
+ const char *srcIPAddress = NULL;
+ int32_t srcPort = -1;
-void CAWiFiTerminateServer(void)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+ srcPort = ntohs(srcSockAddress.sin_port);
- gThreadPool = NULL;
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+ srcIPAddress, srcPort);
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+ gUnicastRecvBuffer, recvLen);
- // Destroy mutex
- CAWiFiServerDestroyMutex();
+ // Notify data to upper layer
+ if (gPacketReceivedCallback)
+ {
+ gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen, false);
+ }
+ }
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CAUnicastReceiveHandler] OUT");
}
-CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
- const int16_t multicastPort, int32_t *serverFD)
+#ifdef __WITH_DTLS__
+static void CASecureUnicastReceiveHandler(void *data)
{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CASecureUnicastReceiveHandler] IN");
+
+ fd_set reads;
+ struct timeval timeout;
- if (gMulticastServerSocketDescriptor != -1)
+ while (!gStopSecureUnicast)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
- return CA_SERVER_STARTED_ALREADY;
- }
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
- VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
- VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
+ FD_ZERO(&reads);
+ FD_SET(gSecureUnicastServerSocketFD, &reads);
- if (0 >= multicastPort)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
- return CA_STATUS_INVALID_PARAM;
- }
+ int32_t ret = select(gSecureUnicastServerSocketFD + 1, &reads, NULL, NULL, &timeout);
+ if (gStopSecureUnicast)
+ {
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop request already received for secure server");
+ break;
+ }
- // Create a datagram socket on which to recv/send.
- u_mutex_lock(gMutexStopMulticast);
- gStopMulticast = false;
- u_mutex_unlock(gMutexStopMulticast);
+ if (ret < 0)
+ {
+ OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+ continue;
+ }
- u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+ if (!FD_ISSET(gSecureUnicastServerSocketFD, &reads))
+ {
+ continue;
+ }
- // create a UDP socket
- if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
- strerror(errno));
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
- }
+ memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
- // Make the socket non-blocking
- if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
- strerror(errno));
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_STATUS_FAILED;
- }
+ // Read data from socket
+ struct sockaddr_in srcSockAddress;
+ int32_t recvLen;
+ socklen_t srcAddressLen = sizeof(srcSockAddress);
+ if (-1 == (recvLen = recvfrom(gSecureUnicastServerSocketFD, gSecureUnicastRecvBuffer,
+ COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+ &srcAddressLen)))
+ {
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+ continue;
+ }
+ else if (0 == recvLen)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
+ // Notify upper layer this exception
+ if (gExceptionCallback)
+ {
+ gExceptionCallback(CA_UNICAST_SERVER);
+ }
+ return;
+ }
- int32_t setOptionOn = 1;
- if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
- (char *) &setOptionOn,
- sizeof(setOptionOn)))
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
- strerror(errno));
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
- }
+ const char *srcIPAddress = NULL;
+ int32_t srcPort = -1;
- struct sockaddr_in sockAddr;
- memset((char *) &sockAddr, 0, sizeof(sockAddr));
+ srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+ srcPort = ntohs(srcSockAddress.sin_port);
- sockAddr.sin_family = AF_INET;
- sockAddr.sin_port = htons(multicastPort);
- sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+ srcIPAddress, srcPort);
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+ gSecureUnicastRecvBuffer, recvLen);
- // bind socket to multicast port
- if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
- sizeof(sockAddr)))
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
- CA_SOCKET_OPERATION_FAILED);
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
+ CAResult_t result = CAAdapterNetDtlsDecrypt(srcIPAddress,
+ srcPort,
+ gSecureUnicastRecvBuffer,
+ recvLen);
+
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, " CAAdapterNetDtlsDecrypt returns [%d]", result);
}
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "[CASecureUnicastReceiveHandler] OUT");
+}
+#endif
- // Add membership to receiving socket (join group)
- memset(&gMReq, 0, sizeof(struct ip_mreq));
- gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
- inet_aton(multicastAddress, &gMReq.imr_multiaddr);
+static void CAMulticastReceiveHandler(void *data)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (char *) &gMReq,
- sizeof(struct ip_mreq)))
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
- strerror(errno));
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
- }
+ fd_set reads;
+ struct timeval timeout;
- /**
- * The task to listen to data from multicastcast socket is added to the thread pool.
- * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
- * This task will be terminated when thread pool is freed on stopping the adapters.
- */
- if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
- (void *)NULL))
+ while (!gStopMulticast)
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
- close(gMulticastServerSocketDescriptor);
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_STATUS_FAILED;
- }
+ FD_ZERO(&reads);
+ FD_SET(gMulticastServerSocketFD, &reads);
- *serverFD = gMulticastServerSocketDescriptor;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+ int32_t ret = select(gMulticastServerSocketFD + 1, &reads, NULL, NULL, &timeout);
+ if (gStopMulticast)
+ {
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop request already received for multicast server");
+ break;
+ }
+ if ( ret < 0)
+ {
+ OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+ continue;
+ }
+ if (!FD_ISSET(gMulticastServerSocketFD, &reads))
+ {
+ continue;
+ }
- OIC_LOG(INFO, WIFI_SERVER_TAG, "thread_pool_add_task done");
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Started Successfully");
+ memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
- return CA_STATUS_OK;
+ // Read data from socket
+ struct sockaddr_in srcSockAddress;
+ int32_t recvLen;
+ socklen_t srcAddressLen = sizeof(srcSockAddress);
+ if (-1 == (recvLen = recvfrom(gMulticastServerSocketFD, gMulticastRecvBuffer,
+ COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+ &srcAddressLen)))
+ {
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+ continue;
+ }
+ else if (0 == recvLen)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown!\n");
-}
+ // Notify upper layer this exception
+ if (gExceptionCallback)
+ {
+ gExceptionCallback(CA_MULTICAST_SERVER);
+ }
+ return;
+ }
-CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
- const bool forceStart, int32_t *serverFD)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ const char *srcIPAddress = NULL;
+ int32_t srcPort = -1;
- if (gUnicastServerSocketDescriptor != -1)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
- CA_SERVER_STARTED_ALREADY);
- return CA_SERVER_STARTED_ALREADY;
- }
+ srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+ srcPort = ntohs(srcSockAddress.sin_port);
+
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+ srcIPAddress, srcPort);
+ OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+ gMulticastRecvBuffer, recvLen);
- VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Invalid argument : localAddress is NULL");
- VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Invalid argument : port is NULL");
- if (0 >= port)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
- return CA_STATUS_INVALID_PARAM;
+ // Notify data to upper layer
+ if (gPacketReceivedCallback)
+ {
+ gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen, false);
+ }
}
- u_mutex_lock(gMutexStopUnicast);
- gStopUnicast = false;
- u_mutex_unlock(gMutexStopUnicast);
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+}
+
+static CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, u_thread_func receiveThread,
+ int32_t *serverFD)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ int32_t socketFD = -1;
- u_mutex_lock(gMutexUnicastServerSocketDescriptor);
// Create a UDP socket
- if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+ if (-1 == (socketFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to create Socket, Error code: %s",
strerror(errno));
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
+ return CA_STATUS_FAILED;
}
// Make the socket non-blocking
- if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+ if (-1 == fcntl(socketFD, F_SETFL, O_NONBLOCK))
{
OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
strerror(errno));
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+ close(socketFD);
return CA_STATUS_FAILED;
}
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
-
if (true == forceStart)
{
int32_t setOptionOn = 1;
- if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+ if (-1 == setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR,
(char *) &setOptionOn,
sizeof(setOptionOn)))
{
OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
strerror(errno));
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
+
+ close(socketFD);
+ return CA_STATUS_FAILED;
}
}
sockAddr.sin_port = htons(serverPort);
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- // Trying for bind in a loop
int16_t i;
for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
{
- if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+ if (-1 == bind(socketFD, (struct sockaddr *) &sockAddr,
sizeof(sockAddr)))
{
if (false == forceStart)
OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ",
strerror(errno));
- // Set the port to next one
+ //Set the port to next one
serverPort += 1;
sockAddr.sin_port = htons(serverPort);
continue;
if (false == isBound)
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
- CA_SOCKET_OPERATION_FAILED);
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- return CA_SOCKET_OPERATION_FAILED;
+ close(socketFD);
+ return CA_STATUS_FAILED;
+ }
+
+ *port = serverPort;
+ *serverFD = socketFD;
+
+ /**
+ * The task to listen for data from unicast socket is added to the thread pool.
+ * This is a blocking call is made where we try to receive some data..
+ * We will keep waiting until some data is received.
+ * This task will be terminated when thread pool is freed on stopping the adapters.
+ */
+ if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, receiveThread, NULL))
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create read thread!");
+
+ close(socketFD);
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+static void CAWiFiServerDestroyMutex(void)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ if (gMutexUnicastServer)
+ {
+ u_mutex_free(gMutexUnicastServer);
+ gMutexUnicastServer = NULL;
+ }
+
+#ifdef __WITH_DTLS__
+ if (gMutexSecureUnicastServer)
+ {
+ u_mutex_free(gMutexSecureUnicastServer);
+ gMutexSecureUnicastServer = NULL;
+ }
+#endif
+
+ if (gMutexMulticastServer)
+ {
+ u_mutex_free(gMutexMulticastServer);
+ gMutexMulticastServer = NULL;
+ }
+
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+}
+
+static CAResult_t CAWiFiServerCreateMutex(void)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ gMutexUnicastServer = u_mutex_new();
+ if (!gMutexUnicastServer)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+ return CA_STATUS_FAILED;
+ }
+
+#ifdef __WITH_DTLS__
+ gMutexSecureUnicastServer = u_mutex_new();
+ if (!gMutexSecureUnicastServer)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+ return CA_STATUS_FAILED;
+ }
+#endif
+
+ gMutexMulticastServer = u_mutex_new();
+ if (!gMutexMulticastServer)
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+ CAWiFiServerDestroyMutex();
+ return CA_STATUS_FAILED;
+ }
+
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ // Input validation
+ VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
+
+ // Initialize mutex
+ if (CA_STATUS_OK != CAWiFiServerCreateMutex())
+ {
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
+ return CA_STATUS_FAILED;
+ }
+
+ gThreadPool = threadPool;
+
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateServer(void)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ gThreadPool = NULL;
+
+ // Destroy mutex
+ CAWiFiServerDestroyMutex();
+
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+}
+
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+ const bool forceStart, const CABool_t isSecured,
+ int32_t *serverFD)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ // Input validation
+ VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "localAddress");
+ VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port");
+ VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "server socket FD");
+
+ if (0 >= *port)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ *serverFD = -1;
+ if (CA_FALSE == isSecured)
+ {
+ u_mutex_lock(gMutexUnicastServer);
+ if (-1 != gUnicastServerSocketFD)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already!",
+ CA_SERVER_STARTED_ALREADY);
+
+ *serverFD = gUnicastServerSocketFD;
+ u_mutex_unlock(gMutexUnicastServer);
+ return CA_SERVER_STARTED_ALREADY;
+ }
+
+ gStopUnicast = false;
+ if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart,
+ CAUnicastReceiveHandler, &gUnicastServerSocketFD))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
+ gUnicastServerSocketFD = -1;
+ u_mutex_unlock(gMutexUnicastServer);
+ return CA_STATUS_FAILED;
+ }
+
+ *serverFD = gUnicastServerSocketFD;
+ u_mutex_unlock(gMutexUnicastServer);
+ }
+#ifdef __WITH_DTLS__
+ else // Start unicast server for secured communication
+ {
+ u_mutex_lock(gMutexSecureUnicastServer);
+ if (-1 != gSecureUnicastServerSocketFD)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already!",
+ CA_SERVER_STARTED_ALREADY);
+
+ *serverFD = gSecureUnicastServerSocketFD;
+ u_mutex_unlock(gMutexSecureUnicastServer);
+ return CA_SERVER_STARTED_ALREADY;
+ }
+
+ gStopSecureUnicast = false;
+ if (CA_STATUS_OK != CAStartUnicastServer(localAddress, port, forceStart,
+ CASecureUnicastReceiveHandler, &gSecureUnicastServerSocketFD))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to start unicast server!");
+ gSecureUnicastServerSocketFD = -1;
+ u_mutex_unlock(gMutexSecureUnicastServer);
+ return CA_STATUS_FAILED;
+ }
+
+ *serverFD = gSecureUnicastServerSocketFD;
+ u_mutex_unlock(gMutexSecureUnicastServer);
+ }
+#endif
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+ const int16_t multicastPort, int32_t *serverFD)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+ // Input validation
+ VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
+ VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
+
+ if (0 >= multicastPort)
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
+ return CA_STATUS_INVALID_PARAM;
}
- OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+ u_mutex_lock(gMutexMulticastServer);
- socklen_t len;
- char *serverAddress = NULL;
- if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
+ if (gMulticastServerSocketFD != -1)
{
- serverPort = ntohs(sockAddr.sin_port);
- serverAddress = inet_ntoa(sockAddr.sin_addr);
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
+ return CA_SERVER_STARTED_ALREADY;
}
- /**
- * The task to listen for data from unicast socket is added to the thread pool.
- * This is a blocking call is made where we try to receive some data..
- * We will keep waiting until some data is received.
- * This task will be terminated when thread pool is freed on stopping the adapters.
- */
- if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAWiFiReceiveThreadForUnicast,
- (void *) NULL))
+ if ((gMulticastServerSocketFD = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+ strerror(errno));
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_STATUS_FAILED;
+ }
- close(gUnicastServerSocketDescriptor);
- gUnicastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+ // Make the socket non-blocking
+ if (-1 == fcntl(gMulticastServerSocketFD, F_SETFL, O_NONBLOCK))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
+ strerror(errno));
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ u_mutex_unlock(gMutexMulticastServer);
return CA_STATUS_FAILED;
}
- // Free the server address previously stored
- OICFree(gUnicastServerAddress);
- gUnicastServerAddress = NULL;
- gUnicastServerPort = serverPort;
- gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
- NULL;
- *port = serverPort;
- *serverFD = gUnicastServerSocketDescriptor;
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Started Successfully");
- return CA_STATUS_OK;
-}
+ int32_t setOptionOn = 1;
+ if (-1 == setsockopt(gMulticastServerSocketFD, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &setOptionOn,
+ sizeof(setOptionOn)))
+ {
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
+ strerror(errno));
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_STATUS_FAILED;
+ }
-CAResult_t CAWiFiStopMulticastServer(void)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+ struct sockaddr_in sockAddr;
+ memset((char *) &sockAddr, 0, sizeof(sockAddr));
- u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+ sockAddr.sin_family = AF_INET;
+ sockAddr.sin_port = htons(multicastPort);
+ sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- if (gMulticastServerSocketDescriptor == -1)
+ // bind socket to multicast port
+ if (-1 == bind(gMulticastServerSocketFD, (struct sockaddr *) &sockAddr,
+ sizeof(sockAddr)))
{
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server is not yet Started");
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- return CA_SERVER_NOT_STARTED;
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket!");
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_STATUS_FAILED;
}
- u_mutex_lock(gMutexStopMulticast);
- gStopMulticast = true;
+ // Add membership to receiving socket (join group)
+ memset(&gMulticastMemberReq, 0, sizeof(struct ip_mreq));
+ gMulticastMemberReq.imr_interface.s_addr = htonl(INADDR_ANY);
+ inet_aton(multicastAddress, &gMulticastMemberReq.imr_multiaddr);
- // leave the group after you are done
- if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
- (char *)&gMReq,
+ if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *) &gMulticastMemberReq,
sizeof(struct ip_mreq)))
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
strerror(errno));
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_STATUS_FAILED;
}
- // close the socket
- if (-1 == close(gMulticastServerSocketDescriptor))
+ /**
+ * The task to listen to data from multicastcast socket is added to the thread pool.
+ * This is a blocking call is made where we try to receive some data.
+ * We will keep waiting until some data is received.
+ * This task will be terminated when thread pool is freed on stopping the adapters.
+ */
+ gStopMulticast = false;
+ if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, CAMulticastReceiveHandler, NULL))
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
- strerror(errno));
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
- u_mutex_unlock(gMutexStopMulticast);
- return CA_SOCKET_OPERATION_FAILED;
- }
-
- u_mutex_unlock(gMutexStopMulticast);
+ OIC_LOG(ERROR, WIFI_SERVER_TAG, "thread_pool_add_task failed!");
- gMulticastServerSocketDescriptor = -1;
- u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+ close(gMulticastServerSocketFD);
+ gMulticastServerSocketFD = -1;
+ gStopMulticast = true;
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_STATUS_FAILED;
+ }
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Stopped Successfully");
+ *serverFD = gMulticastServerSocketFD;
+ u_mutex_unlock(gMutexMulticastServer);
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
return CA_STATUS_OK;
-
}
CAResult_t CAWiFiStopUnicastServer()
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- u_mutex_lock(gMutexUnicastServerSocketDescriptor);
- if (gUnicastServerSocketDescriptor == -1)
+ u_mutex_lock(gMutexUnicastServer);
+ if (-1 == gUnicastServerSocketFD)
{
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server is not yet Started");
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast server is not yet started");
+ u_mutex_unlock(gMutexUnicastServer);
return CA_SERVER_NOT_STARTED;
}
- u_mutex_lock(gMutexStopUnicast);
+
gStopUnicast = true;
// close the socket
- if (-1 == close(gUnicastServerSocketDescriptor))
+ if (-1 == close(gUnicastServerSocketFD))
{
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close socket, Error code: %s\n",
strerror(errno));
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
- u_mutex_unlock(gMutexStopUnicast);
- return CA_SOCKET_OPERATION_FAILED;
+ u_mutex_unlock(gMutexUnicastServer);
+ return CA_STATUS_FAILED;
}
- u_mutex_unlock(gMutexStopUnicast);
- gUnicastServerSocketDescriptor = -1;
-
- u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
-
- OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Stopped Successfully");
- return CA_STATUS_OK;
-}
-
-CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-
- // Input validation
- VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "ipAddress holder is NULL");
- VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port holder is NULL");
- VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "serverID holder is NULL");
-
- *ipAddress = gUnicastServerAddress;
- *port = gUnicastServerPort;
- *serverFD = gUnicastServerSocketDescriptor;
+ gUnicastServerSocketFD = -1;
+ u_mutex_unlock(gMutexUnicastServer);
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast server stopped successfully");
return CA_STATUS_OK;
}
-void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-
- gPacketReceivedCallback = callback;
-}
-
-void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
-{
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-
- gExceptionCallback = callback;
-}
-
-CAResult_t CAWiFiServerCreateMutex(void)
+#ifdef __WITH_DTLS__
+CAResult_t CAWiFiStopSecureUnicastServer()
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- gMutexUnicastServerSocketDescriptor = u_mutex_new();
- if (!gMutexUnicastServerSocketDescriptor)
+ u_mutex_lock(gMutexSecureUnicastServer);
+ if (-1 == gSecureUnicastServerSocketFD)
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
- return CA_STATUS_FAILED;
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Secure unicast server is not yet started");
+ u_mutex_unlock(gMutexSecureUnicastServer);
+ return CA_SERVER_NOT_STARTED;
}
- gMutexMulticastServerSocketDescriptor = u_mutex_new();
- if (!gMutexMulticastServerSocketDescriptor)
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
-
- CAWiFiServerDestroyMutex();
- return CA_STATUS_FAILED;
- }
+ gStopSecureUnicast = true;
- gMutexStopUnicast = u_mutex_new();
- if (!gMutexStopUnicast)
+ // close the socket
+ if (-1 == close(gSecureUnicastServerSocketFD))
{
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
-
- CAWiFiServerDestroyMutex();
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
+ strerror(errno));
+ u_mutex_unlock(gMutexSecureUnicastServer);
return CA_STATUS_FAILED;
}
- gMutexStopMulticast = u_mutex_new();
- if (!gMutexStopMulticast)
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
-
- CAWiFiServerDestroyMutex();
- return CA_STATUS_FAILED;
- }
+ gSecureUnicastServerSocketFD = -1;
+ u_mutex_unlock(gMutexSecureUnicastServer);
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Secure unicast server stopped successfully");
return CA_STATUS_OK;
}
+#endif
-void CAWiFiServerDestroyMutex(void)
+CAResult_t CAWiFiStopMulticastServer(void)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- if (gMutexUnicastServerSocketDescriptor)
- {
- u_mutex_free(gMutexUnicastServerSocketDescriptor);
- gMutexUnicastServerSocketDescriptor = NULL;
- }
+ u_mutex_lock(gMutexMulticastServer);
- if (gMutexMulticastServerSocketDescriptor)
+ if (gMulticastServerSocketFD == -1)
{
- u_mutex_free(gMutexMulticastServerSocketDescriptor);
- gMutexMulticastServerSocketDescriptor = NULL;
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast server is not yet started");
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_SERVER_NOT_STARTED;
}
- if (gMutexStopUnicast)
+ gStopMulticast = true;
+
+ // leave the group after you are done
+ if (-1 == setsockopt(gMulticastServerSocketFD, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+ (char *)&gMulticastMemberReq,
+ sizeof(struct ip_mreq)))
{
- u_mutex_free(gMutexStopUnicast);
- gMutexStopUnicast = NULL;
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to leave multicast group, Error code: %s\n",
+ strerror(errno));
}
- if (gMutexStopMulticast)
+ // close the socket
+ if (-1 == close(gMulticastServerSocketFD))
{
- u_mutex_free(gMutexStopMulticast);
- gMutexStopMulticast = NULL;
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to close the socket, Error code: %s\n",
+ strerror(errno));
+ u_mutex_unlock(gMutexMulticastServer);
+ return CA_SOCKET_OPERATION_FAILED;
}
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+ gMulticastServerSocketFD = -1;
+ u_mutex_unlock(gMutexMulticastServer);
+
+ OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast server stopped successfully");
+ return CA_STATUS_OK;
}
-void *CAWiFiReceiveThreadForUnicast(void *data)
+CAResult_t CAWiFiGetUnicastServerInfo(const CABool_t isSecured, char **ipAddress,
+ int16_t *port, int32_t *serverFD)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- fd_set reads;
- struct timeval timeout;
+ // Input validation
+ VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "IP address");
+ VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Port");
+ VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "Server ID");
- // keep listening for data
- while (!gStopUnicast)
+ struct sockaddr_in sockAddr;
+ socklen_t len = sizeof(struct sockaddr_in);
+ if (-1 == getsockname(gUnicastServerSocketFD, (struct sockaddr *)&sockAddr, &len))
{
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
-
- FD_ZERO(&reads);
- FD_SET(gUnicastServerSocketDescriptor, &reads);
-
- int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
- if (gStopUnicast)
- {
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Unicast is called");
- break;
- }
- if (ret < 0)
- {
- OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
- continue;
- }
- if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
- {
- continue;
- }
-
- memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
-
- // Read data from socket
- struct sockaddr_in srcSockAddress;
- int32_t recvLen;
- socklen_t srcAddressLen = sizeof(srcSockAddress);
- if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
- COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
- &srcAddressLen)))
- {
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
- continue;
- }
- else if (0 == recvLen)
- {
- OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
-
- // Notify upper layer this exception
- if (gExceptionCallback)
- {
- gExceptionCallback(CA_UNICAST_SERVER);
- }
- return NULL;
- }
-
- const char *srcIPAddress = NULL;
- int32_t srcPort = -1;
-
- srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
- srcPort = ntohs(srcSockAddress.sin_port);
-
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
- srcIPAddress, srcPort);
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
- gUnicastRecvBuffer, recvLen);
-
- // Notify data to upper layer
- if (gPacketReceivedCallback)
- {
- gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
- }
+ OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed in getsockname [%s]!", strerror(errno));
+ return CA_STATUS_FAILED;
}
+
+ const char *serverAddress = inet_ntoa(sockAddr.sin_addr);
+ *ipAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) : NULL;
+ *port = ntohs(sockAddr.sin_port);
+#ifdef __WITH_DTLS__
+ *serverFD = (CA_TRUE == isSecured) ? gSecureUnicastServerSocketFD : gUnicastServerSocketFD;
+#else
+ *serverFD = gUnicastServerSocketFD;
+#endif
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
- return NULL;
+ return CA_STATUS_OK;
}
-void *CAReceiveThreadForMulticast(void *data)
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
{
OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- fd_set reads;
- struct timeval timeout;
-
- // keep listening for data
- while (!gStopMulticast)
- {
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
-
- FD_ZERO(&reads);
- FD_SET(gMulticastServerSocketDescriptor, &reads);
-
- int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
- if (gStopMulticast)
- {
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Multicast is called");
- break;
- }
- if ( ret < 0)
- {
- OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
- continue;
- }
- if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
- {
- continue;
- }
-
- memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
-
- // Read data from socket
- struct sockaddr_in srcSockAddress;
- int32_t recvLen;
- socklen_t srcAddressLen = sizeof(srcSockAddress);
- if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
- COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
- &srcAddressLen)))
- {
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
- continue;
- }
- else if (0 == recvLen)
- {
- OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown, returning from \
- thread\n");
-
- // Notify upper layer this exception
- if (gExceptionCallback)
- {
- gExceptionCallback(CA_MULTICAST_SERVER);
- }
- return NULL;
- }
-
- const char *srcIPAddress = NULL;
- int32_t srcPort = -1;
-
- srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
- srcPort = ntohs(srcSockAddress.sin_port);
-
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
- srcIPAddress, srcPort);
- OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
- gMulticastRecvBuffer, recvLen);
-
+ gPacketReceivedCallback = callback;
+}
- // Notify data to upper layer
- if (gPacketReceivedCallback)
- {
- gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
- }
- }
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
+{
+ OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
- OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
- return NULL;
+ gExceptionCallback = callback;
}
//Bt callbacks
-CALocalConnectivity_t* localBtEndpoint = NULL;
+CALocalConnectivity_t *localBtEndpoint = NULL;
CARemoteEndpoint_t remoteMulticastEndpoint;
CARemoteEndpoint_t remoteEndpoint[10]; /* 10 RemoteEndpoints are currently kept */
-char remoteIPAddress[CA_IPADDR_SIZE] = "192.168.1.8"; //Change the Corresponding IP address during testing.
+char remoteIPAddress[CA_IPADDR_SIZE] =
+ "192.168.1.8"; //Change the Corresponding IP address during testing.
char localIPAddress[CA_IPADDR_SIZE] = {0};
int localPort = -1;
int32_t serverId;
// Global bt Addr. Change this before testing.
char btAddr[CA_MACADDR_SIZE] = "BC:79:AD:E6:BC:F6";
-char* serviceUUID = "12341234-1C25-481F-9DFB-59193D238280";
+char *serviceUUID = "12341234-1C25-481F-9DFB-59193D238280";
//static GMainLoop *mainloop;
//int gMainloopStatus = 0;
//Hardcoded values to Test
-char coapData[500] = "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}\]}";
+char coapData[500] =
+ "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}\]}";
-typedef struct ConnectivityHandlerList {
+typedef struct ConnectivityHandlerList
+{
CAConnectivityType_t type;
CAConnectivityHandler_t handler;
- struct ConnectivityHandlerList* nextHandler;
+ struct ConnectivityHandlerList *nextHandler;
} ConnectivityHandlerList;
-CAConnectivityHandler_t* gConnectivityHandlers = NULL;
+CAConnectivityHandler_t *gConnectivityHandlers = NULL;
-void storeInterfaceCallbacks(CAConnectivityHandler_t* newHandler)
+void storeInterfaceCallbacks(CAConnectivityHandler_t *newHandler)
{
printf("\nstoreInterfaceCallbacks Entry in Sample");
- #if 0
+#if 0
newHandler->nextHandler = NULL;
- CAConnectivityHandler* tempCAConnectivityHandlers = gCAConnectivityHandlers;
+ CAConnectivityHandler *tempCAConnectivityHandlers = gCAConnectivityHandlers;
- if (!tempCAConnectivityHandlers) {
+ if (!tempCAConnectivityHandlers)
+ {
gCAConnectivityHandlers = newHandler;
return;
}
- while (tempCAConnectivityHandlers->nextHandler) {
+ while (tempCAConnectivityHandlers->nextHandler)
+ {
tempCAConnectivityHandlers = tempCAConnectivityHandlers->nextHandler;
}
tempCAConnectivityHandlers->nextHandler = newHandler;
- #endif
+#endif
printf("\nstoreInterfaceCallbacks Exit in Sample");
}
CAConnectivityType_t connType)
{
printf("interfaceRegisterCallback Entry in Sample\n");
- ConnectivityHandlerList* newConnectivityHandler = (ConnectivityHandlerList*) malloc(sizeof(ConnectivityHandlerList));
+ ConnectivityHandlerList *newConnectivityHandler = (ConnectivityHandlerList *) malloc(sizeof(
+ ConnectivityHandlerList));
if (NULL == newConnectivityHandler)
{
printf("Memory allocation failed!\n");
printf("interfaceRegisterCallback Exit in Sample\n");
}
-void requestResponseHandler(CARemoteEndpoint_t* object, void* data)
+void requestResponseHandler(CARemoteEndpoint_t *object, void *data)
{
printf("\nrequestResponseHandler Entry in Sample");
- if (object == NULL || data == NULL) {
+ if (object == NULL || data == NULL)
+ {
printf("\nNULL Object");
return;
}
if (object->addressInfo.BT.btMacAddress)
printf("\nData Received from %s\n", object->addressInfo.BT.btMacAddress);
if (data)
- printf("\nReceived Data : %s \n", (char*)data);
+ printf("\nReceived Data : %s \n", (char *)data);
/*
gMainloopStatus = 1;
if (mainloop)
}
-void networkInterfaceCallback(CALocalConnectivity_t* localEndPoint, CANetworkStatus_t networkConnectivityState)
+void networkInterfaceCallback(CALocalConnectivity_t *localEndPoint,
+ CANetworkStatus_t networkConnectivityState)
{
printf("\nnetworkInterfaceCallback Entry in Sample");
- if (localEndPoint == NULL) {
+ if (localEndPoint == NULL)
+ {
printf("\nNULL Object");
return;
}
int bt_tc_001_intializeBT_p(void)
{
CAResult_t error = CA_STATUS_FAILED;
- error = CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
+ error = CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler,
+ networkInterfaceCallback);
assert_eq(error, CA_STATUS_OK);
- CATerminateEDR();
+ CATerminateEDR();
return 0;
}
CAResult_t error = CA_STATUS_FAILED;
//Startup
CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
- uint32_t size = 0;
+ uint32_t size = 0;
- error = CAGetEDRInterfaceInformation(&localBtEndpoint,&size);
+ error = CAGetEDRInterfaceInformation(&localBtEndpoint, &size);
assert_eq(error, CA_STATUS_OK);
- CATerminateEDR();
+ CATerminateEDR();
// Now, check local endpoint information
//assert_neq(localBtEndpoint->endpoint_info, NULL);
//assert_neq(localBtEndpoint->endpoint_info->address, NULL);
int bt_tc_004_getBTInterfaceInformation_n(void)
{
CAResult_t error = CA_STATUS_FAILED;
- error = CAGetEDRInterfaceInformation(NULL,NULL);
+ error = CAGetEDRInterfaceInformation(NULL, NULL);
assert_eq(error, CA_STATUS_INVALID_PARAM);
return 0;
}
int bt_tc_005_startAdapter_p(void)
{
CAResult_t error = CA_STATUS_FAILED;
- CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
- error = CAStartEDR();
+ CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
+ error = CAStartEDR();
assert_eq(error, CA_STATUS_OK);
- CAStopEDR();
- CATerminateEDR();
+ CAStopEDR();
+ CATerminateEDR();
return 0;
}
//Startup
CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
- CAStartEDR();
- CAStartEDRListeningServer();
+ CAStartEDR();
+ CAStartEDRListeningServer();
- CARemoteEndpoint_t endpoint;
- endpoint.connectivityType = CA_EDR;
- strncpy(endpoint.addressInfo.BT.btMacAddress, btAddr, CA_MACADDR_SIZE-1);
- endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE-1] = '\0';
+ CARemoteEndpoint_t endpoint;
+ endpoint.connectivityType = CA_EDR;
+ strncpy(endpoint.addressInfo.BT.btMacAddress, btAddr, CA_MACADDR_SIZE - 1);
+ endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
endpoint.resourceUri = NULL;
ret = CASendEDRUnicastData(&endpoint, coapData, strlen(coapData) + 1);
sleep(5);
{
int dataSize = 0;
int ret = -1;
- CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
+ CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
ret = CASendEDRUnicastData(NULL, NULL, NULL);
CATerminateEDR();
assert_eq(ret, 0);
{
int dataSize = 0;
int ret = 0;
- CAStartEDRListeningServer();
+ CAStartEDRListeningServer();
ret = CASendEDRMulticastData(coapData, strlen(coapData) + 1);
assert_eq(ret, strlen(coapData) + 1);
- CAStopEDR();
+ CAStopEDR();
CATerminateEDR();
return 0;
}
{
int dataSize = 0;
int ret = -1;
- CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
+ CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
ret = CASendEDRMulticastData(NULL, NULL);
- CATerminateEDR();
+ CATerminateEDR();
assert_eq(ret, 0);
return 0;
}
#include <string.h>
#include "tct-liboic-core.h"
-int main(int argc, const char* argv[])
+int main(int argc, const char *argv[])
{
int result = -1;
int i;
- if (argc != 2) {
+ if (argc != 2)
+ {
printf("Usage: %s <testcase name>\n", argv[0]);
return 2;
}
- for (i = 0; tc_array[i].name; i++) {
- if (!strcmp(argv[1], tc_array[i].name)) {
+ for (i = 0; tc_array[i].name; i++)
+ {
+ if (!strcmp(argv[1], tc_array[i].name))
+ {
if (tc_array[i].startup)
tc_array[i].startup();
extern int wifi_tc_010_startWifiServers_n(void);
extern int wifi_tc_011_stopWifiServers_p(void);
-testcase tc_array[] = {
+testcase tc_array[] =
+{
{"wifi_tc_001_initializeWifi_p", wifi_tc_001_initializeWifi_p, utc_liboic_startup, utc_liboic_cleanup},
{"wifi_tc_002_initializeWifi_n", wifi_tc_002_initializeWifi_n, utc_liboic_startup, utc_liboic_cleanup},
{"wifi_tc_003_getWIFIInterfaceInformation_p", wifi_tc_003_getWIFIInterfaceInformation_p, utc_liboic_startup, utc_liboic_cleanup},
//Wifi callbacks
-CALocalConnectivity* localWifiEndpoint = NULL;
+CALocalConnectivity *localWifiEndpoint = NULL;
CARemoteEndpoint remoteMulticastEndpoint;
CARemoteEndpoint remoteEndpoint[10]; /* 10 RemoteEndpoints are currently kept */
-char remoteIPAddress[CA_IPADDR_SIZE] = "192.168.1.103"; //Change the Corresponding IP address during testing.
+char remoteIPAddress[CA_IPADDR_SIZE] =
+ "192.168.1.103"; //Change the Corresponding IP address during testing.
char localIPAddress[CA_IPADDR_SIZE] = {0};
int localPort = -1;
int32_t serverId;
//int gMainloopStatus = 0;
//Hardcoded values to Test
-typedef struct ConnectivityHandlerList {
+typedef struct ConnectivityHandlerList
+{
CAConnectivityType type;
CAConnectivityHandler handler;
- struct ConnectivityHandlerList* nextHandler;
+ struct ConnectivityHandlerList *nextHandler;
} ConnectivityHandlerList;
-char coapData[500] = "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}\]}";
+char coapData[500] =
+ "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}\]}";
-#define CA_PORT 5283
+#define CA_PORT 5683
#define CA_MCAST_PORT 5298
/**
#define CA_MULTICAST_IP "224.0.1.187"
-CAConnectivityHandler* gCAConnectivityHandlers = NULL;
+CAConnectivityHandler *gCAConnectivityHandlers = NULL;
int interfaceInitializeEndpoint(int d)
{
- int i = 0;
+ int i = 0;
/* As of initializing one endpoint */
for (i = 0; i < 1; i++)
{
remoteEndpoint[i].connectivityType = CA_WIFI;
strncpy(remoteEndpoint[i].addressInfo.IP.ipAddress, remoteIPAddress, CA_IPADDR_SIZE);
- remoteEndpoint[i].addressInfo.IP.port = 5283; /* Send the corresponding port here */
+ remoteEndpoint[i].addressInfo.IP.port = 5683; /* Send the corresponding port here */
}
remoteMulticastEndpoint.connectivityType = CA_WIFI;
}
-void storeInterfaceCallbacks(CAConnectivityHandler* newHandler)
+void storeInterfaceCallbacks(CAConnectivityHandler *newHandler)
{
printf("\nstoreInterfaceCallbacks Entry in Sample");
- #if 0
+#if 0
newHandler->nextHandler = NULL;
- CAConnectivityHandler* tempCAConnectivityHandlers = gCAConnectivityHandlers;
+ CAConnectivityHandler *tempCAConnectivityHandlers = gCAConnectivityHandlers;
- if (!tempCAConnectivityHandlers) {
+ if (!tempCAConnectivityHandlers)
+ {
gCAConnectivityHandlers = newHandler;
return;
}
- while (tempCAConnectivityHandlers->nextHandler) {
+ while (tempCAConnectivityHandlers->nextHandler)
+ {
tempCAConnectivityHandlers = tempCAConnectivityHandlers->nextHandler;
}
tempCAConnectivityHandlers->nextHandler = newHandler;
- #endif
+#endif
printf("\nstoreInterfaceCallbacks Exit in Sample");
}
{
printf("\ninterfaceRegisterCallback Entry in Sample");
CAConnectivityHandler newCAConnectivityHandler;
- newCAConnectivityHandler.start = handler.start;
- newCAConnectivityHandler.stop = handler.stop;
- newCAConnectivityHandler.startAdapter = handler.startAdapter;
- newCAConnectivityHandler.sendData= handler.sendData;
- newCAConnectivityHandler.sendDataToAll= handler.sendDataToAll;
- newCAConnectivityHandler.statNotifyServer= handler.statNotifyServer;
- newCAConnectivityHandler.sendNotification= handler.sendNotification;
- newCAConnectivityHandler.GetnetInfo= handler.GetnetInfo;
- //newCAConnectivityHandler.cType= cType;
- storeInterfaceCallbacks(&newCAConnectivityHandler);
+ newCAConnectivityHandler.start = handler.start;
+ newCAConnectivityHandler.stop = handler.stop;
+ newCAConnectivityHandler.startAdapter = handler.startAdapter;
+ newCAConnectivityHandler.sendData= handler.sendData;
+ newCAConnectivityHandler.sendDataToAll= handler.sendDataToAll;
+ newCAConnectivityHandler.statNotifyServer= handler.statNotifyServer;
+ newCAConnectivityHandler.sendNotification= handler.sendNotification;
+ newCAConnectivityHandler.GetnetInfo= handler.GetnetInfo;
+ //newCAConnectivityHandler.cType= cType;
+ storeInterfaceCallbacks(&newCAConnectivityHandler);
printf("\ninterfaceRegisterCallback Exit in Sample");
}
*/
printf("interfaceRegisterCallback Entry in Sample\n");
// connectivity Handlerlist is not used
#if 0
- ConnectivityHandlerList* newConnectivityHandler = (ConnectivityHandlerList*) malloc(sizeof(ConnectivityHandlerList));
+ ConnectivityHandlerList *newConnectivityHandler = (ConnectivityHandlerList *) malloc(sizeof(
+ ConnectivityHandlerList));
if (NULL == newConnectivityHandler)
{
printf("Memory allocation failed!\n");
return;
}
-
+
newConnectivityHandler->type = connType;
newConnectivityHandler->handler = handler;
storeInterfaceCallbacks(newConnectivityHandler);
}
-void requestResponseHandler(CARemoteEndpoint* object, void* data)
+void requestResponseHandler(CARemoteEndpoint *object, void *data)
{
printf("\nrequestResponseHandler Entry in Sample");
- if (object == NULL || data == NULL) {
+ if (object == NULL || data == NULL)
+ {
printf("\nNULL Object");
return;
}
if (object->addressInfo.IP.ipAddress)
printf("\nData Received from %s\n", object->addressInfo.IP.ipAddress);
if (data)
- printf("\nReceived Data : %s \n", (char*)data);
+ printf("\nReceived Data : %s \n", (char *)data);
/*
gMainloopStatus = 1;
if (mainloop)
}
-void networkInterfaceCallback(CALocalConnectivity* localEndPoint, CANetworkStatus networkConnectivityState)
+void networkInterfaceCallback(CALocalConnectivity *localEndPoint,
+ CANetworkStatus networkConnectivityState)
{
printf("\nnetworkInterfaceCallback Entry in Sample");
- if (localEndPoint == NULL) {
+ if (localEndPoint == NULL)
+ {
printf("\nNULL Object");
return;
}
int wifi_tc_001_initializeWifi_p(void)
{
CAResult error = CA_STATUS_FAILED;
- error = CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
+ error = CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler,
+ networkInterfaceCallback);
assert_eq(error, CA_STATUS_OK);
return 0;
}
{
uint32_t dataSize;
CAResult error = CA_STATUS_FAILED;
-
+
//Startup
CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback);
uint32_t size = 0;
error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size);
assert_eq(error, CA_STATUS_OK);
-
- localWifiEndpoint->addressInfo.IP.port = 5283;
+
+ localWifiEndpoint->addressInfo.IP.port = 5683;
//StartWifiAdapter(localWifiEndpoint);
interfaceInitializeEndpoint(0);
uint32_t size = 0;
error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size);
assert_eq(error, CA_STATUS_OK);
-
+
error = CAStartUnicastServer(localWifiEndpoint->addressInfo.IP.ipAddress, NULL);
assert_eq(error, CA_STATUS_INVALID_PARAM);
//Cleanup
uint32_t size = 0;
error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size);
assert_eq(error, CA_STATUS_OK);
-
+
error = CAStartUnicastServer(NULL, NULL);
assert_eq(error, CA_STATUS_INVALID_PARAM);
//Cleanup