From c24a356f0f1cd4fbb8bcf88b458e1799a5685fcf Mon Sep 17 00:00:00 2001 From: "ashok.channa" Date: Fri, 12 Dec 2014 11:25:30 +0900 Subject: [PATCH] Implementation of connectivity abstraction feature Release v0.61 Connectivity Abstraction feature provides unified approach for multiple Transports Supported Features : Ubuntu ( WIFI-DTLS, ETH) - Multi Thread Tizen (WIFI, BT, BLE) - Multi Thread Arduino( WIFI, ETH) -Single Thread Android( WIFI, BLE) - Multi Thread Please read the RELEASE v0.6 @csdk\connectivity for more information. Signed-off-by: ashok.channa Change-Id: I57c81845725f255b43829b9f9e8fe62e8d7b8517 --- resource/csdk/connectivity/RELEASE v0.61 | 96 ++ resource/csdk/connectivity/api/cacommon.h | 64 +- resource/csdk/connectivity/api/cainterface.h | 11 +- resource/csdk/connectivity/build/Makefile | 9 +- .../csdk/connectivity/build/android/jni/Android.mk | 2 +- .../csdk/connectivity/build/arduino/README.txt | 23 +- .../build/arduino/arduinomega.properties | 15 +- resource/csdk/connectivity/build/arduino/build.sh | 8 +- resource/csdk/connectivity/build/linux/Makefile | 28 +- resource/csdk/connectivity/build/tizen/Makefile | 12 +- resource/csdk/connectivity/build/tizen/gbsbuild.sh | 5 + resource/csdk/connectivity/common/inc/oic_logger.h | 6 +- .../connectivity/common/inc/oic_logger_types.h | 4 +- resource/csdk/connectivity/common/inc/uarraylist.h | 6 +- resource/csdk/connectivity/common/inc/umutex.h | 3 + resource/csdk/connectivity/common/inc/uqueue.h | 22 +- resource/csdk/connectivity/common/src/logger.c | 2 +- resource/csdk/connectivity/common/src/logger.cpp | 6 +- .../connectivity/common/src/oic_console_logger.c | 4 +- resource/csdk/connectivity/common/src/oic_logger.c | 8 +- resource/csdk/connectivity/common/src/uarraylist.c | 5 +- resource/csdk/connectivity/common/src/umutex.c | 22 +- .../csdk/connectivity/common/src/uthreadpool.c | 25 +- .../connectivity/{ => doc/release}/RELEASE v0.5 | 0 .../csdk/connectivity/doc/release/RELEASE v0.6 | 96 ++ .../csdk/connectivity/inc/caadapterinterface.h | 13 + resource/csdk/connectivity/inc/caadapternetdtls.h | 176 +++ resource/csdk/connectivity/inc/caadapterutils.h | 11 +- resource/csdk/connectivity/inc/caedradapter.h | 13 +- .../connectivity/inc/caedradapter_singlethread.h | 146 --- resource/csdk/connectivity/inc/caethernetadapter.h | 13 +- .../inc/caethernetadapter_singlethread.h | 137 --- .../csdk/connectivity/inc/caethernetinterface.h | 125 ++- .../csdk/connectivity/inc/cainterfacecontroller.h | 2 +- .../inc/cainterfacecontroller_singlethread.h | 61 + resource/csdk/connectivity/inc/caleadapter.h | 115 +- .../connectivity/inc/caleadapter_singlethread.h | 139 --- resource/csdk/connectivity/inc/calecore.h | 24 +- resource/csdk/connectivity/inc/caleinterface.h | 174 +++ resource/csdk/connectivity/inc/camessagehandler.h | 14 +- .../inc/camessagehandler_singlethread.h | 61 +- resource/csdk/connectivity/inc/camessagequeue.h | 94 -- resource/csdk/connectivity/inc/camsgparser.h | 123 ++- resource/csdk/connectivity/inc/caprotocolmessage.h | 102 +- resource/csdk/connectivity/inc/caqueueingthread.h | 16 +- resource/csdk/connectivity/inc/caremotehandler.h | 16 +- resource/csdk/connectivity/inc/caretransmission.h | 98 ++ .../inc/caretransmission_singlethread.h | 94 ++ resource/csdk/connectivity/inc/cawifiadapter.h | 12 +- .../connectivity/inc/cawifiadapter_singlethread.h | 135 --- resource/csdk/connectivity/inc/cawifiinterface.h | 92 +- .../inc/com_iotivity_jar_CALeInterface.h | 24 +- .../inc/com_iotivity_jar_CAWiFiInterface.h | 4 +- .../lib/extlibs/arduino_linux_ethernet_cpp.patch | 17 + .../arduino_linux_ethernet_socket_cpp.patch | 59 + .../csdk/connectivity/samples/arduino/casample.cpp | 34 +- .../connectivity/samples/arduino/sample_main.cpp | 34 +- resource/csdk/connectivity/samples/linux/README | 4 + resource/csdk/connectivity/samples/linux/sample.sh | 5 + .../csdk/connectivity/samples/linux/sample_main.c | 466 ++++++-- .../csdk/connectivity/samples/tizen/casample.c | 39 +- .../connectivity/samples/tizen/interfacesample.c | 25 +- .../connectivity/src/adapter_util/caadapterutils.c | 12 +- .../connectivity/src/adapter_util/camessagequeue.c | 200 ---- .../connectivity/src/adapter_util/camsgparser.c | 26 +- .../src/bt_edr_adapter/linux/caedradapter.c | 10 +- .../src/bt_edr_adapter/tizen/cabtclient.c | 7 +- .../src/bt_edr_adapter/tizen/cabtdevicelist.c | 6 +- .../src/bt_edr_adapter/tizen/cabtdevicelist.h | 2 +- .../src/bt_edr_adapter/tizen/cabtendpoint.c | 2 +- .../src/bt_edr_adapter/tizen/cabtmanager.c | 750 +++++++------ .../src/bt_edr_adapter/tizen/cabtmanager.h | 7 +- .../src/bt_edr_adapter/tizen/cabtserver.c | 6 +- .../src/bt_edr_adapter/tizen/cabtutils.c | 2 +- .../src/bt_edr_adapter/tizen/cabtutils.h | 2 +- .../src/bt_edr_adapter/tizen/caedradapter.c | 51 +- .../src/bt_le_adapter/arduino/caleadapter.cpp | 208 +++- .../src/bt_le_adapter/arduino/caleserver.cpp | 168 +-- .../src/bt_le_adapter/arduino/caleserver.h | 75 +- .../connectivity/src/bt_le_adapter/caleadapter.c | 1162 +++++++++++++++++++- .../src/bt_le_adapter/linux/caleadapter.c | 10 +- .../src/bt_le_adapter/tizen/cableclient.c | 525 +-------- .../src/bt_le_adapter/tizen/cableclient.h | 123 +-- .../src/bt_le_adapter/tizen/cableclientutil.h | 15 +- .../src/bt_le_adapter/tizen/cableserver.c | 462 +------- .../src/bt_le_adapter/tizen/cableserver.h | 64 +- resource/csdk/connectivity/src/caadapternetdtls.c | 600 ++++++++++ .../csdk/connectivity/src/caconnectivitymanager.c | 24 +- .../src/caconnectivitymanager_singlethread.c | 5 +- .../csdk/connectivity/src/cainterfacecontroller.c | 36 +- .../src/cainterfacecontroller_singlethread.c | 49 +- resource/csdk/connectivity/src/camessagehandler.c | 90 +- .../src/camessagehandler_singlethread.c | 73 +- .../csdk/connectivity/src/canetworkconfigurator.c | 4 +- .../src/canetworkconfigurator_singlethread.c | 11 +- resource/csdk/connectivity/src/caprotocolmessage.c | 123 ++- resource/csdk/connectivity/src/caqueueingthread.c | 8 +- resource/csdk/connectivity/src/caremotehandler.c | 14 +- resource/csdk/connectivity/src/caretransmission.c | 480 ++++++++ .../src/caretransmission_singlethread.cpp | 404 +++++++ .../ethernet_adapter/arduino/caethernetadapter.c | 276 ----- .../arduino/caethernetadapterutils.cpp | 327 +----- .../arduino/caethernetadapterutils.h | 66 +- .../ethernet_adapter/arduino/caethernetclient.cpp | 135 +++ .../arduino/caethernetnwmonitor.cpp | 68 ++ .../ethernet_adapter/arduino/caethernetserver.cpp | 309 ++++++ .../src/ethernet_adapter/caethernetadapter.c | 43 +- .../caethernetadapter_singlethread.c | 476 ++++++++ .../src/ethernet_adapter/linux/caethernetclient.c | 3 +- .../ethernet_adapter/linux/caethernetnwmonitor.c | 11 +- .../src/ethernet_adapter/linux/caethernetserver.c | 7 +- .../src/wifi_adapter/arduino/cawifiadapter.c | 294 ----- .../src/wifi_adapter/arduino/cawifiadapterutils.h | 109 -- .../src/wifi_adapter/arduino/cawificlient.cpp | 140 +++ .../src/wifi_adapter/arduino/cawifinwmonitor.cpp | 69 ++ .../{cawifiadapterutils.cpp => cawifiserver.cpp} | 255 ++--- .../connectivity/src/wifi_adapter/cawifiadapter.c | 245 +++-- .../src/wifi_adapter/cawifiadapter_singlethread.c | 480 ++++++++ .../src/wifi_adapter/linux/cawificlient.c | 64 +- .../src/wifi_adapter/linux/cawifinwmonitor.c | 92 +- .../src/wifi_adapter/linux/cawifiserver.c | 965 ++++++++-------- .../src/wifi_adapter/tizen/cawificlient.c | 66 +- .../src/wifi_adapter/tizen/cawifinwmonitor.c | 11 +- .../src/wifi_adapter/tizen/cawifiserver.c | 1123 ++++++++++--------- .../unittests/tizen/tct/liboic/bt/utc-bt-liboic.c | 90 +- .../unittests/tizen/tct/liboic/tct-liboic-core.c | 11 +- .../unittests/tizen/tct/liboic/tct-liboic-core.h | 3 +- .../tizen/tct/liboic/wifi/utc-wifi-liboic.c | 86 +- 128 files changed, 9218 insertions(+), 5621 deletions(-) create mode 100644 resource/csdk/connectivity/RELEASE v0.61 rename resource/csdk/connectivity/{ => doc/release}/RELEASE v0.5 (100%) create mode 100644 resource/csdk/connectivity/doc/release/RELEASE v0.6 create mode 100644 resource/csdk/connectivity/inc/caadapternetdtls.h delete mode 100644 resource/csdk/connectivity/inc/caedradapter_singlethread.h delete mode 100644 resource/csdk/connectivity/inc/caethernetadapter_singlethread.h delete mode 100644 resource/csdk/connectivity/inc/caleadapter_singlethread.h create mode 100644 resource/csdk/connectivity/inc/caleinterface.h delete mode 100644 resource/csdk/connectivity/inc/camessagequeue.h create mode 100644 resource/csdk/connectivity/inc/caretransmission.h create mode 100644 resource/csdk/connectivity/inc/caretransmission_singlethread.h delete mode 100644 resource/csdk/connectivity/inc/cawifiadapter_singlethread.h create mode 100644 resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_cpp.patch create mode 100644 resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_socket_cpp.patch delete mode 100644 resource/csdk/connectivity/src/adapter_util/camessagequeue.c create mode 100644 resource/csdk/connectivity/src/caadapternetdtls.c create mode 100644 resource/csdk/connectivity/src/caretransmission.c create mode 100644 resource/csdk/connectivity/src/caretransmission_singlethread.cpp delete mode 100644 resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapter.c create mode 100644 resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp create mode 100644 resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp create mode 100644 resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp create mode 100644 resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c delete mode 100644 resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapter.c delete mode 100644 resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapterutils.h create mode 100644 resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp create mode 100644 resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp rename resource/csdk/connectivity/src/wifi_adapter/arduino/{cawifiadapterutils.cpp => cawifiserver.cpp} (58%) create mode 100644 resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c diff --git a/resource/csdk/connectivity/RELEASE v0.61 b/resource/csdk/connectivity/RELEASE v0.61 new file mode 100644 index 0000000..df2d75d --- /dev/null +++ b/resource/csdk/connectivity/RELEASE v0.61 @@ -0,0 +1,96 @@ +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 diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index a1dd635..4414129 100644 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -71,19 +71,40 @@ extern "C" #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 @@ -183,6 +204,8 @@ typedef struct CAAddress_t addressInfo; /** Connectivity of the endpoint**/ CAConnectivityType_t connectivityType; + /** Secure connection**/ + CABool_t isSecured; } CARemoteEndpoint_t; @@ -206,6 +229,8 @@ typedef struct CAAddress_t addressInfo; /** Connectivity type that localconnectivity avaialble **/ CAConnectivityType_t type; + /** Secure connection**/ + CABool_t isSecured; } CALocalConnectivity_t; /** @@ -228,7 +253,7 @@ typedef enum CA_DESTINATION_DISCONNECTED, CA_STATUS_FAILED, CA_NOT_SUPPORTED -/* Result code - END HERE */ + /* Result code - END HERE */ } CAResult_t; /** @@ -243,7 +268,7 @@ typedef enum CA_BAD_REQ = 400, CA_BAD_OPT = 402, CA_NOT_FOUND = 404 -/* Response status code - END HERE */ + /* Response status code - END HERE */ } CAResponseResult_t; /** @@ -281,10 +306,14 @@ typedef struct { /**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 **/ @@ -317,6 +346,29 @@ typedef struct 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 diff --git a/resource/csdk/connectivity/api/cainterface.h b/resource/csdk/connectivity/api/cainterface.h index e86a76c..d4d8c00 100644 --- a/resource/csdk/connectivity/api/cainterface.h +++ b/resource/csdk/connectivity/api/cainterface.h @@ -152,8 +152,8 @@ CAResult_t CASendRequest(const CARemoteEndpoint_t *object, CARequestInfo_t *requ * @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 @@ -171,7 +171,8 @@ CAResult_t CASendResponse(const CARemoteEndpoint_t *object, CAResponseInfo_t *re * @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 @@ -180,8 +181,8 @@ CAResult_t CASendNotification(const CARemoteEndpoint_t *object, CAResponseInfo_t * @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 diff --git a/resource/csdk/connectivity/build/Makefile b/resource/csdk/connectivity/build/Makefile index f732213..b57c9f6 100644 --- a/resource/csdk/connectivity/build/Makefile +++ b/resource/csdk/connectivity/build/Makefile @@ -26,6 +26,7 @@ BUILD := debug PLATFORM := linux TRANSPORT := ALL +ARDUINO_DIR := /usr/share/arduino APPNAME := casample OBJ_DIR := ./bin VERSION_MAJOR := 0 @@ -40,14 +41,14 @@ all: 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**********) diff --git a/resource/csdk/connectivity/build/android/jni/Android.mk b/resource/csdk/connectivity/build/android/jni/Android.mk index 432bee8..24275b8 100644 --- a/resource/csdk/connectivity/build/android/jni/Android.mk +++ b/resource/csdk/connectivity/build/android/jni/Android.mk @@ -107,7 +107,7 @@ LOCAL_CFLAGS += $(BUILD_FLAG) 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 \ diff --git a/resource/csdk/connectivity/build/arduino/README.txt b/resource/csdk/connectivity/build/arduino/README.txt index 572df31..23ec126 100644 --- a/resource/csdk/connectivity/build/arduino/README.txt +++ b/resource/csdk/connectivity/build/arduino/README.txt @@ -1,27 +1,28 @@ 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 = /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= +4) BUILD : Go to "connectivity\build" directory. To build a specific TRANSPORT [ETHERNET,BLE,WIFI], use the following command : + sudo make PLATFORM=arduinomega TRANSPORT= ARDUINO_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-/library" folder - Download BLE library from internet and place it in "arduino-/library" folder - - + Flashing Interface APIs for ARDUINOMEGA: ======================================== Precondition: Connect Arduino Mega Board to Linux PC. Open Arduino IDE and select corresponding connected PORT diff --git a/resource/csdk/connectivity/build/arduino/arduinomega.properties b/resource/csdk/connectivity/build/arduino/arduinomega.properties index 03934f4..329914a 100644 --- a/resource/csdk/connectivity/build/arduino/arduinomega.properties +++ b/resource/csdk/connectivity/build/arduino/arduinomega.properties @@ -12,13 +12,13 @@ SDIR_ARD_UTIL = $(BASE_DIR)/src/adapter_util/ 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) @@ -58,13 +58,12 @@ ifeq ($(TRANSPORT),ETHERNET) 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 @@ -100,20 +99,20 @@ CORE_CPPOBJ = CDC.cpp.o HardwareSerial.cpp.o HardwareSerial0.cpp.o HardwareSeria 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 diff --git a/resource/csdk/connectivity/build/arduino/build.sh b/resource/csdk/connectivity/build/arduino/build.sh index 2c23bfe..04abff2 100644 --- a/resource/csdk/connectivity/build/arduino/build.sh +++ b/resource/csdk/connectivity/build/arduino/build.sh @@ -2,12 +2,12 @@ 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 diff --git a/resource/csdk/connectivity/build/linux/Makefile b/resource/csdk/connectivity/build/linux/Makefile index c23f62c..edf85e2 100644 --- a/resource/csdk/connectivity/build/linux/Makefile +++ b/resource/csdk/connectivity/build/linux/Makefile @@ -24,6 +24,7 @@ BUILD = debug PLATFORM = linux TRANSPORT = ALL +DTLS = 0 OBJ_DIR = ./$(BUILD) VERSION_MAJOR = 0 VERSION_MINOR = 1 @@ -41,7 +42,11 @@ LE = NO_LE_ADAPTER 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 @@ -70,9 +75,16 @@ TARGET_ALIAS = lib$(PROJECT_NAME).so ## 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)) @@ -84,11 +96,15 @@ RELEASE_DIR = ./release ## 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) ## @@ -103,7 +119,11 @@ IFLAGS = -I$(PROJECT_COMMON_INC_PATH) \ -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) diff --git a/resource/csdk/connectivity/build/tizen/Makefile b/resource/csdk/connectivity/build/tizen/Makefile index 59fffd1..ceda5c8 100644 --- a/resource/csdk/connectivity/build/tizen/Makefile +++ b/resource/csdk/connectivity/build/tizen/Makefile @@ -6,6 +6,7 @@ BUILD := debug PLATFORM := tizen OBJ_DIR := ./bin +ROOT_DIR := . VERSION_MAJOR := 0 VERSION_MINOR := 1 VERSION_PATCH := 0 @@ -17,6 +18,9 @@ CC=gcc 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) @@ -25,6 +29,12 @@ COMPILEFLAG = `pkg-config --cflags --libs capi-network-wifi dlog capi-network-bl # 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)) @@ -38,7 +48,7 @@ all: $(OBJECTS) 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: diff --git a/resource/csdk/connectivity/build/tizen/gbsbuild.sh b/resource/csdk/connectivity/build/tizen/gbsbuild.sh index 1705555..718a9e3 100644 --- a/resource/csdk/connectivity/build/tizen/gbsbuild.sh +++ b/resource/csdk/connectivity/build/tizen/gbsbuild.sh @@ -16,10 +16,12 @@ sourcedir=`pwd` 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 @@ -27,6 +29,7 @@ cp -R ../../common/src/* $sourcedir/tizen/tmp/ 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="" @@ -75,6 +78,8 @@ cd $sourcedir/tizen/tmp/ #multiple definition error. rm -rf *_singlethread.* +rm -rf *dtls.* + #cd $builddir #cp -R ./* $sourcedir/tmp/ diff --git a/resource/csdk/connectivity/common/inc/oic_logger.h b/resource/csdk/connectivity/common/inc/oic_logger.h index df738c2..2488b9d 100644 --- a/resource/csdk/connectivity/common/inc/oic_logger.h +++ b/resource/csdk/connectivity/common/inc/oic_logger.h @@ -29,9 +29,9 @@ extern "C" #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); diff --git a/resource/csdk/connectivity/common/inc/oic_logger_types.h b/resource/csdk/connectivity/common/inc/oic_logger_types.h index f372a4c..f02dc11 100644 --- a/resource/csdk/connectivity/common/inc/oic_logger_types.h +++ b/resource/csdk/connectivity/common/inc/oic_logger_types.h @@ -43,11 +43,11 @@ typedef enum 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 *); diff --git a/resource/csdk/connectivity/common/inc/uarraylist.h b/resource/csdk/connectivity/common/inc/uarraylist.h index 386ea09..77e62bb 100644 --- a/resource/csdk/connectivity/common/inc/uarraylist.h +++ b/resource/csdk/connectivity/common/inc/uarraylist.h @@ -49,7 +49,7 @@ typedef struct u_arraylist_t * @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 @@ -68,7 +68,7 @@ CAResult_t u_arraylist_free(u_arraylist_t *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 @@ -89,7 +89,7 @@ CAResult_t u_arraylist_add(u_arraylist_t *list, void *data); * [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 diff --git a/resource/csdk/connectivity/common/inc/umutex.h b/resource/csdk/connectivity/common/inc/umutex.h index 6566404..93459f0 100644 --- a/resource/csdk/connectivity/common/inc/umutex.h +++ b/resource/csdk/connectivity/common/inc/umutex.h @@ -24,6 +24,9 @@ #ifndef __UMUTEX_H_ #define __UMUTEX_H_ +#include +#include +#include #include #include "cacommon.h" diff --git a/resource/csdk/connectivity/common/inc/uqueue.h b/resource/csdk/connectivity/common/inc/uqueue.h index b40be81..7832214 100644 --- a/resource/csdk/connectivity/common/inc/uqueue.h +++ b/resource/csdk/connectivity/common/inc/uqueue.h @@ -53,9 +53,9 @@ typedef struct u_queue_element_t u_queue_element; 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; }; /** @@ -65,7 +65,7 @@ struct u_queue_element_t 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; @@ -74,7 +74,7 @@ typedef struct 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 @@ -83,7 +83,7 @@ u_queue_t* u_queue_create(); * @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 @@ -93,7 +93,7 @@ CAResult_t u_queue_delete(u_queue_t* queue); * @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 @@ -103,7 +103,7 @@ CAResult_t u_queue_add_element(u_queue_t* queue, u_queue_message_t *message); * @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 @@ -112,7 +112,7 @@ u_queue_message_t* u_queue_get_element(u_queue_t* queue); * @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 @@ -120,7 +120,7 @@ CAResult_t u_queue_remove_element(u_queue_t* queue); * 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 @@ -129,7 +129,7 @@ uint32_t u_queue_get_size(u_queue_t* queue); * @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 @@ -138,7 +138,7 @@ CAResult_t u_queue_reset(u_queue_t* queue); * @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" */ diff --git a/resource/csdk/connectivity/common/src/logger.c b/resource/csdk/connectivity/common/src/logger.c index be92eea..c281714 100644 --- a/resource/csdk/connectivity/common/src/logger.c +++ b/resource/csdk/connectivity/common/src/logger.c @@ -38,7 +38,7 @@ static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + // 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 diff --git a/resource/csdk/connectivity/common/src/logger.cpp b/resource/csdk/connectivity/common/src/logger.cpp index 9af46e2..5fbb71c 100644 --- a/resource/csdk/connectivity/common/src/logger.cpp +++ b/resource/csdk/connectivity/common/src/logger.cpp @@ -101,9 +101,9 @@ void OICLog(LogLevel level, const char *tag, const char *logStr) #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){ diff --git a/resource/csdk/connectivity/common/src/oic_console_logger.c b/resource/csdk/connectivity/common/src/oic_console_logger.c index 500f5a6..40a24d5 100644 --- a/resource/csdk/connectivity/common/src/oic_console_logger.c +++ b/resource/csdk/connectivity/common/src/oic_console_logger.c @@ -32,8 +32,8 @@ typedef struct 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) diff --git a/resource/csdk/connectivity/common/src/oic_logger.c b/resource/csdk/connectivity/common/src/oic_logger.c index 7c1d7e9..032c201 100644 --- a/resource/csdk/connectivity/common/src/oic_logger.c +++ b/resource/csdk/connectivity/common/src/oic_logger.c @@ -23,14 +23,14 @@ #include #include -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) diff --git a/resource/csdk/connectivity/common/src/uarraylist.c b/resource/csdk/connectivity/common/src/uarraylist.c index ae6fbc3..1d90acc 100644 --- a/resource/csdk/connectivity/common/src/uarraylist.c +++ b/resource/csdk/connectivity/common/src/uarraylist.c @@ -38,7 +38,7 @@ u_arraylist_t *u_arraylist_create() 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); @@ -115,6 +115,9 @@ void *u_arraylist_remove(u_arraylist_t *list, uint32_t index) 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; diff --git a/resource/csdk/connectivity/common/src/umutex.c b/resource/csdk/connectivity/common/src/umutex.c index 1640d3f..e4ddf98 100644 --- a/resource/csdk/connectivity/common/src/umutex.c +++ b/resource/csdk/connectivity/common/src/umutex.c @@ -56,7 +56,7 @@ void u_mutex_lock(u_mutex mutex) { if (NULL == mutex) { - OIC_LOG_V(ERROR, TAG ,"u_mutex_lock, Invalid mutex !"); + OIC_LOG_V(ERROR, TAG , "u_mutex_lock, Invalid mutex !"); return; } @@ -68,7 +68,7 @@ CABool_t u_mutex_trylock(u_mutex mutex) { 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; } @@ -86,7 +86,7 @@ void u_mutex_unlock(u_mutex mutex) { if (NULL == mutex) { - OIC_LOG_V(ERROR, TAG,"u_mutex_unlock, Invalid mutex !"); + OIC_LOG_V(ERROR, TAG, "u_mutex_unlock, Invalid mutex !"); return; } @@ -98,7 +98,7 @@ void u_mutex_free(u_mutex mutex) { if (NULL == mutex) { - OIC_LOG_V(ERROR, TAG,"u_mutex_free, Invalid mutex !"); + OIC_LOG_V(ERROR, TAG, "u_mutex_free, Invalid mutex !"); return; } @@ -121,7 +121,7 @@ void u_cond_signal(u_cond cond) { if (NULL == cond) { - OIC_LOG_V(ERROR, TAG,"u_cond_signal, Invalid condition !"); + OIC_LOG_V(ERROR, TAG, "u_cond_signal, Invalid condition !"); return; } @@ -133,7 +133,7 @@ void u_cond_broadcast(u_cond cond) { if (NULL == cond) { - OIC_LOG_V(ERROR, TAG,"u_cond_broadcast, Invalid condition !"); + OIC_LOG_V(ERROR, TAG, "u_cond_broadcast, Invalid condition !"); return; } @@ -145,13 +145,13 @@ void u_cond_wait(u_cond cond, u_mutex mutex) { 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; } @@ -164,13 +164,13 @@ void u_cond_timed_wait(u_cond cond, u_mutex mutex, int32_t microseconds) { 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; } @@ -196,7 +196,7 @@ void u_cond_free(u_cond cond) { if (NULL == cond) { - OIC_LOG_V(ERROR, TAG,"u_cond_free, Invalid condition !"); + OIC_LOG_V(ERROR, TAG, "u_cond_free, Invalid condition !"); return; } diff --git a/resource/csdk/connectivity/common/src/uthreadpool.c b/resource/csdk/connectivity/common/src/uthreadpool.c index 4331fe8..d393d7b 100644 --- a/resource/csdk/connectivity/common/src/uthreadpool.c +++ b/resource/csdk/connectivity/common/src/uthreadpool.c @@ -16,6 +16,7 @@ * limitations under the License. * ******************************************************************/ + /** * @file uthreadpool.c * @brief This file provides APIs related to thread pool @@ -24,6 +25,7 @@ #include "uthreadpool.h" #include "logger.h" #include "oic_malloc.h" + #define TAG PCF("UTHREADPOOL") /** @@ -60,6 +62,7 @@ CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_p } return CA_STATUS_FAILED; } + *thread_pool = (u_thread_pool_t) gThreadpool; OIC_LOG(DEBUG, TAG, "OUT"); @@ -95,11 +98,12 @@ CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, void (*routine)(v 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); @@ -110,18 +114,19 @@ void run(void *thread_data, void *user_data) { 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; } diff --git a/resource/csdk/connectivity/RELEASE v0.5 b/resource/csdk/connectivity/doc/release/RELEASE v0.5 similarity index 100% rename from resource/csdk/connectivity/RELEASE v0.5 rename to resource/csdk/connectivity/doc/release/RELEASE v0.5 diff --git a/resource/csdk/connectivity/doc/release/RELEASE v0.6 b/resource/csdk/connectivity/doc/release/RELEASE v0.6 new file mode 100644 index 0000000..85906ef --- /dev/null +++ b/resource/csdk/connectivity/doc/release/RELEASE v0.6 @@ -0,0 +1,96 @@ +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 diff --git a/resource/csdk/connectivity/inc/caadapterinterface.h b/resource/csdk/connectivity/inc/caadapterinterface.h index 4a9dbf8..1ca3af7 100644 --- a/resource/csdk/connectivity/inc/caadapterinterface.h +++ b/resource/csdk/connectivity/inc/caadapterinterface.h @@ -162,6 +162,19 @@ typedef void (*CANetworkPacketReceivedCallback)(CARemoteEndpoint_t *endPoint, vo */ 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 diff --git a/resource/csdk/connectivity/inc/caadapternetdtls.h b/resource/csdk/connectivity/inc/caadapternetdtls.h new file mode 100644 index 0000000..e327cda --- /dev/null +++ b/resource/csdk/connectivity/inc/caadapternetdtls.h @@ -0,0 +1,176 @@ +/****************************************************************** +* +* 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 + diff --git a/resource/csdk/connectivity/inc/caadapterutils.h b/resource/csdk/connectivity/inc/caadapterutils.h index a8b25f5..7a1ec28 100644 --- a/resource/csdk/connectivity/inc/caadapterutils.h +++ b/resource/csdk/connectivity/inc/caadapterutils.h @@ -70,8 +70,8 @@ extern "C" * @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 @@ -89,14 +89,15 @@ void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndPoint); * @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 diff --git a/resource/csdk/connectivity/inc/caedradapter.h b/resource/csdk/connectivity/inc/caedradapter.h index 293761b..02328ac 100644 --- a/resource/csdk/connectivity/inc/caedradapter.h +++ b/resource/csdk/connectivity/inc/caedradapter.h @@ -29,7 +29,9 @@ **/ #include "cacommon.h" #include "caadapterinterface.h" +#ifndef ARDUINO #include "uthreadpool.h" /* for thread pool */ +#endif //ARDUINO #ifdef __cplusplus extern "C" @@ -53,10 +55,17 @@ 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 @@ -110,8 +119,8 @@ CAResult_t CAStartEDRDiscoveryServer(); * @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 diff --git a/resource/csdk/connectivity/inc/caedradapter_singlethread.h b/resource/csdk/connectivity/inc/caedradapter_singlethread.h deleted file mode 100644 index 2bb9a9a..0000000 --- a/resource/csdk/connectivity/inc/caedradapter_singlethread.h +++ /dev/null @@ -1,146 +0,0 @@ -/****************************************************************** - * - * 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_ diff --git a/resource/csdk/connectivity/inc/caethernetadapter.h b/resource/csdk/connectivity/inc/caethernetadapter.h index 650d012..d4240fb 100644 --- a/resource/csdk/connectivity/inc/caethernetadapter.h +++ b/resource/csdk/connectivity/inc/caethernetadapter.h @@ -27,7 +27,9 @@ #include "cacommon.h" #include "caadapterinterface.h" +#ifndef ARDUINO #include "uthreadpool.h" /* for thread pool */ +#endif //ARDUINO #ifdef __cplusplus extern "C" @@ -42,9 +44,14 @@ 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. @@ -80,7 +87,7 @@ CAResult_t CAStartEthernetDiscoveryServer(); * @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. diff --git a/resource/csdk/connectivity/inc/caethernetadapter_singlethread.h b/resource/csdk/connectivity/inc/caethernetadapter_singlethread.h deleted file mode 100644 index 7aefe0d..0000000 --- a/resource/csdk/connectivity/inc/caethernetadapter_singlethread.h +++ /dev/null @@ -1,137 +0,0 @@ -/****************************************************************** - * - * 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__ diff --git a/resource/csdk/connectivity/inc/caethernetinterface.h b/resource/csdk/connectivity/inc/caethernetinterface.h index 2ff7044..7aa8c2c 100644 --- a/resource/csdk/connectivity/inc/caethernetinterface.h +++ b/resource/csdk/connectivity/inc/caethernetinterface.h @@ -29,7 +29,9 @@ #include #include "cacommon.h" -#include "uthreadpool.h" +#ifndef ARDUINO +#include "uthreadpool.h" /* for thread pool */ +#endif //ARDUINO #ifdef __cplusplus extern "C" @@ -55,11 +57,12 @@ typedef enum * @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 @@ -73,6 +76,7 @@ typedef void (*CAEthernetExceptionCallback)(CAAdapterServerType_t type); /** * @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. @@ -82,9 +86,10 @@ typedef void (*CAEthernetExceptionCallback)(CAAdapterServerType_t type); * @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 @@ -118,8 +123,29 @@ void CAEthernetTerminateServer(void); * @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 @@ -128,6 +154,7 @@ CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char * * @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. @@ -137,7 +164,8 @@ CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char * * @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 @@ -160,10 +188,22 @@ CAResult_t CAEthernetStopMulticastServer(void); 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. @@ -173,8 +213,31 @@ CAResult_t CAEthernetStopUnicastServer(); * @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. @@ -217,6 +280,25 @@ void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback); 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 * @@ -225,7 +307,30 @@ void CAEthernetSetUnicastSocket(const int32_t socketFD); * @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 @@ -233,7 +338,10 @@ void CAEthernetSetUnicastSocket(const int32_t socketFD); * @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 @@ -258,9 +366,10 @@ typedef void (*CAEthernetConnectionStateChangeCallback)(const char *ipAddress, * @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 diff --git a/resource/csdk/connectivity/inc/cainterfacecontroller.h b/resource/csdk/connectivity/inc/cainterfacecontroller.h index bca90c0..52e8c4c 100644 --- a/resource/csdk/connectivity/inc/cainterfacecontroller.h +++ b/resource/csdk/connectivity/inc/cainterfacecontroller.h @@ -84,7 +84,7 @@ CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size); * @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. diff --git a/resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h b/resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h index 0b0d859..dcde405 100644 --- a/resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h +++ b/resource/csdk/connectivity/inc/cainterfacecontroller_singlethread.h @@ -21,6 +21,7 @@ * @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_ @@ -32,28 +33,88 @@ extern "C" { #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 diff --git a/resource/csdk/connectivity/inc/caleadapter.h b/resource/csdk/connectivity/inc/caleadapter.h index 7773fad..cec404b 100644 --- a/resource/csdk/connectivity/inc/caleadapter.h +++ b/resource/csdk/connectivity/inc/caleadapter.h @@ -27,7 +27,9 @@ #include "cacommon.h" #include "caadapterinterface.h" -#include "uthreadpool.h" +#ifndef ARDUINO +#include "uthreadpool.h" /* for thread pool */ +#endif //ARDUINO /** * BLE Interface APIs. @@ -38,18 +40,36 @@ extern "C" #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 @@ -77,13 +97,13 @@ 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. + * 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. @@ -104,13 +124,13 @@ 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. + * 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 @@ -139,6 +159,83 @@ CAResult_t CAStopLE(); */ 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 diff --git a/resource/csdk/connectivity/inc/caleadapter_singlethread.h b/resource/csdk/connectivity/inc/caleadapter_singlethread.h deleted file mode 100644 index 90247e6..0000000 --- a/resource/csdk/connectivity/inc/caleadapter_singlethread.h +++ /dev/null @@ -1,139 +0,0 @@ -/****************************************************************** - * - * 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_ diff --git a/resource/csdk/connectivity/inc/calecore.h b/resource/csdk/connectivity/inc/calecore.h index f720c33..fab83cb 100644 --- a/resource/csdk/connectivity/inc/calecore.h +++ b/resource/csdk/connectivity/inc/calecore.h @@ -34,17 +34,17 @@ extern "C" { #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(); @@ -54,13 +54,13 @@ int32_t CALEStopMulticastServer(int32_t serverID); 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 @@ -90,14 +90,14 @@ void CANativeLEStartScanImpl(JNIEnv *env, jobject callback); 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); @@ -120,7 +120,7 @@ void CANativeCreateScanDeviceList(JNIEnv *env); void CANativeAddScanDeviceToList(JNIEnv *env, jobject device); -jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress); +jboolean CANativeIsDeviceInList(JNIEnv *env, const char *remoteAddress); void CANativeRemoveAllDevices(JNIEnv *env); @@ -135,7 +135,7 @@ void CANativeCreateGattObjList(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); diff --git a/resource/csdk/connectivity/inc/caleinterface.h b/resource/csdk/connectivity/inc/caleinterface.h new file mode 100644 index 0000000..a6d0921 --- /dev/null +++ b/resource/csdk/connectivity/inc/caleinterface.h @@ -0,0 +1,174 @@ +/****************************************************************** +* +* 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 + +#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_ diff --git a/resource/csdk/connectivity/inc/camessagehandler.h b/resource/csdk/connectivity/inc/camessagehandler.h index 44c6e4b..a914d3c 100644 --- a/resource/csdk/connectivity/inc/camessagehandler.h +++ b/resource/csdk/connectivity/inc/camessagehandler.h @@ -40,7 +40,7 @@ extern "C" * @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 @@ -48,8 +48,8 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint, * @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 @@ -58,7 +58,7 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t* object, * @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 @@ -69,7 +69,7 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint, * @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 @@ -77,8 +77,8 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t * @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 diff --git a/resource/csdk/connectivity/inc/camessagehandler_singlethread.h b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h index 02e7a07..c3840be 100644 --- a/resource/csdk/connectivity/inc/camessagehandler_singlethread.h +++ b/resource/csdk/connectivity/inc/camessagehandler_singlethread.h @@ -17,36 +17,91 @@ * 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 #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 diff --git a/resource/csdk/connectivity/inc/camessagequeue.h b/resource/csdk/connectivity/inc/camessagequeue.h deleted file mode 100644 index 56fce4f..0000000 --- a/resource/csdk/connectivity/inc/camessagequeue.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************** - * - * 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_ - - diff --git a/resource/csdk/connectivity/inc/camsgparser.h b/resource/csdk/connectivity/inc/camsgparser.h index 77acfcd..7189d1f 100644 --- a/resource/csdk/connectivity/inc/camsgparser.h +++ b/resource/csdk/connectivity/inc/camsgparser.h @@ -30,19 +30,62 @@ #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 @@ -50,57 +93,75 @@ extern "C" { #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" */ diff --git a/resource/csdk/connectivity/inc/caprotocolmessage.h b/resource/csdk/connectivity/inc/caprotocolmessage.h index 59f5ec6..fde94e0 100644 --- a/resource/csdk/connectivity/inc/caprotocolmessage.h +++ b/resource/csdk/connectivity/inc/caprotocolmessage.h @@ -57,8 +57,8 @@ coap_pdu_t *CAGeneratePdu(const char *uri, const uint32_t code, const CAInfo_t i * @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. @@ -68,107 +68,107 @@ uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqI * @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) */ @@ -176,18 +176,34 @@ CAResult_t CAGenerateTokenInternal(CAToken_t *token); /** * @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 diff --git a/resource/csdk/connectivity/inc/caqueueingthread.h b/resource/csdk/connectivity/inc/caqueueingthread.h index f88746d..d933204 100644 --- a/resource/csdk/connectivity/inc/caqueueingthread.h +++ b/resource/csdk/connectivity/inc/caqueueingthread.h @@ -36,7 +36,7 @@ extern "C" #endif /**Thread function to be invoked**/ -typedef void (*CAThreadTask)(void* threadData); +typedef void (*CAThreadTask)(void *threadData); typedef struct { @@ -51,7 +51,7 @@ 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; /** @@ -61,15 +61,15 @@ typedef struct * @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 @@ -78,7 +78,7 @@ CAResult_t CAQueueingThreadStart(CAQueueingThread_t* 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 @@ -86,7 +86,7 @@ CAResult_t CAQueueingThreadAddData(CAQueueingThread_t* thread, void* data, uint3 * @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 @@ -94,7 +94,7 @@ CAResult_t CAQueueingThreadStop(CAQueueingThread_t* 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" */ diff --git a/resource/csdk/connectivity/inc/caremotehandler.h b/resource/csdk/connectivity/inc/caremotehandler.h index 1fe2873..3dc9dbc 100644 --- a/resource/csdk/connectivity/inc/caremotehandler.h +++ b/resource/csdk/connectivity/inc/caremotehandler.h @@ -42,14 +42,14 @@ 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 @@ -58,7 +58,7 @@ CARemoteEndpoint_t* CACreateRemoteEndpointUriInternal(const CAURI_t uri); * @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); /** @@ -66,35 +66,35 @@ CARemoteEndpoint_t* CACreateRemoteEndpointInternal(const CAURI_t resourceUri, * @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" */ diff --git a/resource/csdk/connectivity/inc/caretransmission.h b/resource/csdk/connectivity/inc/caretransmission.h new file mode 100644 index 0000000..0b9fee8 --- /dev/null +++ b/resource/csdk/connectivity/inc/caretransmission.h @@ -0,0 +1,98 @@ +/****************************************************************** + * + * 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 + +#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_ diff --git a/resource/csdk/connectivity/inc/caretransmission_singlethread.h b/resource/csdk/connectivity/inc/caretransmission_singlethread.h new file mode 100644 index 0000000..2262a0b --- /dev/null +++ b/resource/csdk/connectivity/inc/caretransmission_singlethread.h @@ -0,0 +1,94 @@ +/****************************************************************** + * + * 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 + +#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_ diff --git a/resource/csdk/connectivity/inc/cawifiadapter.h b/resource/csdk/connectivity/inc/cawifiadapter.h index 929dafb..66f8766 100644 --- a/resource/csdk/connectivity/inc/cawifiadapter.h +++ b/resource/csdk/connectivity/inc/cawifiadapter.h @@ -27,7 +27,9 @@ #include "cacommon.h" #include "caadapterinterface.h" +#ifndef ARDUINO #include "uthreadpool.h" /* for thread pool */ +#endif //ARDUINO #ifdef __cplusplus extern "C" @@ -42,9 +44,15 @@ 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. @@ -79,8 +87,8 @@ CAResult_t CAStartWIFIDiscoveryServer(); * @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. diff --git a/resource/csdk/connectivity/inc/cawifiadapter_singlethread.h b/resource/csdk/connectivity/inc/cawifiadapter_singlethread.h deleted file mode 100644 index 6642b3e..0000000 --- a/resource/csdk/connectivity/inc/cawifiadapter_singlethread.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************** - * - * 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__ diff --git a/resource/csdk/connectivity/inc/cawifiinterface.h b/resource/csdk/connectivity/inc/cawifiinterface.h index 5b290c6..7845702 100644 --- a/resource/csdk/connectivity/inc/cawifiinterface.h +++ b/resource/csdk/connectivity/inc/cawifiinterface.h @@ -29,7 +29,9 @@ #include #include "cacommon.h" +#ifndef ARDUINO #include "uthreadpool.h" +#endif //ARDUINO #ifdef __cplusplus extern "C" @@ -55,11 +57,18 @@ typedef enum * @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 @@ -82,18 +91,14 @@ typedef void (*CAWiFiExceptionCallback)(CAAdapterServerType_t type); * @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 /** @@ -128,6 +133,7 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult * @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. @@ -136,8 +142,15 @@ CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *mult * @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 @@ -159,11 +172,24 @@ CAResult_t CAWiFiStopMulticastServer(void); */ 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. @@ -173,8 +199,18 @@ CAResult_t CAWiFiStopUnicastServer(); * @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. @@ -216,6 +252,17 @@ void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback); */ 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 @@ -225,16 +272,28 @@ void CAWiFiSetUnicastSocket(const int32_t socketFD); * @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. @@ -258,8 +317,17 @@ typedef void (*CAWiFiConnectionStateChangeCallback)(const char *ipAddress, * @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 @@ -334,4 +402,4 @@ void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback } #endif -#endif //_CA_WIFI_INTERFACE_ \ No newline at end of file +#endif //_CA_WIFI_INTERFACE_ diff --git a/resource/csdk/connectivity/inc/com_iotivity_jar_CALeInterface.h b/resource/csdk/connectivity/inc/com_iotivity_jar_CALeInterface.h index a10a34a..c1e6c23 100644 --- a/resource/csdk/connectivity/inc/com_iotivity_jar_CALeInterface.h +++ b/resource/csdk/connectivity/inc/com_iotivity_jar_CALeInterface.h @@ -13,7 +13,7 @@ extern "C" { * 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 @@ -21,7 +21,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeScanCallb * 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 @@ -29,7 +29,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattCallb * 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 @@ -37,7 +37,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeScanCallback * 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 @@ -45,7 +45,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattConnectionSta * 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 @@ -53,7 +53,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServicesDisco * 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 @@ -61,7 +61,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristi * 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 @@ -69,7 +69,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristi * 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 @@ -77,7 +77,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristi * 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 @@ -85,7 +85,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorRea * 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 @@ -93,7 +93,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorWri * 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 @@ -101,7 +101,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReliableWrite * 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 } diff --git a/resource/csdk/connectivity/inc/com_iotivity_jar_CAWiFiInterface.h b/resource/csdk/connectivity/inc/com_iotivity_jar_CAWiFiInterface.h index 828c37a..fcc47d9 100644 --- a/resource/csdk/connectivity/inc/com_iotivity_jar_CAWiFiInterface.h +++ b/resource/csdk/connectivity/inc/com_iotivity_jar_CAWiFiInterface.h @@ -13,7 +13,7 @@ extern "C" { * Signature: ()V */ JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateEnabled - (JNIEnv *, jclass); +(JNIEnv *, jclass); /* * Class: com_iotivity_jar_CAWiFiInterface @@ -21,7 +21,7 @@ JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateEnabled * Signature: ()V */ JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateDisabled - (JNIEnv *, jclass); +(JNIEnv *, jclass); #ifdef __cplusplus } diff --git a/resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_cpp.patch b/resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_cpp.patch new file mode 100644 index 0000000..d66445e --- /dev/null +++ b/resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_cpp.patch @@ -0,0 +1,17 @@ +--- 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); diff --git a/resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_socket_cpp.patch b/resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_socket_cpp.patch new file mode 100644 index 0000000..bec38f6 --- /dev/null +++ b/resource/csdk/connectivity/lib/extlibs/arduino_linux_ethernet_socket_cpp.patch @@ -0,0 +1,59 @@ +--- /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; + } + + diff --git a/resource/csdk/connectivity/samples/arduino/casample.cpp b/resource/csdk/connectivity/samples/arduino/casample.cpp index 14802e5..08a847c 100644 --- a/resource/csdk/connectivity/samples/arduino/casample.cpp +++ b/resource/csdk/connectivity/samples/arduino/casample.cpp @@ -108,6 +108,7 @@ CAConnectivityType_t getConnectivityType() case 3: return CA_LE; } + return CA_ETHERNET; } void setup() { @@ -269,6 +270,27 @@ void send_request() 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); @@ -283,7 +305,9 @@ void send_request() 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)); @@ -411,8 +435,8 @@ void send_notification() 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)); @@ -523,7 +547,7 @@ void send_response(CARemoteEndpoint_t *endpoint, CAToken_t request_token) 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)); @@ -545,7 +569,7 @@ void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token) 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)); diff --git a/resource/csdk/connectivity/samples/arduino/sample_main.cpp b/resource/csdk/connectivity/samples/arduino/sample_main.cpp index 81f9200..d994c28 100644 --- a/resource/csdk/connectivity/samples/arduino/sample_main.cpp +++ b/resource/csdk/connectivity/samples/arduino/sample_main.cpp @@ -35,7 +35,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include "Arduino.h" #include "caadapterinterface.h" #include "cacommon.h" -#include "caleadapter_singlethread.h" +#include "caleadapter.h" #include #include @@ -168,17 +168,17 @@ void loop() 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(); } @@ -192,7 +192,7 @@ void loop() #include "Arduino.h" -#include "cawifiadapter_singlethread.h" +#include "cawifiadapter.h" #include #include "caadapterinterface.h" @@ -230,7 +230,7 @@ int16_t CAInterfaceInitializeEndpoint() 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; @@ -356,8 +356,8 @@ int16_t CAInterfaceStartServer(CAConnectivityType_t connType) 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(); @@ -392,7 +392,7 @@ int16_t CAInterfaceSendUnicastData(CAConnectivityType_t connType) 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) diff --git a/resource/csdk/connectivity/samples/linux/README b/resource/csdk/connectivity/samples/linux/README index 53c5564..a16842c 100644 --- a/resource/csdk/connectivity/samples/linux/README +++ b/resource/csdk/connectivity/samples/linux/README @@ -12,3 +12,7 @@ #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) + + diff --git a/resource/csdk/connectivity/samples/linux/sample.sh b/resource/csdk/connectivity/samples/linux/sample.sh index 7bb9135..ce04425 100644 --- a/resource/csdk/connectivity/samples/linux/sample.sh +++ b/resource/csdk/connectivity/samples/linux/sample.sh @@ -24,7 +24,12 @@ make 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 diff --git a/resource/csdk/connectivity/samples/linux/sample_main.c b/resource/csdk/connectivity/samples/linux/sample_main.c index 37852ca..10f62f6 100644 --- a/resource/csdk/connectivity/samples/linux/sample_main.c +++ b/resource/csdk/connectivity/samples/linux/sample_main.c @@ -21,15 +21,34 @@ #include #include #include +#include #include #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(); @@ -47,12 +66,66 @@ void handle_request_response(); 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() { @@ -62,6 +135,16 @@ 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) { @@ -90,6 +173,7 @@ int main() process(); CATerminate(); + clearDtlsCredentialInfo(); return 0; } @@ -164,9 +248,9 @@ void process() case 'Y': while (1) { - received = FALSE; + gReceived = 0; find_fixed_resource(); - while (received == FALSE) + while (gReceived == 0) { sleep(1); handle_request_response(); @@ -197,6 +281,8 @@ void process() } + + void start_listening_server() { printf("start listening server!!\n"); @@ -233,8 +319,6 @@ void find_fixed_resource() { 0, }; strcpy(buf, "a/light"); - - // create token CAToken_t token = NULL; CAResult_t res = CAGenerateToken(&token); @@ -258,11 +342,11 @@ void find_fixed_resource() // delete token /* - if (token != NULL) - { - CADestroyToken(token); - } - */ + if (token != NULL) + { + CADestroyToken(token); + } + */ printf("=============================================\n"); } @@ -304,44 +388,59 @@ void find_resource() // 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; @@ -349,11 +448,29 @@ void send_request() 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)); @@ -369,11 +486,7 @@ void send_request() } // destroy remote endpoint - if (endpoint != NULL) - { - CADestroyRemoteEndpoint(endpoint); - } - + CADestroyRemoteEndpoint(endpoint); printf("=============================================\n"); } @@ -391,7 +504,7 @@ void send_request_all() gets(buf); // create remote endpoint - CARemoteEndpoint_t* endpoint = NULL; + CARemoteEndpoint_t *endpoint = NULL; CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint); if (res != CA_STATUS_OK) @@ -402,11 +515,11 @@ void send_request_all() } - 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; @@ -467,7 +580,7 @@ void advertise_resource() 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"); @@ -508,11 +621,11 @@ void advertise_resource() // delete token /* - if (token != NULL) - { - CADestroyToken(token); - } - */ + if (token != NULL) + { + CADestroyToken(token); + } + */ free(headerOpt); @@ -532,7 +645,7 @@ void send_notification() gets(buf); // create remote endpoint - CARemoteEndpoint_t* endpoint = NULL; + CARemoteEndpoint_t *endpoint = NULL; CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint); if (res != CA_STATUS_OK) @@ -685,19 +798,20 @@ void get_network_info() { 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) @@ -705,37 +819,54 @@ void get_network_info() 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) { @@ -743,32 +874,61 @@ void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* re 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) { @@ -776,37 +936,50 @@ void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* 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) @@ -819,10 +992,9 @@ void send_response(CARemoteEndpoint_t* endpoint, CAToken_t request_token) } 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"); @@ -854,3 +1026,73 @@ void send_request_tmp(CARemoteEndpoint_t* endpoint, CAToken_t token) } +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); +} diff --git a/resource/csdk/connectivity/samples/tizen/casample.c b/resource/csdk/connectivity/samples/tizen/casample.c index b493ad0..60edefd 100644 --- a/resource/csdk/connectivity/samples/tizen/casample.c +++ b/resource/csdk/connectivity/samples/tizen/casample.c @@ -179,7 +179,7 @@ void find_resource() gets(buf); - // create token + // create token CAToken_t token = NULL; CAResult_t res = CAGenerateToken(&token); if (res != CA_STATUS_OK) @@ -285,7 +285,7 @@ void advertise_resource() scanf("%d", &optionNum); CAHeaderOption_t *headerOpt; - if(optionNum > 0) + if (optionNum > 0) { headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum); if (NULL == headerOpt) @@ -417,19 +417,22 @@ void handle_request_response() 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 ); } } @@ -439,23 +442,27 @@ void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *re } -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 ); } } diff --git a/resource/csdk/connectivity/samples/tizen/interfacesample.c b/resource/csdk/connectivity/samples/tizen/interfacesample.c index 9ea21a3..7f8f018 100644 --- a/resource/csdk/connectivity/samples/tizen/interfacesample.c +++ b/resource/csdk/connectivity/samples/tizen/interfacesample.c @@ -34,11 +34,11 @@ #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) @@ -53,10 +53,10 @@ static u_thread_pool_t gBTThreadPool = NULL; 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 @@ -104,7 +104,7 @@ void initializeThreadPool(CAConnectivityType_t type) #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; @@ -347,7 +347,7 @@ int16_t interfaceSendUnicastData(CAConnectivityType_t connType) } 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)); @@ -412,8 +412,8 @@ int16_t interfaceSendUnicastData(CAConnectivityType_t connType) } 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)); @@ -955,6 +955,7 @@ void testTerminateBTInterface(void) printf( "Terminating BT Adapter thread pool"); u_thread_pool_free(gBTThreadPool); + gBTThreadPool = NULL; } #endif //BT_ADAPTER_TEST @@ -987,6 +988,7 @@ void testTerminateWIFIInterface(void) // 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(); @@ -1024,6 +1026,7 @@ void testTerminateBLEInterface(void) printf( "Terminating BLE Adapter thread pool"); u_thread_pool_free(gLEThreadPool); + gLEThreadPool = NULL; printf("testTerminateBLEInterface OUT\n"); } diff --git a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c index 71b192b..0f87e4e 100644 --- a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c +++ b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c @@ -26,8 +26,8 @@ #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)); @@ -93,8 +93,10 @@ CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(CALocalConnectivity_t *connect 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; } @@ -106,8 +108,9 @@ void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndpoint) } } -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)); @@ -186,6 +189,7 @@ CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remote info->resourceUri = OICStrdup(remoteEndpoint->resourceUri); } + info->isSecured = remoteEndpoint->isSecured; return info; } diff --git a/resource/csdk/connectivity/src/adapter_util/camessagequeue.c b/resource/csdk/connectivity/src/adapter_util/camessagequeue.c deleted file mode 100644 index c345d70..0000000 --- a/resource/csdk/connectivity/src/adapter_util/camessagequeue.c +++ /dev/null @@ -1,200 +0,0 @@ -/****************************************************************** - * - * 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 -#include -#include -#include - -#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; -} - diff --git a/resource/csdk/connectivity/src/adapter_util/camsgparser.c b/resource/csdk/connectivity/src/adapter_util/camsgparser.c index f60c07f..50a403b 100644 --- a/resource/csdk/connectivity/src/adapter_util/camsgparser.c +++ b/resource/csdk/connectivity/src/adapter_util/camsgparser.c @@ -167,6 +167,7 @@ uint32_t CAFragmentData(const char *data, char **dataSegment, uint32_t TotalLen, if (CA_STATUS_OK != result ) { OIC_LOG(ERROR, CA_MSG_PARSER_TAG, "Generate header failed"); + OICFree(header); return -1; } @@ -189,28 +190,3 @@ uint32_t CAFragmentData(const char *data, char **dataSegment, uint32_t TotalLen, } -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; - -} - - - diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c b/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c index 8735d96..79f5e66 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c @@ -31,8 +31,8 @@ static CANetworkPacketReceivedCallback gEDRReceivedCallback = NULL; 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"); @@ -79,21 +79,21 @@ CAResult_t CAStartEDRDiscoveryServer() 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"); diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.c index 57ba895..15126f7 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.c @@ -32,8 +32,8 @@ CAResult_t CABTClientConnect(const char *remoteAddress, const char *serviceUUID) { 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"); @@ -74,7 +74,7 @@ CAResult_t CABTClientDisconnect(const int32_t clientID) 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]", @@ -83,5 +83,6 @@ CAResult_t CABTClientDisconnect(const int32_t clientID) } OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; } diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c index 15cf3e8..56223d7 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c @@ -54,7 +54,7 @@ static void CADestroyBTData(BTData *data); 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"); @@ -119,7 +119,7 @@ CAResult_t CACreateBTDevice(const char *deviceAddress, const char *uuid, BTDevic 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); @@ -371,7 +371,7 @@ void CADestroyBTDataList(BTDataList **dataList) { BTDataList *curNode = *dataList; *dataList = (*dataList)->next; - + CADestroyBTData(curNode->data); OICFree(curNode); } diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h index c85970d..f464794 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h @@ -92,7 +92,7 @@ typedef struct _BTDeviceList * */ CAResult_t CACreateAndAddToDeviceList(BTDeviceList **deviceList, const char *deviceAddress, - const char *uuid, BTDevice **device); + const char *uuid, BTDevice **device); /** * @fn CAAddBTDeviceToList diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c index 513550a..93ab106 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c @@ -42,7 +42,7 @@ CAResult_t CABTSendData(const int32_t serverFD, const void *data, const uint32_t 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) { diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c index af2393d..0f897c0 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c @@ -30,7 +30,7 @@ #include "cabtdevicelist.h" #include "cabtutils.h" #include "caadapterutils.h" -#include "camessagequeue.h" +#include "caqueueingthread.h" #include "camsgparser.h" /** @@ -44,16 +44,15 @@ typedef struct } 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 @@ -92,59 +91,42 @@ static CALocalConnectivity_t *gLocalConnectivity = NULL; 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. */ @@ -156,7 +138,7 @@ static void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapte * @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); /** @@ -171,7 +153,7 @@ static void CABTDataRecvCallback(bt_socket_received_data_s *data, 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); @@ -180,16 +162,28 @@ static void CABTDeviceDiscoveryCallback(int result, * @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. */ @@ -224,14 +218,14 @@ static void CABTManagerDataReceiverHandler(void *context); * @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 @@ -294,11 +288,25 @@ static void CABTFreeNetworkEvent(CABTNetworkEvent *event); */ 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())) @@ -308,14 +316,6 @@ CAResult_t CABTManagerInitialize(u_thread_pool_t threadPool) 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(); @@ -324,27 +324,18 @@ CAResult_t CABTManagerInitialize(u_thread_pool_t threadPool) 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; @@ -405,7 +396,8 @@ CAResult_t CABTManagerStart(void) 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 @@ -417,23 +409,18 @@ CAResult_t CABTManagerStart(void) //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; } @@ -445,30 +432,18 @@ void CABTManagerStop(void) { 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(); @@ -482,21 +457,29 @@ void CABTManagerStop(void) 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"); @@ -511,22 +494,13 @@ CAResult_t CABTManagerPushDataToReceiverQueue(const char *remoteAddress, const c 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; } @@ -535,18 +509,17 @@ CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUI { 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) @@ -555,46 +528,64 @@ CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUI 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 @@ -610,7 +601,7 @@ CAResult_t CABTManagerGetInterface(CALocalConnectivity_t **info) } //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!"); @@ -636,115 +627,113 @@ CAResult_t CABTManagerInitializeQueues(void) { 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"); } @@ -753,78 +742,70 @@ void CABTManagerDataReceiverHandler(void *context) { 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"); } @@ -833,95 +814,85 @@ void CABTManagerDataSendHandler(void *context) { 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"); } @@ -976,7 +947,7 @@ CAResult_t CABTManagerSendUnicastData(const char *remoteAddress, const char *ser { //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!"); @@ -1010,8 +981,8 @@ CAResult_t CABTManagerSendUnicastData(const char *remoteAddress, const char *ser 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"); @@ -1041,7 +1012,7 @@ CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data, uin OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "There is no device!"); break; } - + if (-1 == device->socketFD) { //Check if the device service search is finished @@ -1053,7 +1024,7 @@ CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data, uin //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; @@ -1091,7 +1062,7 @@ CAResult_t CABTGetAdapterEnableState(bool *state) //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 @@ -1117,7 +1088,7 @@ CAResult_t CABTStartDeviceDiscovery(void) { 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 @@ -1138,7 +1109,7 @@ CAResult_t CABTStartDeviceDiscovery(void) return CA_STATUS_FAILED; } } - + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); return CA_STATUS_OK; } @@ -1147,7 +1118,7 @@ CAResult_t CABTStopDeviceDiscovery(void) { 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 @@ -1164,7 +1135,7 @@ CAResult_t CABTStopDeviceDiscovery(void) 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); } } @@ -1177,7 +1148,7 @@ CAResult_t CABTStartServiceSearch(const char *remoteAddress) { 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"); @@ -1203,7 +1174,7 @@ CAResult_t CABTStopServiceSearch(void) { 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())) @@ -1217,12 +1188,25 @@ CAResult_t CABTStopServiceSearch(void) 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); } @@ -1230,12 +1214,13 @@ void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState, { //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"); @@ -1249,7 +1234,7 @@ void CABTSocketConnectionStateCallback(int result, bt_socket_connection_state_e return; } - switch (connectionState) + switch (state) { case BT_SOCKET_CONNECTED: { @@ -1363,7 +1348,7 @@ void CABTDataRecvCallback(bt_socket_received_data_s *data, void *userData) 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"); @@ -1377,7 +1362,7 @@ void CABTDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e return; } - switch (discoveryState) + switch (state) { case BT_ADAPTER_DEVICE_DISCOVERY_STARTED: { @@ -1396,8 +1381,8 @@ void CABTDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e 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); @@ -1432,7 +1417,7 @@ void CABTDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e 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"); @@ -1456,7 +1441,7 @@ void CABTServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo, void } 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)) @@ -1566,9 +1551,9 @@ void CABTFreeNetworkEvent(CABTNetworkEvent *event) void CABTManagerDisconnectAll(void) { OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); - + u_mutex_lock(gBTDeviceListMutex); - + BTDeviceList *cur = gBTDeviceList; while (cur != NULL) { @@ -1579,15 +1564,48 @@ void CABTManagerDisconnectAll(void) { 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); +} diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h index 76a7b0c..3fdc8cc 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h @@ -144,7 +144,6 @@ CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUI * @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 @@ -153,14 +152,12 @@ CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUI * @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 @@ -169,7 +166,7 @@ CAResult_t CABTManagerStartServer(const char *serviceUUID, int32_t *serverID); * * @see CABTManagerStartServer() */ -CAResult_t CABTManagerStopServer(const int32_t serverID); +CAResult_t CABTManagerStopServer(void); /** * @fn CABTManagerGetInterface diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c index 8c0f2e0..c35018b 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c @@ -34,9 +34,9 @@ CAResult_t CABTServerStart(const char *serviceUUID, int32_t *serverFD) { 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"); @@ -89,7 +89,7 @@ CAResult_t CABTServerStop(const int32_t serverFD) { 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]", diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c index 661a6c2..a861b96 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c @@ -29,7 +29,7 @@ #include bool CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount, - const char *matchService) + const char *matchService) { OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h index 92192be..7a2293a 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h @@ -57,7 +57,7 @@ extern "C" * */ bool CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount, - const char *matchService); + const char *matchService); #ifdef __cplusplus } /* extern "C" */ diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c index b8f98f7..c9a39a9 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c @@ -29,11 +29,7 @@ #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, @@ -46,11 +42,11 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, //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 @@ -102,18 +98,18 @@ CAResult_t CAStartEDRListeningServer(void) { 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"); @@ -139,7 +135,7 @@ uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *da 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; @@ -210,23 +206,7 @@ CAResult_t CAStopEDR(void) { 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(); @@ -245,22 +225,13 @@ void CATerminateEDR(void) 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); diff --git a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp index d7db5a7..504201d 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp +++ b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleadapter.cpp @@ -17,24 +17,57 @@ * limitations under the License. * ******************************************************************/ -#include "caleadapter_singlethread.h" +#include "caleadapter.h" + +#include + +#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) @@ -43,7 +76,7 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, return CA_STATUS_INVALID_PARAM; } - CASetBLEReqRescallback(reqRespCallback); + gRespCallback = reqRespCallback; LERegisterNetworkNotifications(netCallback); CAConnectivityHandler_t connHandler; connHandler.startAdapter = NULL; @@ -61,14 +94,17 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, 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; @@ -77,7 +113,9 @@ CAResult_t CAStartLEListeningServer() { OIC_LOG(DEBUG, TAG, "IN"); CAInitializeBle(); - CAArduoinoCheckServerData(); + gRcvAction.enable(); + CABleDoEvents(); + gRcvAction.check(); OIC_LOG(DEBUG, TAG, "OUT"); return CA_STATUS_OK; } @@ -96,14 +134,64 @@ CAResult_t CAStartLENotifyServer() 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) @@ -111,8 +199,7 @@ uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *dat 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; } @@ -125,8 +212,7 @@ uint32_t CASendLEMulticastData(void *data, uint32_t dataLen) 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; } @@ -144,7 +230,7 @@ CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *s /** * 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"); @@ -156,10 +242,100 @@ CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *s 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; +} + + diff --git a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.cpp b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.cpp index f04b526..22f307b 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.cpp +++ b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.cpp @@ -21,16 +21,7 @@ #include "caleserver.h" #include #include "oic_malloc.h" -#include - -#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" @@ -44,107 +35,12 @@ CAResult_t CAInitializeBle() 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 @@ -169,7 +65,8 @@ CAResult_t CARegisterBleServicewithGattServer(const char *svc_path) 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) @@ -184,44 +81,29 @@ CAResult_t CARemoveCharacteristicsFromGattServer(const char *char_path) 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 diff --git a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.h b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.h index 61f3b23..979c529 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.h +++ b/resource/csdk/connectivity/src/bt_le_adapter/arduino/caleserver.h @@ -28,7 +28,6 @@ #include #include #include -#include #include "cacommon.h" #include "caadapterinterface.h" @@ -50,38 +49,6 @@ CAResult_t CAInitializeBle(); 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 @@ -119,27 +86,53 @@ CAResult_t CARegisterBleServicewithGattServer(const char *svc_path); * @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_ diff --git a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c index 7b2c713..d5c74b8 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c @@ -40,6 +40,10 @@ #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; @@ -54,11 +58,111 @@ static u_mutex gBleNetworkCbMutex = 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(); @@ -77,7 +181,6 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, 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!"); @@ -92,8 +195,11 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, CASetBleServerThreadPoolHandle(handle); CASetBleClientThreadPoolHandle(handle); - CASetBLEReqRespServerCallback(reqRespCallback); - CASetBLEReqRespClientCallback(reqRespCallback); + CASetBleAdapterThreadPoolHandle(handle); + CASetBLEReqRespServerCallback(CABLEServerReceivedData); + CASetBLEReqRespClientCallback(CABLEClientReceivedData); + CASetBLEReqRespAdapterCallback(reqRespCallback); + CALERegisterNetworkNotifications(netCallback); CAConnectivityHandler_t connHandler; @@ -132,6 +238,8 @@ void CATerminateLE() } u_mutex_unlock(gBleIsServerMutex); + CATerminateBleQueues(); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return; } @@ -140,6 +248,32 @@ CAResult_t CAStartLEListeningServer() { 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"); @@ -153,6 +287,32 @@ CAResult_t CAStartLEDiscoveryServer() { 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"); @@ -203,7 +363,7 @@ uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uin 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, @@ -214,8 +374,7 @@ uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uin } else { - - result = CABleClientSenderQueueEnqueueMessage(endpoint, data, dataLen); + result = CABLEClientSendData(endpoint, data, dataLen); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, @@ -252,7 +411,7 @@ uint32_t CASendLEMulticastData(void *data, uint32_t dataLen) 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, @@ -263,7 +422,7 @@ uint32_t CASendLEMulticastData(void *data, uint32_t dataLen) } else { - result = CABleClientSenderQueueEnqueueMessage(NULL, data, dataLen); + result = CABLEClientSendData(NULL, data, dataLen); if (CA_STATUS_OK != result) { OIC_LOG(ERROR, CALEADAPTER_TAG, @@ -363,6 +522,19 @@ void CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, 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) { @@ -373,6 +545,7 @@ void CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, OIC_LOG(ERROR, CALEADAPTER_TAG, "gNetworkCallback is NULL"); } u_mutex_unlock(gBleNetworkCbMutex); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); } @@ -410,19 +583,990 @@ CAResult_t CAInitBleAdapterMutex() 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 diff --git a/resource/csdk/connectivity/src/bt_le_adapter/linux/caleadapter.c b/resource/csdk/connectivity/src/bt_le_adapter/linux/caleadapter.c index 1daf199..44c340b 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/linux/caleadapter.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/linux/caleadapter.c @@ -31,8 +31,8 @@ static CANetworkPacketReceivedCallback gLEReceivedCallback = NULL; 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"); @@ -79,21 +79,21 @@ CAResult_t CAStartLEDiscoveryServer() 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"); diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c index d2f2162..7d10e08 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c @@ -32,7 +32,7 @@ #include "umutex.h" #include "uarraylist.h" -#include "camessagequeue.h" +#include "caqueueingthread.h" #include "caadapterutils.h" #include "camsgparser.h" @@ -61,18 +61,6 @@ static BLEServiceList *gBLEServiceList = NULL; 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. */ @@ -93,42 +81,18 @@ static u_mutex gBleReqRespClientCbMutex = NULL; 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. */ @@ -139,7 +103,7 @@ static u_mutex gBleClientThreadPoolMutex = NULL; * @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 @@ -183,54 +147,6 @@ static const char *gRemoteAddress = "E4:12:1D:99:F3:57"; 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, @@ -254,14 +170,18 @@ void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic, 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; @@ -335,23 +255,6 @@ void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32 "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"); @@ -495,7 +398,6 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void * if (CA_STATUS_OK != retVal) { OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAGetBLEServiceInfo failed! "); - bleServiceInfo = NULL; return; } u_mutex_unlock(gBleServiceListMutex); @@ -606,6 +508,13 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, i 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; @@ -623,6 +532,7 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, i { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDisConnect failed!"); + OICFree(addr); return false; } } @@ -654,7 +564,6 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, i 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! "); @@ -666,13 +575,21 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, i 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; } @@ -739,11 +656,12 @@ void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const cha 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"); @@ -773,8 +691,8 @@ void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const cha 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); @@ -823,6 +741,12 @@ void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result, 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."); @@ -870,93 +794,7 @@ void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result, } 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) @@ -992,13 +830,13 @@ void CASetBleClientThreadPoolHandle(u_thread_pool_t handle) 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); @@ -1018,7 +856,7 @@ CAResult_t CAStartBLEGattClient() 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"); @@ -1038,6 +876,7 @@ CAResult_t CAStartBLEGattClient() } u_mutex_unlock(gBleClientThreadPoolMutex); + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); return CA_STATUS_OK; } @@ -1054,16 +893,7 @@ void *CAStartBleGattClientThread(void *data) 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"); @@ -1096,6 +926,8 @@ void *CAStartBleGattClientThread(void *data) 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(); @@ -1125,13 +957,10 @@ void CAStopBLEGattClient() } 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(); @@ -1146,8 +975,6 @@ void 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); @@ -1180,8 +1007,6 @@ void CATerminateBLEGattClient() CAResetRegisteredServiceCount(); - CATerminateBleQueues(); - gIsBleGattClientStarted = CA_FALSE; u_mutex_unlock(gBleClientStateMutex); @@ -1205,16 +1030,6 @@ CAResult_t CAInitGattClientMutexVaraibles() } } - 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(); @@ -1235,26 +1050,6 @@ CAResult_t CAInitGattClientMutexVaraibles() } } - 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(); @@ -1292,78 +1087,16 @@ void CATerminateGattClientMutexVariables() 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"); @@ -1549,7 +1282,6 @@ void *CAGattConnectThread (void *remoteAddress) { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address); OICFree(address); - address = NULL; return NULL; } @@ -1611,7 +1343,6 @@ void *CADiscoverBLEServicesThread (void *remoteAddress) { OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed"); OICFree(address); - address = NULL; return NULL; } @@ -1640,7 +1371,7 @@ CAResult_t CABleGattDiscoverServices(const char *remoteAddress) 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] ", @@ -1891,148 +1622,8 @@ CAResult_t CABleGATTCreateBond(const char *remoteAddress) 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"); @@ -2101,7 +1692,7 @@ CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const 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"); @@ -2135,13 +1726,3 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, int32_t d 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; -} - diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h index 213dcda..beff2ae 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h @@ -30,7 +30,7 @@ #include "caadapterinterface.h" #include "logger.h" #include "uthreadpool.h" - +#include "caleinterface.h" /** @@ -77,7 +77,8 @@ void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32 /** * @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 @@ -121,7 +122,8 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, i /** * @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 @@ -174,32 +176,10 @@ void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discover 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) @@ -210,27 +190,6 @@ CAResult_t CAStartBLEGattClient(); 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. * @@ -252,24 +211,6 @@ CAResult_t CAInitGattClientMutexVaraibles(); 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 * @@ -396,7 +337,8 @@ CAResult_t CABleGattDisConnect(const char *remoteAddress); /** * @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. * @@ -423,7 +365,8 @@ CAResult_t CABleGattDiscoverServices(const char *remoteAddress); * @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. * @@ -449,7 +392,8 @@ CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service, const c * @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. * @@ -475,7 +419,8 @@ CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char * * @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. * @@ -500,7 +445,8 @@ CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattChar * @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. * @@ -523,7 +469,8 @@ CAResult_t CABleGATTCreateBond(const char *remoteAddress); /** * @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 @@ -548,38 +495,6 @@ CAResult_t CABleClientSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remote 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. * diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h index 1019561..bfe5478 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h @@ -84,18 +84,12 @@ typedef enum 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; @@ -103,7 +97,7 @@ typedef struct gattCharDescriptor 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 @@ -289,4 +283,5 @@ CAResult_t CAVerifyOICService(bt_gatt_attribute_h serviceHandle); * */ const char *CABTGetErrorMsg(bt_error_e err); + #endif //#ifndef _BLE_CLIENT_UTIL diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c index 1ba782f..31d9ad9 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c @@ -18,13 +18,17 @@ * ******************************************************************/ +#include +#include +#include + #include "cableserver.h" #include #include "cacommon.h" #include "caadapterutils.h" #include #include "umutex.h" -#include "camessagequeue.h" +#include "caqueueingthread.h" #include "caadapterutils.h" #include "camsgparser.h" #include "cableclientutil.h" @@ -35,7 +39,14 @@ */ #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 @@ -62,23 +73,11 @@ static char *gGattWriteCharPath = NULL; 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 @@ -113,12 +112,6 @@ static u_mutex gBleServiceMutex = NULL; 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. */ @@ -143,23 +136,12 @@ static u_cond gReceiverDataCond = NULL; 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 @@ -179,232 +161,6 @@ static u_thread_pool_t gBleServerThreadPool = NULL; */ 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. @@ -438,39 +194,8 @@ CAResult_t CAStartBleGattServer() 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; @@ -500,7 +225,7 @@ void *CAStartBleGattServerThread(void *data) sleep(5); // Sleep is must. otherwise its crashing - char *serviceUUID = "713d0000-503e-4c75-ba94-3148f18d941e"; + char *serviceUUID = CA_BLE_SERVICE_UUID; ret = CAAddNewBleServiceInGattServer(serviceUUID); @@ -512,7 +237,7 @@ void *CAStartBleGattServerThread(void *data) return NULL; } - char *charReadUUID = "00002af5-0000-1000-8000-00805f9b34fb"; + char *charReadUUID = CA_BLE_READ_CHAR_UUID; char charReadValue[4] = {33, 44, 55, 66}; @@ -527,7 +252,7 @@ void *CAStartBleGattServerThread(void *data) return NULL; } - char *charWriteUUID = "00002af6-0000-1000-8000-00805f9b34fb"; + char *charWriteUUID = CA_BLE_WRITE_CHAR_UUID; char charWriteValue[4] = {33, 44, 55, 66}; @@ -611,13 +336,10 @@ CAResult_t CAStopBleGattServer() } 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(); @@ -698,24 +420,6 @@ void 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"); @@ -764,47 +468,6 @@ CAResult_t CAInitGattServerMutexVaraibles() 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() @@ -813,11 +476,6 @@ 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; @@ -826,15 +484,6 @@ void CATerminateGattServerMutexVaraibles() 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() @@ -875,14 +524,6 @@ void CASetBleServerThreadPoolHandle(u_thread_pool_t handle) 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"); @@ -977,7 +618,6 @@ void CABleGattRemoteCharacteristicWriteCb(char *charPath, if (NULL == data) { OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc failed!"); - // OICFree(remoteEndPoint); return; } @@ -987,47 +627,20 @@ void CABleGattRemoteCharacteristicWriteCb(char *charPath, 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) @@ -1051,8 +664,8 @@ 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"); @@ -1109,7 +722,8 @@ CAResult_t CARemoveCharacteristicsFromGattServer(const char *charPath) 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"); @@ -1125,7 +739,6 @@ CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, int32_t ch } char *data = (char *) OICMalloc(sizeof(char) * (charValueLen + 1)); - if (NULL == data) { OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "malloc failed!"); @@ -1149,7 +762,6 @@ CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, int32_t ch return CA_STATUS_FAILED; } OICFree(data); - data = NULL; u_mutex_unlock(gBleCharacteristicMutex); @@ -1158,13 +770,13 @@ CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, int32_t ch 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); diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h index 7a274a7..20a94e4 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h @@ -20,25 +20,10 @@ #ifndef __TZ_BLE_SERVER_H_ #define __TZ_BLE_SERVER_H_ -#include -#include -#include - #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 @@ -54,18 +39,6 @@ CAResult_t CAStartBleGattServer(); 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. * @@ -206,8 +179,9 @@ CAResult_t CARegisterBleServicewithGattServer(const char *svcPath); * @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 @@ -224,22 +198,6 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUU 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. * @@ -255,17 +213,6 @@ void CABleGattRemoteCharacteristicWriteCb(char *charPath, 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. * @@ -279,7 +226,8 @@ CAResult_t CALEReadDataFromLEServer(); /** * @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 diff --git a/resource/csdk/connectivity/src/caadapternetdtls.c b/resource/csdk/connectivity/src/caadapternetdtls.c new file mode 100644 index 0000000..4313378 --- /dev/null +++ b/resource/csdk/connectivity/src/caadapternetdtls.c @@ -0,0 +1,600 @@ +/****************************************************************** + * + * 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; +} + diff --git a/resource/csdk/connectivity/src/caconnectivitymanager.c b/resource/csdk/connectivity/src/caconnectivitymanager.c index 86310e9..0c2d086 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager.c @@ -76,11 +76,11 @@ CAResult_t CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback Re 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; @@ -90,14 +90,14 @@ CAResult_t CACreateRemoteEndpoint(const CAURI_t uri, CARemoteEndpoint_t** 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"); @@ -111,7 +111,7 @@ void CADestroyToken(CAToken_t token) 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"); @@ -126,22 +126,22 @@ CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token) } -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"); @@ -149,7 +149,7 @@ CAResult_t CASendNotification(const CARemoteEndpoint_t* object, CAResponseInfo_t } -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"); @@ -157,8 +157,8 @@ CAResult_t CASendResponse(const CARemoteEndpoint_t* object, CAResponseInfo_t* re } -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"); diff --git a/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c b/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c index d304bbd..772ab1f 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c @@ -142,8 +142,9 @@ CAResult_t CASendResponse(const CARemoteEndpoint_t *object, CAResponseInfo_t *re 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); } diff --git a/resource/csdk/connectivity/src/cainterfacecontroller.c b/resource/csdk/connectivity/src/cainterfacecontroller.c index 3f36e5b..1c92ab6 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@ -83,8 +83,8 @@ static void CARegisterCallback(CAConnectivityHandler_t handler, CAConnectivityTy 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"); @@ -95,8 +95,8 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, } } -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"); @@ -120,18 +120,18 @@ void CAInitializeAdapters(u_thread_pool_t handle) #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 */ } @@ -213,7 +213,7 @@ CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size) 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); } } @@ -275,7 +275,7 @@ memory_error_exit: 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.."); @@ -323,7 +323,7 @@ CAResult_t CASendMulticastData(void *data, uint32_t length) 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); @@ -335,7 +335,7 @@ CAResult_t CASendMulticastData(void *data, uint32_t length) 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!"); @@ -364,7 +364,7 @@ CAResult_t CAStartListeningServerAdapters() 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); @@ -399,7 +399,7 @@ CAResult_t CAStartDiscoveryServerAdapters() 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); @@ -428,8 +428,8 @@ void CATerminateAdapters() { if (gAdapterHandler[index].terminate != NULL) { - gAdapterHandler[index].stopAdapter(); - gAdapterHandler[index].terminate(); + gAdapterHandler[index].stopAdapter(); + gAdapterHandler[index].terminate(); } } } diff --git a/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c b/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c index ff88e54..f282f9b 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c @@ -25,10 +25,10 @@ #include #include -#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" @@ -36,7 +36,7 @@ #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 @@ -240,7 +240,7 @@ CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size) // #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; @@ -320,9 +320,16 @@ CAResult_t CASendMulticastData(void *data, uint32_t length) 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); @@ -355,9 +362,16 @@ CAResult_t CAStartListeningServerAdapters() 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); @@ -390,9 +404,16 @@ CAResult_t CAStartDiscoveryServerAdapters() 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); @@ -440,10 +461,16 @@ CAResult_t CAReadData() 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); diff --git a/resource/csdk/connectivity/src/camessagehandler.c b/resource/csdk/connectivity/src/camessagehandler.c index b39ee81..07ff442 100644 --- a/resource/csdk/connectivity/src/camessagehandler.c +++ b/resource/csdk/connectivity/src/camessagehandler.c @@ -34,12 +34,13 @@ #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 @@ -66,6 +67,8 @@ static u_thread_pool_t gThreadPoolHandle = NULL; static CAQueueingThread_t gSendThread; static CAQueueingThread_t gReceiveThread; +static CARetransmission_t gRetransmissionContext; + // handler field static CARequestCallback gRequestHandler = NULL; static CAResponseCallback gResponseHandler = NULL; @@ -113,7 +116,7 @@ static void CASendThreadProcess(void *threadData) 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 { @@ -129,7 +132,7 @@ static void CASendThreadProcess(void *threadData) 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); @@ -137,6 +140,10 @@ static void CASendThreadProcess(void *threadData) 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); } @@ -164,7 +171,7 @@ static void CASendThreadProcess(void *threadData) 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); @@ -177,11 +184,11 @@ static void CASendThreadProcess(void *threadData) { 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!!"); @@ -229,8 +236,8 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, 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) @@ -328,6 +335,9 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, cadata->responseInfo = ResInfo; CAQueueingThreadAddData(&gReceiveThread, cadata, sizeof(CAData_t)); + + // for retransmission + CARetransmissionReceivedData(&gRetransmissionContext, endpoint, pdu->hdr, pdu->length); } } @@ -423,8 +433,8 @@ void CAHandleRequestResponseCallbacks() 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"); @@ -434,18 +444,18 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, } 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; @@ -474,19 +484,19 @@ memory_error_exit: } 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)); @@ -494,11 +504,11 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t* object, 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; @@ -512,7 +522,7 @@ CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t* object, return CA_STATUS_OK; // memory error label. - memory_error_exit: +memory_error_exit: CADestroyRemoteEndpointInternal(remoteEndpoint); @@ -537,18 +547,18 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object, } 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; @@ -577,14 +587,14 @@ memory_error_exit: } 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)); @@ -597,8 +607,8 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_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 !"); @@ -620,7 +630,7 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t 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); @@ -647,8 +657,8 @@ memory_error_exit: 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."); @@ -699,6 +709,18 @@ CAResult_t CAInitializeMessageHandler() // 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); @@ -710,6 +732,10 @@ void CATerminateMessageHandler() // terminate interface adapters by controller CATerminateAdapters(); + // stop retransmission + CARetransmissionStop(&gRetransmissionContext); + CARetransmissionDestroy(&gRetransmissionContext); + // stop thread // delete thread data CAQueueingThreadStop(&gSendThread); diff --git a/resource/csdk/connectivity/src/camessagehandler_singlethread.c b/resource/csdk/connectivity/src/camessagehandler_singlethread.c index 6955f69..55c7196 100644 --- a/resource/csdk/connectivity/src/camessagehandler_singlethread.c +++ b/resource/csdk/connectivity/src/camessagehandler_singlethread.c @@ -37,7 +37,7 @@ #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 @@ -59,6 +59,8 @@ typedef struct // message handler callback static CAMessageHandlerCallback gHandlerCallback = NULL; +static CARetransmission_t gRetransmissionContext; + // handler field static CARequestCallback gRequestHandler = NULL; static CAResponseCallback gResponseHandler = NULL; @@ -106,6 +108,10 @@ static void CAProcessData(CAData_t *data) 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); } } @@ -173,7 +179,6 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u coap_delete_pdu(pdu); return; } - VERIFY_NON_NULL_VOID(ReqInfo, TAG1, "reqInfo"); memset(ReqInfo, 0, sizeof(CARequestInfo_t)); CAGetRequestInfoFromPdu(pdu, ReqInfo, uri); @@ -188,7 +193,7 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u } } - if(NULL != ReqInfo->info.payload) + if (NULL != ReqInfo->info.payload) { OIC_LOG_V(DEBUG, TAG1, "Request- payload: %s", ReqInfo->info.payload); } @@ -230,7 +235,6 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u coap_delete_pdu(pdu); return; } - VERIFY_NON_NULL_VOID(ResInfo, TAG1, "ResInfo"); memset(ResInfo, 0, sizeof(CAResponseInfo_t)); CAGetResponseInfoFromPdu(pdu, ResInfo, uri); @@ -244,7 +248,7 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u 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); } @@ -272,6 +276,9 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u if (gResponseHandler) { gResponseHandler(endpoint, ResInfo); + + // for retransmission + CARetransmissionReceivedData(&gRetransmissionContext, endpoint, pdu->hdr, pdu->length); } CADestroyResponseInfoInternal(ResInfo); } @@ -293,6 +300,7 @@ static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatu void CAHandleRequestResponseCallbacks() { CAReadData(); + CARetransmissionBaseRoutine((void*)&gRetransmissionContext); } CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request) @@ -301,20 +309,22 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequ 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; @@ -350,20 +360,21 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object, 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; @@ -393,7 +404,8 @@ memory_error_exit: 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"); @@ -401,27 +413,23 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t { 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; @@ -437,7 +445,7 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t 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); @@ -488,6 +496,11 @@ CAResult_t CAInitializeMessageHandler() CASetNetworkChangeCallback(CANetworkChangedCallback); + CAResult_t res; + + // retransmission initialize + CARetransmissionInitialize(&gRetransmissionContext, CASendUnicastData, NULL); + CAInitializeAdapters(); OIC_LOG(DEBUG, TAG1, "OUT"); return CA_STATUS_OK; @@ -499,6 +512,10 @@ void CATerminateMessageHandler() // terminate interface adapters by controller CATerminateAdapters(); + // stop retransmission + CARetransmissionStop(&gRetransmissionContext); + CARetransmissionDestroy(&gRetransmissionContext); + OIC_LOG(DEBUG, TAG1, "OUT"); } diff --git a/resource/csdk/connectivity/src/canetworkconfigurator.c b/resource/csdk/connectivity/src/canetworkconfigurator.c index 027f095..e1abe8a 100644 --- a/resource/csdk/connectivity/src/canetworkconfigurator.c +++ b/resource/csdk/connectivity/src/canetworkconfigurator.c @@ -123,9 +123,9 @@ CAResult_t CARemoveNetworkType(uint32_t ConnectivityType) 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) { diff --git a/resource/csdk/connectivity/src/canetworkconfigurator_singlethread.c b/resource/csdk/connectivity/src/canetworkconfigurator_singlethread.c index 0ec26a5..d34d785 100644 --- a/resource/csdk/connectivity/src/canetworkconfigurator_singlethread.c +++ b/resource/csdk/connectivity/src/canetworkconfigurator_singlethread.c @@ -110,11 +110,18 @@ CAResult_t CARemoveNetworkType(uint32_t 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) { diff --git a/resource/csdk/connectivity/src/caprotocolmessage.c b/resource/csdk/connectivity/src/caprotocolmessage.c index 988d700..ee9deaf 100644 --- a/resource/csdk/connectivity/src/caprotocolmessage.c +++ b/resource/csdk/connectivity/src/caprotocolmessage.c @@ -40,8 +40,8 @@ #include #endif //#ifdef __ARDUINO__ -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) { OIC_LOG(DEBUG, TAG, "CAGetRequestInfoFromPdu IN"); @@ -55,8 +55,8 @@ uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqI return 1; } -uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, - char *outUri) +uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, + char *outUri) { OIC_LOG(DEBUG, TAG, "CAGetResponseInfoFromPdu IN"); if (NULL == pdu) @@ -139,7 +139,7 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode) } coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *options, - const char* payload, const CAInfo_t info) + const char *payload, const CAInfo_t info) { OIC_LOG(DEBUG, TAG, "CACreatePDUforRequestWithPayload IN"); @@ -153,19 +153,30 @@ coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *opt if (!(pdu = coap_new_pdu())) return NULL; - /* initialize message id */ unsigned short message_id; - prng((unsigned char * )&message_id, sizeof(unsigned short)); + + if (info.messageId == 0) + { + /* initialize message id */ + prng((unsigned char * )&message_id, sizeof(unsigned short)); + ++message_id; + + OIC_LOG_V(DEBUG, TAG, "generate the message id(%d)", message_id); + } + else + { + /* use saved message id */ + message_id = info.messageId; + } pdu->hdr->type = info.type; - ++message_id; pdu->hdr->id = htons(message_id); pdu->hdr->code = code; if (info.token) { pdu->hdr->token_length = CA_MAX_TOKEN_LEN; - if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token)) + if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token)) { OIC_LOG(DEBUG, TAG, "cannot add token to request"); } @@ -195,8 +206,8 @@ coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *opt return pdu; } -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) { OIC_LOG(DEBUG, TAG, "CACreatePDUforRequest IN"); @@ -209,19 +220,30 @@ coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options, return NULL; } - /* initialize message id */ unsigned short message_id; - prng((unsigned char * )&message_id, sizeof(unsigned short)); + + if (info.messageId == 0) + { + /* initialize message id */ + prng((unsigned char * )&message_id, sizeof(unsigned short)); + ++message_id; + + OIC_LOG_V(DEBUG, TAG, "generate the message id(%d)", message_id); + } + else + { + /* use saved message id */ + message_id = info.messageId; + } pdu->hdr->type = info.type; - ++message_id; pdu->hdr->id = htons(message_id); pdu->hdr->code = code; OIC_LOG_V(DEBUG, TAG, "token info : %s, %d", info.token, strlen(info.token)); pdu->hdr->token_length = CA_MAX_TOKEN_LEN; - if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token)) + if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char *) info.token)) { OIC_LOG(DEBUG, TAG, "cannot add token to request"); } @@ -256,7 +278,7 @@ void CAParseURI(const char *uriInfo, coap_list_t **optlist) { coap_insert(optlist, CACreateNewOptionNode(COAP_OPTION_URI_PORT, - coap_encode_var_bytes(portbuf, uri.port), portbuf), + coap_encode_var_bytes(portbuf, uri.port), portbuf), CAOrderOpts); } @@ -312,7 +334,7 @@ void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **o OIC_LOG_V(DEBUG, TAG, "Head Option length: %d", info.options[i].optionLength); coap_insert(optlist, - CACreateNewOptionNode(info.options[i].optionID, + CACreateNewOptionNode(info.options[i].optionID, info.options[i].optionLength, info.options[i].optionData), CAOrderOpts); } @@ -320,8 +342,8 @@ void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **o OIC_LOG(DEBUG, TAG, "CAParseHeadOption OUT"); } -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) { OIC_LOG(DEBUG, TAG, "CACreateNewOptionNode IN"); coap_option *option; @@ -333,7 +355,7 @@ coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length, OIC_LOG(DEBUG, TAG, "Out of memory"); return NULL; } - memset(option, 0, sizeof(coap_option)+length); + memset(option, 0, sizeof(coap_option) + length); COAP_OPTION_KEY(*option) = key; COAP_OPTION_LENGTH(*option) = length; @@ -380,7 +402,9 @@ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter) if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type) { - } else { + } + else + { count++; } } @@ -388,8 +412,8 @@ uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter) return count; } -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) { OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo IN"); char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */ @@ -417,7 +441,10 @@ void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *out // set type outInfo->type = pdu->hdr->type; - if(count > 0) + // set message id + outInfo->messageId = ntohs(pdu->hdr->id); + + if (count > 0) { outInfo->options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * count); if (outInfo->options == NULL) @@ -431,9 +458,9 @@ void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *out while ((option = coap_option_next(&opt_iter))) { - if (CAGetOptionData((uint8_t*)(COAP_OPT_VALUE(option)), - COAP_OPT_LENGTH(option), (uint8_t*)buf, sizeof(buf), - encode)) + if (CAGetOptionData((uint8_t *)(COAP_OPT_VALUE(option)), + COAP_OPT_LENGTH(option), (uint8_t *)buf, sizeof(buf), + encode)) { if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type) { @@ -459,14 +486,16 @@ void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *out memcpy(optionResult + optionLength, buf, strlen((const char *) buf)); optionLength += strlen((const char *) buf); } - } else { + } + else + { if (idx < count) { uint32_t length = (uint32_t) strlen((const char *) buf); - if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH) - { + if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH) + { outInfo->options[idx].optionID = opt_iter.type; outInfo->options[idx].optionLength = length; outInfo->options[idx].protocolID = CA_COAP_ID; @@ -484,11 +513,11 @@ void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *out OIC_LOG(DEBUG, TAG, "inside pdu->hdr->token_length"); outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN); if (outInfo->token == NULL) - { - OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !"); - OICFree(outInfo->options); - return; - } + { + OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !"); + OICFree(outInfo->options); + return; + } memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN); } @@ -592,7 +621,7 @@ void CADeinitialize(CAInfo_t *info) } uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result, - uint32_t buflen, uint32_t encode_always) + uint32_t buflen, uint32_t encode_always) { const unsigned char hex[] = "0123456789ABCDEF"; uint32_t cnt = 0; @@ -631,3 +660,25 @@ uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result, *result = '\0'; return cnt; } + +CAMessageType_t CAGetMessageTypeFromPduBinaryData(const void* pdu, uint32_t size) +{ + // pdu minimum size is 4 byte. + if (size < 4) + return CA_MSG_NONCONFIRM; + + coap_hdr_t* hdr = (coap_hdr_t*) pdu; + + return (CAMessageType_t) hdr->type; +} + +uint16_t CAGetMessageIdFromPduBinaryData(const void* pdu, uint32_t size) +{ + // pdu minimum size is 4 byte. + if (size < 4) + return 0; + + coap_hdr_t* hdr = (coap_hdr_t*) pdu; + + return ntohs(hdr->id); +} diff --git a/resource/csdk/connectivity/src/caqueueingthread.c b/resource/csdk/connectivity/src/caqueueingthread.c index 18da00d..3ce5406 100644 --- a/resource/csdk/connectivity/src/caqueueingthread.c +++ b/resource/csdk/connectivity/src/caqueueingthread.c @@ -53,7 +53,7 @@ static void CAQueueingThreadBaseRoutine(void *threadValue) if (u_queue_get_size(thread->dataQueue) <= 0) { OIC_LOG_V(DEBUG, TAG, "wait.."); - + // wait u_cond_wait(thread->threadCond, thread->threadMutex); @@ -76,6 +76,7 @@ static void CAQueueingThreadBaseRoutine(void *threadValue) thread->threadTask(data); // free + OICFree(message); } u_cond_signal(thread->threadCond); @@ -130,17 +131,16 @@ CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread) 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; } diff --git a/resource/csdk/connectivity/src/caremotehandler.c b/resource/csdk/connectivity/src/caremotehandler.c index b0addc6..435cda9 100644 --- a/resource/csdk/connectivity/src/caremotehandler.c +++ b/resource/csdk/connectivity/src/caremotehandler.c @@ -68,6 +68,9 @@ CARemoteEndpoint_t *CACloneRemoteEndpoint(const CARemoteEndpoint_t *rep) #define COAP_PREFIX "coap://" #define COAP_PREFIX_LEN 7 +#define COAPS_PREFIX "coaps://" +#define COAPS_PREFIX_LEN 8 + // return 1 : ip // return 0 : mac @@ -132,13 +135,20 @@ CARemoteEndpoint_t *CACreateRemoteEndpointUriInternal(const CAURI_t uri) // 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; @@ -211,9 +221,11 @@ CARemoteEndpoint_t *CACreateRemoteEndpointUriInternal(const CAURI_t uri) } 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; } diff --git a/resource/csdk/connectivity/src/caretransmission.c b/resource/csdk/connectivity/src/caretransmission.c new file mode 100644 index 0000000..0d7dc6b --- /dev/null +++ b/resource/csdk/connectivity/src/caretransmission.c @@ -0,0 +1,480 @@ +/****************************************************************** + * + * 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 +#include +#include +#include +#include + +#ifdef __ANDROID__ +#include +#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; +} diff --git a/resource/csdk/connectivity/src/caretransmission_singlethread.cpp b/resource/csdk/connectivity/src/caretransmission_singlethread.cpp new file mode 100644 index 0000000..4a7a262 --- /dev/null +++ b/resource/csdk/connectivity/src/caretransmission_singlethread.cpp @@ -0,0 +1,404 @@ +/****************************************************************** + * + * 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 +#include +#include +#include + +#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; +} diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapter.c b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapter.c deleted file mode 100644 index 6e482a2..0000000 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapter.c +++ /dev/null @@ -1,276 +0,0 @@ -/****************************************************************** - * - * 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 -#include -#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; -} - diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp index 89ab822..a0b64db 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.cpp @@ -17,7 +17,6 @@ * limitations under the License. * ******************************************************************/ - #include "caethernetadapterutils.h" #include @@ -26,106 +25,21 @@ #include #include #include -#include #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; @@ -178,7 +92,6 @@ CAResult_t CAArduinoInitMulticastUdpSocket(const char *mcastAddress, const int16 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); @@ -217,237 +130,8 @@ CAResult_t CAArduinoInitMulticastUdpSocket(const char *mcastAddress, const int16 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; @@ -502,6 +186,7 @@ int16_t CAParseIPv4AddressLocal(unsigned char *ipAddrStr, uint8_t *ipAddr, uint1 { return 1; } - OIC_LOG(DEBUG, MOD_NAME, "OUT"); return 0; } + + diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h index 8d4d90a..9cdee4e 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetadapterutils.h @@ -18,66 +18,42 @@ * ******************************************************************/ -#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 +#include +#include +#include +#include +#include + +#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_ diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp new file mode 100644 index 0000000..556b4b7 --- /dev/null +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetclient.cpp @@ -0,0 +1,135 @@ +/****************************************************************** +* +* 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 +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp new file mode 100644 index 0000000..e90a7b5 --- /dev/null +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetnwmonitor.cpp @@ -0,0 +1,68 @@ +/****************************************************************** +* +* 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 +#include +#include +#include +#include +#include +#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 diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp new file mode 100644 index 0000000..67deff5 --- /dev/null +++ b/resource/csdk/connectivity/src/ethernet_adapter/arduino/caethernetserver.cpp @@ -0,0 +1,309 @@ +/****************************************************************** +* +* 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 +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c index 2bc6d3f..61677f2 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c @@ -114,15 +114,15 @@ static u_thread_pool_t gThreadPool = NULL; 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); @@ -149,6 +149,8 @@ CAResult_t CAEthernetInitializeQueueHandles() CAEthernetSendDataThread)) { OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Initialize send queue thread"); + OICFree(gSendQueueHandle); + gSendQueueHandle = NULL; return CA_STATUS_FAILED; } @@ -168,9 +170,9 @@ void CAEthernetDeinitializeQueueHandles() } 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"); @@ -187,7 +189,7 @@ void CAEthernetNotifyNetworkChange(const char *address, const int16_t port, } void CAEthernetConnectionStateCB(const char *ipAddress, - const CANetworkStatus_t status) + const CANetworkStatus_t status) { OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); @@ -201,7 +203,7 @@ void CAEthernetConnectionStateCB(const char *ipAddress, /* 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); @@ -220,11 +222,11 @@ void CAEthernetConnectionStateCB(const char *ipAddress, 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 @@ -263,7 +265,7 @@ void CAEthernetConnectionStateCB(const char *ipAddress, } 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); @@ -294,8 +296,8 @@ void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port, } 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"); @@ -370,7 +372,7 @@ CAResult_t CAStartEthernet() 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); @@ -434,7 +436,7 @@ CAResult_t CAStartEthernetDiscoveryServer() } uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data, - uint32_t dataLength) + uint32_t dataLength) { OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); @@ -517,7 +519,7 @@ CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint3 } // 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!", @@ -623,13 +625,14 @@ void CAEthernetSendDataThread(void *threadData) { 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 @@ -640,7 +643,7 @@ void CAEthernetSendDataThread(void *threadData) } CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, void *data, - uint32_t dataLength) + uint32_t dataLength) { CAEthernetData *ethernetData = (CAEthernetData *) OICMalloc(sizeof(CAEthernetData)); if (!ethernetData) diff --git a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c new file mode 100644 index 0000000..13282d9 --- /dev/null +++ b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter_singlethread.c @@ -0,0 +1,476 @@ +/****************************************************************** + * + * 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 +#include +#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; +} + diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c index 744de99..3f16301 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c @@ -47,7 +47,8 @@ void CAEthernetSetUnicastSocket(const int32_t socketFD) } 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"); diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c index b4b7527..0a83453 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c @@ -79,7 +79,7 @@ static CAEthernetConnectionStateChangeCallback gNetworkChangeCb = NULL; */ 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) { @@ -181,14 +181,15 @@ CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress) 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); @@ -259,7 +260,7 @@ void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress) freeifaddrs(ifp); } -void CANetworkMonitorThread(void* threadData) +void CANetworkMonitorThread(void *threadData) { while (!gStopNetworkMonitor) { diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c index 94afc43..50dcc83 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c @@ -196,7 +196,7 @@ void CAEthernetTerminateServer(void) } 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"); @@ -323,7 +323,7 @@ CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char * } 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"); @@ -555,7 +555,8 @@ CAResult_t CAEthernetStopUnicastServer() 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"); diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapter.c deleted file mode 100644 index 3eac4a2..0000000 --- a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapter.c +++ /dev/null @@ -1,294 +0,0 @@ -/****************************************************************** - * - * 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 -#include -#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; -} diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapterutils.h b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapterutils.h deleted file mode 100644 index 934ff24..0000000 --- a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapterutils.h +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************** -* -* 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 - diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp new file mode 100644 index 0000000..15439e4 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawificlient.cpp @@ -0,0 +1,140 @@ +/****************************************************************** +* +* 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 +#include +#include +#include +#include +#include +#include +#include + +#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; +} + diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp new file mode 100644 index 0000000..6256e83 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifinwmonitor.cpp @@ -0,0 +1,69 @@ +/****************************************************************** +* +* 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 +#include +#include +#include +#include +#include +#include +#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 diff --git a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapterutils.cpp b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp similarity index 58% rename from resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapterutils.cpp rename to resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp index 7025dd1..59906b0 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiadapterutils.cpp +++ b/resource/csdk/connectivity/src/wifi_adapter/arduino/cawifiserver.cpp @@ -18,10 +18,11 @@ * ******************************************************************/ -#include "cawifiadapterutils.h" +#include "cawifiinterface.h" #include #include +#include #include #include #include @@ -32,21 +33,19 @@ #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) @@ -56,19 +55,42 @@ int16_t status = WL_IDLE_STATUS; // the Wifi radio's status #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; @@ -76,7 +98,7 @@ CAResult_t CAArduinoInitUdpSocket(const int16_t *port, int32_t *socketID) 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 { @@ -88,7 +110,8 @@ CAResult_t CAArduinoInitUdpSocket(const int16_t *port, int32_t *socketID) 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"); @@ -122,7 +145,7 @@ CAResult_t CAStartUnicastServer(const char *localAddress, const int16_t *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) @@ -134,39 +157,16 @@ CAResult_t CAStartUnicastServer(const char *localAddress, const int16_t *port) 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) @@ -187,42 +187,39 @@ CAResult_t CAStopUnicastServer() 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 @@ -231,36 +228,28 @@ void CACheckData() { 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"); @@ -293,73 +282,61 @@ int32_t CAArduinoRecvData(int32_t sockFd, uint8_t *buf, uint32_t bufLen, uint8_t *((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; } + + diff --git a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c index 8ca8a84..ebba6be 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c +++ b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c @@ -27,6 +27,9 @@ #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" @@ -41,7 +44,13 @@ * @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 @@ -93,6 +102,13 @@ static bool gStartUnicastServerRequested = false; */ 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. @@ -118,7 +134,8 @@ static void CAWiFiNotifyNetworkChange(const char *address, const int16_t port, 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, @@ -172,14 +189,14 @@ void CAWiFiDeinitializeQueueHandles() 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); @@ -203,11 +220,11 @@ void CAWiFiConnectionStateCB(const char *ipAddress, { 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); @@ -218,6 +235,22 @@ void CAWiFiConnectionStateCB(const char *ipAddress, { 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 @@ -225,12 +258,12 @@ void CAWiFiConnectionStateCB(const char *ipAddress, { 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 @@ -239,38 +272,35 @@ void CAWiFiConnectionStateCB(const char *ipAddress, } } - 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); @@ -283,6 +313,7 @@ void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port, return; } endPoint->addressInfo.IP.port = port; + endPoint->isSecured = isSecured; void *buf = OICMalloc(dataLength + 1); if (NULL == buf) @@ -329,7 +360,12 @@ CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, CATerminateWIfI(); return ret; } + CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB); +#ifdef __WITH_DTLS__ + CAAdapterNetDtlsInit(); + CADTLSSetPacketReceiveCallback(CAWiFiPacketReceivedCB); +#endif CAConnectivityHandler_t wifiHandler; wifiHandler.startAdapter = CAStartWIFI; @@ -366,18 +402,25 @@ CAResult_t 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); @@ -385,16 +428,20 @@ CAResult_t CAStartWIFI() 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() @@ -417,7 +464,7 @@ 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; @@ -504,6 +551,7 @@ CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t 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) { @@ -512,31 +560,62 @@ CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t 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"); @@ -553,24 +632,30 @@ CAResult_t CAReadWIFIData() 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() @@ -584,31 +669,39 @@ 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; } @@ -626,15 +719,39 @@ void CAWiFiSendDataThread(void *threadData) 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 diff --git a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c new file mode 100644 index 0000000..3c4771d --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter_singlethread.c @@ -0,0 +1,480 @@ +/****************************************************************** + * + * 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 +#include +#include +#include + +#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; +} + diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawificlient.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawificlient.c index 707d377..3092c99 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/linux/cawificlient.c +++ b/resource/csdk/connectivity/src/wifi_adapter/linux/cawificlient.c @@ -39,15 +39,16 @@ */ 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"); @@ -60,7 +61,7 @@ uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port, return 0; } - if (0 > gUnicastServerSocketDescClient) + if (0 > sockfd) { OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running !"); return 0; @@ -78,7 +79,7 @@ uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port, 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) { @@ -92,3 +93,46 @@ uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port, 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; +} + + diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c index a0fe577..24d337d 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c +++ b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c @@ -20,14 +20,17 @@ #include "cawifiinterface.h" -#include +#include #include +#include +#include #include - -#include "caadapterutils.h" -#include "umutex.h" +#include +#include #include "logger.h" #include "oic_malloc.h" +#include "umutex.h" +#include "caadapterutils.h" #define WIFI_MONITOR_TAG "WIFI_MONITOR" @@ -79,7 +82,7 @@ static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL; */ 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) { @@ -139,7 +142,7 @@ CAResult_t CAWiFiStartNetworkMonitor(void) 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; } @@ -177,26 +180,20 @@ CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress) { 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; } @@ -210,7 +207,8 @@ bool CAWiFiIsConnected(void) return true; } -void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback) +void CAWiFiSetConnectionStateChangeCallback( + CAWiFiConnectionStateChangeCallback callback) { OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN"); @@ -222,35 +220,47 @@ void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress) 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)); @@ -262,16 +272,12 @@ void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress) 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; @@ -304,4 +310,6 @@ void CANetworkMonitorThread(void* threadData) OICFree(interfaceName); OICFree(ipAddress); } + + OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT"); } diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c index e715759..a62d74f 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c +++ b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c @@ -30,6 +30,9 @@ #include "pdu.h" #include "caadapterutils.h" +#ifdef __WITH_DTLS__ +#include "caadapternetdtls.h" +#endif #include "umutex.h" /** @@ -45,75 +48,72 @@ #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 @@ -128,261 +128,152 @@ static CAWiFiPacketReceivedCallback gPacketReceivedCallback = NULL; 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; } } @@ -395,19 +286,18 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port, 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; @@ -426,22 +316,45 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port, 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; } /** @@ -449,374 +362,392 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port, * 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; } diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c index e2cc90b..3092c99 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c @@ -37,17 +37,18 @@ * @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"); @@ -60,7 +61,7 @@ uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port, return 0; } - if (0 > gUnicastServerSocketDescClient) + if (0 > sockfd) { OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running !"); return 0; @@ -78,7 +79,7 @@ uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port, 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) { @@ -92,3 +93,46 @@ uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port, 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; +} + + diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c index b87d727..f3bd0b0 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c @@ -218,14 +218,16 @@ bool CAWiFiIsConnected(void) 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"); @@ -315,7 +317,7 @@ void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress) 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); @@ -326,7 +328,8 @@ void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress) 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); diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c index 8d2ebe0..c7afc02 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c @@ -45,75 +45,78 @@ #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 @@ -139,250 +142,281 @@ static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0}; */ 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; } } @@ -395,11 +429,10 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port, 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) @@ -407,7 +440,7 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port, 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; @@ -426,397 +459,461 @@ CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port, 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; } diff --git a/resource/csdk/connectivity/unittests/tizen/tct/liboic/bt/utc-bt-liboic.c b/resource/csdk/connectivity/unittests/tizen/tct/liboic/bt/utc-bt-liboic.c index d38dacb..de9b661 100644 --- a/resource/csdk/connectivity/unittests/tizen/tct/liboic/bt/utc-bt-liboic.c +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/bt/utc-bt-liboic.c @@ -8,49 +8,54 @@ //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"); } @@ -58,7 +63,8 @@ void interfaceRegisterCallback(CAConnectivityHandler_t handler, 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"); @@ -71,10 +77,11 @@ void interfaceRegisterCallback(CAConnectivityHandler_t handler, 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; } @@ -82,7 +89,7 @@ void requestResponseHandler(CARemoteEndpoint_t* object, void* data) 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) @@ -95,10 +102,12 @@ void requestResponseHandler(CARemoteEndpoint_t* object, void* data) } -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; } @@ -127,9 +136,10 @@ void utc_liboic_cleanup(void) 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; } @@ -146,12 +156,12 @@ int bt_tc_003_getBTInterfaceInformation_p(void) 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); @@ -161,7 +171,7 @@ int bt_tc_003_getBTInterfaceInformation_p(void) 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; } @@ -169,11 +179,11 @@ int bt_tc_004_getBTInterfaceInformation_n(void) 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; } @@ -185,13 +195,13 @@ int bt_tc_006_sendBTUnicastData_p(void) //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); @@ -208,7 +218,7 @@ int bt_tc_007_sendBTUnicastData_n(void) { int dataSize = 0; int ret = -1; - CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); ret = CASendEDRUnicastData(NULL, NULL, NULL); CATerminateEDR(); assert_eq(ret, 0); @@ -219,10 +229,10 @@ int bt_tc_008_sendBTMulticastDataToAll_p(void) { 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; } @@ -231,9 +241,9 @@ int bt_tc_009_sendBTMulticastDataToAll_n(void) { 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; } diff --git a/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.c b/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.c index 0075867..387691a 100644 --- a/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.c +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.c @@ -2,18 +2,21 @@ #include #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 \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(); diff --git a/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.h b/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.h index b2dfe18..e7da73b 100644 --- a/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.h +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.h @@ -18,7 +18,8 @@ extern int wifi_tc_009_startWifiServers_p(void); 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}, diff --git a/resource/csdk/connectivity/unittests/tizen/tct/liboic/wifi/utc-wifi-liboic.c b/resource/csdk/connectivity/unittests/tizen/tct/liboic/wifi/utc-wifi-liboic.c index 352bb7a..5c6791a 100644 --- a/resource/csdk/connectivity/unittests/tizen/tct/liboic/wifi/utc-wifi-liboic.c +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/wifi/utc-wifi-liboic.c @@ -10,10 +10,11 @@ //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; @@ -21,15 +22,17 @@ 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 /** @@ -39,40 +42,42 @@ char coapData[500] = "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"s #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"); } @@ -81,16 +86,16 @@ void interfaceRegisterCallback(CAConnectivityHandler handler , CAConnectivityTyp { 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"); } */ @@ -101,13 +106,14 @@ void interfaceRegisterCallback(CAConnectivityHandler handler, 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); @@ -116,10 +122,11 @@ void interfaceRegisterCallback(CAConnectivityHandler handler, } -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; } @@ -127,7 +134,7 @@ void requestResponseHandler(CARemoteEndpoint* object, void* data) 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) @@ -140,10 +147,12 @@ void requestResponseHandler(CARemoteEndpoint* object, void* data) } -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; } @@ -172,7 +181,8 @@ void utc_liboic_cleanup(void) 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; } @@ -213,14 +223,14 @@ int wifi_tc_005_sendWifiUnicastData_p(void) { 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); @@ -301,7 +311,7 @@ int wifi_tc_011_startUnicastServer_n(void) 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 @@ -318,7 +328,7 @@ int wifi_tc_012_startUnicastServer_n(void) 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 -- 2.7.4