From 59caeebc53d0ac206b0a77ed8329849a9f8d3ff7 Mon Sep 17 00:00:00 2001 From: "ashok.channa" Date: Tue, 25 Nov 2014 13:37:18 -0800 Subject: [PATCH] Implementation of connectivity abstraction feature release v0.2 Connectivity Abstraction feature provides unified approach for multiple Transports Please check Release v0.2 document for additional information We followed Coding guidelines as per current base source Non Supported code is just made to print the message. Change-Id: I2b34772b3189c0a5740e74589d9f790c0dc383a7 Signed-off-by: ashok.channa --- resource/csdk/connectivity/RELEASE v0.2 | 91 ++ resource/csdk/connectivity/api/cacommon.h | 120 +- resource/csdk/connectivity/api/cainterface.h | 8 +- resource/csdk/connectivity/build/Makefile | 56 + resource/csdk/connectivity/build/common.mk | 59 + resource/csdk/connectivity/build/linux/Makefile | 13 +- resource/csdk/connectivity/build/tizen/Makefile | 54 + .../connectivity/build/tizen/com.samsung.oicca.pc | 9 + resource/csdk/connectivity/build/tizen/gbsbuild.sh | 94 ++ .../build/tizen/packaging/com.samsung.oicca.spec | 66 + resource/csdk/connectivity/common/inc/logger.h | 29 +- resource/csdk/connectivity/common/inc/oic_string.h | 45 + .../csdk/connectivity/common/inc/uthreadpool.h | 1 - resource/csdk/connectivity/common/src/logger.c | 7 +- resource/csdk/connectivity/common/src/oic_string.c | 32 + resource/csdk/connectivity/common/src/uqueue.c | 2 +- .../csdk/connectivity/common/src/uthreadpool.c | 14 +- .../connectivity/{ => doc/release}/RELEASE v0.1 | 0 .../csdk/connectivity/inc/caadapterinterface.h | 52 +- resource/csdk/connectivity/inc/caadapterutils.h | 101 ++ resource/csdk/connectivity/inc/caedradapter.h | 15 +- resource/csdk/connectivity/inc/caerrorcode.h | 65 - resource/csdk/connectivity/inc/caethernetadapter.h | 41 +- resource/csdk/connectivity/inc/caethernetcore.h | 68 + .../csdk/connectivity/inc/cainterfacecontroller.h | 7 +- resource/csdk/connectivity/inc/caleadapter.h | 34 +- resource/csdk/connectivity/inc/camessagehandler.h | 17 +- resource/csdk/connectivity/inc/camessagequeue.h | 94 ++ .../csdk/connectivity/inc/canetworkconfigurator.h | 3 + resource/csdk/connectivity/inc/caprotocolmessage.h | 38 +- resource/csdk/connectivity/inc/caqueueingthread.h | 66 + resource/csdk/connectivity/inc/cawifiadapter.h | 31 +- resource/csdk/connectivity/inc/cawificore.h | 31 +- .../csdk/connectivity/inc/cawifiethernetadapter.h | 137 -- .../csdk/connectivity/lib/libcoap-4.1.1/address.h | 11 +- .../csdk/connectivity/lib/libcoap-4.1.1/async.h | 36 +- .../csdk/connectivity/lib/libcoap-4.1.1/bits.h | 20 +- .../csdk/connectivity/lib/libcoap-4.1.1/block.c | 2 +- .../csdk/connectivity/lib/libcoap-4.1.1/block.h | 14 +- .../csdk/connectivity/lib/libcoap-4.1.1/coap.h | 1 + .../connectivity/lib/libcoap-4.1.1/coap_list.c | 2 +- .../connectivity/lib/libcoap-4.1.1/coap_list.h | 2 +- .../connectivity/lib/libcoap-4.1.1/coap_time.h | 6 +- .../csdk/connectivity/lib/libcoap-4.1.1/configure | 1 + .../connectivity/lib/libcoap-4.1.1/configure.in | 1 + .../csdk/connectivity/lib/libcoap-4.1.1/debug.c | 10 +- .../csdk/connectivity/lib/libcoap-4.1.1/debug.h | 6 +- .../csdk/connectivity/lib/libcoap-4.1.1/encode.c | 2 +- .../csdk/connectivity/lib/libcoap-4.1.1/encode.h | 2 +- .../lib/libcoap-4.1.1/examples/Makefile | 1 + .../lib/libcoap-4.1.1/examples/Makefile.in | 1 + .../lib/libcoap-4.1.1/examples/client.c | 12 +- .../lib/libcoap-4.1.1/examples/etsi_iot_01.c | 4 +- .../connectivity/lib/libcoap-4.1.1/examples/rd.c | 2 +- .../lib/libcoap-4.1.1/examples/server.c | 4 +- .../connectivity/lib/libcoap-4.1.1/examples/tiny.c | 2 +- .../csdk/connectivity/lib/libcoap-4.1.1/hashkey.c | 2 +- .../csdk/connectivity/lib/libcoap-4.1.1/hashkey.h | 22 +- resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h | 2 +- resource/csdk/connectivity/lib/libcoap-4.1.1/net.c | 29 +- resource/csdk/connectivity/lib/libcoap-4.1.1/net.h | 76 +- .../csdk/connectivity/lib/libcoap-4.1.1/option.c | 16 +- .../csdk/connectivity/lib/libcoap-4.1.1/option.h | 70 +- resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c | 9 +- resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h | 36 +- .../csdk/connectivity/lib/libcoap-4.1.1/prng.h | 14 +- .../csdk/connectivity/lib/libcoap-4.1.1/resource.c | 44 +- .../csdk/connectivity/lib/libcoap-4.1.1/resource.h | 64 +- resource/csdk/connectivity/lib/libcoap-4.1.1/str.c | 2 +- resource/csdk/connectivity/lib/libcoap-4.1.1/str.h | 2 +- .../connectivity/lib/libcoap-4.1.1/subscribe.c | 2 +- .../connectivity/lib/libcoap-4.1.1/subscribe.h | 4 +- .../csdk/connectivity/lib/libcoap-4.1.1/t_list.h | 10 +- .../connectivity/lib/libcoap-4.1.1/tests/Makefile | 1 + .../lib/libcoap-4.1.1/tests/Makefile.in | 1 + .../lib/libcoap-4.1.1/tests/test_error_response.c | 8 +- .../lib/libcoap-4.1.1/tests/test_error_response.h | 2 +- .../lib/libcoap-4.1.1/tests/test_options.c | 28 +- .../lib/libcoap-4.1.1/tests/test_options.h | 2 +- .../lib/libcoap-4.1.1/tests/test_pdu.c | 18 +- .../lib/libcoap-4.1.1/tests/test_pdu.h | 2 +- .../lib/libcoap-4.1.1/tests/test_sendqueue.c | 12 +- .../lib/libcoap-4.1.1/tests/test_sendqueue.h | 2 +- .../lib/libcoap-4.1.1/tests/test_uri.c | 10 +- .../lib/libcoap-4.1.1/tests/test_uri.h | 2 +- .../lib/libcoap-4.1.1/tests/test_wellknown.c | 12 +- .../lib/libcoap-4.1.1/tests/test_wellknown.h | 2 +- resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c | 38 +- resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h | 52 +- .../csdk/connectivity/lib/libcoap-4.1.1/uthash.h | 68 +- .../csdk/connectivity/lib/libcoap-4.1.1/utlist.h | 16 +- resource/csdk/connectivity/samples/linux/sample.sh | 3 +- .../csdk/connectivity/samples/linux/sample_main.c | 162 +- .../connectivity/samples/linux/threadpool/Makefile | 4 +- .../connectivity/samples/linux/threadpool/main.c | 25 +- resource/csdk/connectivity/samples/tizen/Makefile | 52 + .../csdk/connectivity/samples/tizen/README.txt | 31 + .../csdk/connectivity/samples/tizen/casample.c | 547 +++++++ .../tizen/com.samsung.interfacesample.manifest | 25 + .../samples/tizen/com.samsung.interfacesample.rule | 39 + .../samples/tizen/com.samsung.interfacesample.xml | 16 + .../connectivity/samples/tizen/interfacesample.c | 1287 +++++++++++++++ .../packaging/com.samsung.interfacesample.spec | 65 + .../connectivity/src/adapter_util/caadapterutils.c | 202 +++ .../connectivity/src/adapter_util/camessagequeue.c | 195 +++ .../src/bt_edr_adapter/linux/caedradapter.c | 7 +- .../src/bt_edr_adapter/tizen/cabtclient.c | 63 + .../src/bt_edr_adapter/tizen/cabtclient.h | 58 + .../src/bt_edr_adapter/tizen/cabtdevicelist.c | 400 +++++ .../src/bt_edr_adapter/tizen/cabtdevicelist.h | 99 ++ .../src/bt_edr_adapter/tizen/cabtendpoint.c | 57 + .../src/bt_edr_adapter/tizen/cabtendpoint.h | 61 + .../src/bt_edr_adapter/tizen/cabtmanager.c | 1193 ++++++++++++++ .../src/bt_edr_adapter/tizen/cabtmanager.h | 198 +++ .../src/bt_edr_adapter/tizen/cabtserver.c | 103 ++ .../src/bt_edr_adapter/tizen/cabtserver.h | 71 + .../src/bt_edr_adapter/tizen/cabtutils.c | 56 + .../src/bt_edr_adapter/tizen/cabtutils.h | 66 + .../src/bt_edr_adapter/tizen/caedradapter.c | 283 ++++ .../connectivity/src/bt_le_adapter/caleadapter.c | 312 ++-- .../src/bt_le_adapter/linux/README.txt | 0 .../src/bt_le_adapter/linux/caleadapter.c | 7 +- .../src/bt_le_adapter/tizen/cableclient.c | 1703 ++++++++++++++++++++ .../src/bt_le_adapter/tizen/cableclient.h | 448 +++++ .../src/bt_le_adapter/tizen/cableclientutil.c | 435 +++++ .../src/bt_le_adapter/tizen/cableclientutil.h | 266 +++ .../src/bt_le_adapter/tizen/cableserver.c | 899 +++++++++++ .../src/bt_le_adapter/tizen/cableserver.h | 306 ++++ .../csdk/connectivity/src/caconnectivitymanager.c | 51 +- .../csdk/connectivity/src/cainterfacecontroller.c | 122 +- resource/csdk/connectivity/src/camessagehandler.c | 495 +++--- .../csdk/connectivity/src/canetworkconfigurator.c | 12 +- resource/csdk/connectivity/src/caprotocolmessage.c | 232 ++- resource/csdk/connectivity/src/caqueueingthread.c | 223 +++ resource/csdk/connectivity/src/caremotehandler.c | 3 +- .../src/ethernet_adapter/linux/caethernetadapter.c | 118 +- .../src/ethernet_adapter/linux/caethernetcore.c | 622 +++++++ .../src/wifi_adapter/cawifiethernetadapter.c | 371 ----- .../src/wifi_adapter/linux/cawifiadapter.c | 53 +- .../src/wifi_adapter/linux/cawificore.c | 1117 +++++++------ .../src/wifi_adapter/tizen/caethernetadapter.c | 120 ++ .../src/wifi_adapter/tizen/cawifiadapter.c | 494 ++++++ .../src/wifi_adapter/tizen/cawificlient.c | 207 +++ .../src/wifi_adapter/tizen/cawificlient.h | 75 + .../src/wifi_adapter/tizen/cawifimonitor.c | 231 +++ .../src/wifi_adapter/tizen/cawifimonitor.h | 95 ++ .../src/wifi_adapter/tizen/cawifiserver.c | 717 ++++++++ .../src/wifi_adapter/tizen/cawifiserver.h | 104 ++ .../unittests/linux/sample1_unittest.cc | 142 +- .../connectivity/unittests/tizen/tct/README.txt | 9 + .../unittests/tizen/tct/liboic/CMakeLists.txt | 31 + .../unittests/tizen/tct/liboic/bt/utc-bt-liboic.c | 269 ++++ .../unittests/tizen/tct/liboic/tct-liboic-core.c | 31 + .../unittests/tizen/tct/liboic/tct-liboic-core.h | 36 + .../unittests/tizen/tct/liboic/utc-liboic.c | 32 + .../tizen/tct/liboic/wifi/utc-wifi-liboic.c | 411 +++++ .../tizen/tct/packaging/core-liboic-tests.spec | 57 + 157 files changed, 16181 insertions(+), 2365 deletions(-) create mode 100644 resource/csdk/connectivity/RELEASE v0.2 create mode 100644 resource/csdk/connectivity/build/Makefile create mode 100644 resource/csdk/connectivity/build/common.mk create mode 100644 resource/csdk/connectivity/build/tizen/Makefile create mode 100644 resource/csdk/connectivity/build/tizen/com.samsung.oicca.pc create mode 100644 resource/csdk/connectivity/build/tizen/gbsbuild.sh create mode 100644 resource/csdk/connectivity/build/tizen/packaging/com.samsung.oicca.spec create mode 100644 resource/csdk/connectivity/common/inc/oic_string.h create mode 100644 resource/csdk/connectivity/common/src/oic_string.c rename resource/csdk/connectivity/{ => doc/release}/RELEASE v0.1 (100%) create mode 100644 resource/csdk/connectivity/inc/caadapterutils.h delete mode 100644 resource/csdk/connectivity/inc/caerrorcode.h create mode 100644 resource/csdk/connectivity/inc/caethernetcore.h create mode 100644 resource/csdk/connectivity/inc/camessagequeue.h create mode 100644 resource/csdk/connectivity/inc/caqueueingthread.h delete mode 100644 resource/csdk/connectivity/inc/cawifiethernetadapter.h create mode 100644 resource/csdk/connectivity/samples/tizen/Makefile create mode 100644 resource/csdk/connectivity/samples/tizen/README.txt create mode 100644 resource/csdk/connectivity/samples/tizen/casample.c create mode 100644 resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.manifest create mode 100644 resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.rule create mode 100644 resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.xml create mode 100644 resource/csdk/connectivity/samples/tizen/interfacesample.c create mode 100644 resource/csdk/connectivity/samples/tizen/packaging/com.samsung.interfacesample.spec create mode 100644 resource/csdk/connectivity/src/adapter_util/caadapterutils.c create mode 100644 resource/csdk/connectivity/src/adapter_util/camessagequeue.c create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.c create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h create mode 100644 resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/linux/README.txt create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.c create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c create mode 100644 resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h create mode 100644 resource/csdk/connectivity/src/caqueueingthread.c create mode 100644 resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetcore.c delete mode 100644 resource/csdk/connectivity/src/wifi_adapter/cawifiethernetadapter.c create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/caethernetadapter.c create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiadapter.c create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.h create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.c create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.h create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c create mode 100644 resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.h create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/README.txt create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/liboic/CMakeLists.txt create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/liboic/bt/utc-bt-liboic.c create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.c create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.h create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/liboic/utc-liboic.c create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/liboic/wifi/utc-wifi-liboic.c create mode 100644 resource/csdk/connectivity/unittests/tizen/tct/packaging/core-liboic-tests.spec diff --git a/resource/csdk/connectivity/RELEASE v0.2 b/resource/csdk/connectivity/RELEASE v0.2 new file mode 100644 index 0000000..81ab892 --- /dev/null +++ b/resource/csdk/connectivity/RELEASE v0.2 @@ -0,0 +1,91 @@ +Project Name: IoTivity +Release Version No: CA_v0.2 +API Version: CA_v0.4 + +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 +2) Tizen 2.3 + Connectivity : WIFI, EDR, BLE(1:1). + +Preconditions: +1)gcc 4.6.3 and above. +2)glib library (sudo apt-get install libglib2.0-dev) +3)libcoap.a library ( do make @lib/libcoap-4.1.1) + + +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 Connectivity abstraction. +5. Executed Open Source Verification and Prevent analysis. + +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() + +Non Supported APIs +CAGetNetworkInfo() + +Type of Release: Source + + +Known and Open Issues: +1) OIC Log, OIC Malloc will be removed once name changes applied to OIC Bases code +3) Termination sequence is not working.Its blocked. + +Nature of Release: Partial + +How to Build: +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) diff --git a/resource/csdk/connectivity/api/cacommon.h b/resource/csdk/connectivity/api/cacommon.h index 7e4cda1..fd683b8 100644 --- a/resource/csdk/connectivity/api/cacommon.h +++ b/resource/csdk/connectivity/api/cacommon.h @@ -22,6 +22,7 @@ * @file cacommon.h * @brief This file contains the common data structures between Resource , CA and adapters */ + #ifndef __CA_COMMON_H_ #define __CA_COMMON_H_ @@ -34,57 +35,84 @@ extern "C" #endif /** - @brief IP Address Length + @brief IP address Length */ #define CA_IPADDR_SIZE 16 /** - @brief Mac Address Length for BT + @brief Mac address length for BT port */ #define CA_MACADDR_SIZE 18 /** - @brief Max Header Options data length + @brief Max header options data length */ #define CA_MAX_HEADER_OPTION_DATA_LENGTH 16 /** - @brief CAPayload_t + @brief Max URI length + */ +#define CA_MAX_URI_LENGTH 128 + +/** +@brief option types - the highest option number 63 +*/ +#define CA_OPTION_IF_MATCH 1 +#define CA_OPTION_ETAG 4 +#define CA_OPTION_IF_NONE_MATCH 5 +#define CA_OPTION_LOCATION_PATH 8 +#define CA_OPTION_URI_PATH 11 +#define CA_OPTION_CONTENT_FORMAT 12 +#define CA_OPTION_CONTENT_TYPE COAP_OPTION_CONTENT_FORMAT +#define CA_OPTION_MAXAGE 14 +#define CA_OPTION_URI_QUERY 15 +#define CA_OPTION_ACCEPT 17 +#define CA_OPTION_LOCATION_QUERY 20 +#define CA_OPTION_OBSERVE 6 + +/** + @brief Payload information from resource model */ typedef char* CAPayload_t; /** - @brief CAURI_t + @brief URI for the OIC base.CA considers relative URI as the URI. */ typedef char* CAURI_t; /** - @brief CAToken_t + @brief Token information for mapping the request and responses by resource model */ typedef char* CAToken_t; /** - @brief CABool_t + @brief Boolean value used for specifying the success or failure */ + typedef enum { - CA_FALSE = 0, CA_TRUE + CA_FALSE = 0, + CA_TRUE } CABool_t; /** - @brief CAConnectivityType_t + @brief Different connectivities that are handled in Connectivity Abstraction */ typedef enum { - CA_ETHERNET = (1 << 0), CA_WIFI = (1 << 1), CA_EDR = (1 << 2), CA_LE = (1 << 3) + CA_ETHERNET = (1 << 0), + CA_WIFI = (1 << 1), + CA_EDR = (1 << 2), + CA_LE = (1 << 3) } CAConnectivityType_t; /** - @brief CANetworkStatus_t + @brief Information about the network status.CA_INTERFACE_UP means connectivity is available */ typedef enum { - CA_INTERFACE_UP, CA_INTERFACE_DOWN + CA_INTERFACE_UP, + CA_INTERFACE_DOWN } CANetworkStatus_t; /** @@ -93,15 +121,25 @@ typedef enum typedef union { /** - @brief BT Information + @brief BT Mac Information */ struct { - /** @brief Bluettoth Mac Address **/ + /** @brief BT mac address **/ char btMacAddress[CA_MACADDR_SIZE]; } BT; + + /** + @brief LE MAC Information + */ + struct + { + /** @brief BLE mac address **/ + char leMacAddress[CA_MACADDR_SIZE]; + } LE; + /** - @brief IP Information + @brief IP Information for wifi and ethernet ports */ struct { @@ -113,23 +151,29 @@ typedef union } CAAddress_t; /** - @brief CAQualityOfService + @brief Quality of service for Base source code */ typedef enum { - CA_LOW_QOS = 0, CA_MEDIUM_QOS, CA_HIGH_QOS, CA_NA_QOS // No Quality is defined, let the stack decide + CA_LOW_QOS = 0, + CA_MEDIUM_QOS, + CA_HIGH_QOS, + CA_NA_QOS // No Quality is defined, let the stack decide } CAQualityOfService_t; /** - @brief CAMethod_t + @brief Allowed method to be used by resource model */ typedef enum { - CA_GET = 1, CA_POST, CA_PUT, CA_DELETE + CA_GET = 1, + CA_POST, + CA_PUT, + CA_DELETE } CAMethod_t; /** - @brief RemoteEndpoint information for connectivities + @brief Remote endpoint information for connectivities */ typedef struct { @@ -150,7 +194,7 @@ typedef struct CAAddress_t addressInfo; /** Connectivity type that localconnectivity avaialble **/ CAConnectivityType_t type; -} CALocalConnectivityt_t; +} CALocalConnectivity_t; /** @brief Enums for CA return values @@ -160,7 +204,11 @@ typedef enum /* Success status code - START HERE */ CA_STATUS_OK = 0, CA_STATUS_INVALID_PARAM, + CA_ADAPTER_NOT_ENABLED, + CA_SERVER_STARTED_ALREADY, + CA_SERVER_NOT_STARTED, CA_DESTINATION_NOT_REACHABLE, + CA_SOCKET_OPERATION_FAILED, CA_SEND_FAILED, CA_RECEVIE_FAILED, CA_MEMORY_ALLOC_FAILED, @@ -168,7 +216,7 @@ typedef enum CA_DESTINATION_DISCONNECTED, CA_STATUS_FAILED, CA_NOT_SUPPORTED -/* Error status code - END HERE */ +/* Result code - END HERE */ } CAResult_t; /** @@ -184,15 +232,16 @@ typedef enum CA_BAD_REQ = 400, CA_BAD_OPT = 402, CA_NOT_FOUND = 404 -/* Error status code - END HERE */ +/* Response status code - END HERE */ } CAResponseResult_t; /** - @brief Transport Protocol IDs + @brief Transport Protocol IDs for additional options */ typedef enum { - CA_INVALID_ID = (1 << 0), CA_COAP_ID = (1 << 1) + CA_INVALID_ID = (1 << 0), + CA_COAP_ID = (1 << 1) } CATransportProtocolID_t; /** @@ -206,19 +255,13 @@ typedef struct CATransportProtocolID_t protocolID; /** The header option ID which will be added to communication packets**/ uint16_t optionID; - /** its length 191**/ + /** its length **/ uint16_t optionLength; /** optional data values**/ uint8_t optionData[CA_MAX_HEADER_OPTION_DATA_LENGTH]; } CAHeaderOption_t; /** - * @brief Request Information to be sent - * - * This structure is used to hold request information - */ - -/** * @brief Base Information received * * This structure is used to hold request & response base information @@ -237,24 +280,29 @@ typedef struct CAPayload_t payload; } CAInfo_t; +/** + * @brief Request Information to be sent + * + * This structure is used to hold request information + */ typedef struct { /** Name of the Method Allowed **/ CAMethod_t method; - /** Base Information **/ + /** Information of the request. **/ CAInfo_t info; } CARequestInfo_t; /** - * @brief Response Information received + * @brief Response information received * * This structure is used to hold response information */ typedef struct { - /**Response Result by Resource Model**/ + /**Result for response by resource model**/ CAResponseResult_t result; - /**Base Information **/ + /**Information of the response.**/ CAInfo_t info; } CAResponseInfo_t; diff --git a/resource/csdk/connectivity/api/cainterface.h b/resource/csdk/connectivity/api/cainterface.h index 8619f92..a88e10f 100644 --- a/resource/csdk/connectivity/api/cainterface.h +++ b/resource/csdk/connectivity/api/cainterface.h @@ -43,7 +43,8 @@ extern "C" * address based on the connectivity type. * @param requestInfo [OUT] Identifier which needs to be sent with request. */ -typedef void (*CARequestCallback)(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo); +typedef void (*CARequestCallback)(const CARemoteEndpoint_t* object, + const CARequestInfo_t* requestInfo); /** * @brief Callback function type for response delivery. @@ -51,7 +52,8 @@ typedef void (*CARequestCallback)(CARemoteEndpoint_t* object, CARequestInfo_t* r * @param object [OUT] Endpoint object from which the response is received. * @param responseInfo [OUT] Identifier which needs to be mapped with response. */ -typedef void (*CAResponseCallback)(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo); +typedef void (*CAResponseCallback)(const CARemoteEndpoint_t* object, + const CAResponseInfo_t* responseInfo); /** * @brief Initialize the connectivity abstraction module. @@ -192,7 +194,7 @@ CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork); * @param size [OUT] No Of Array objects * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -CAResult_t CAGetNetworkInformation(CALocalConnectivityt_t **info, uint32_t* size); +CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t* size); /** * @brief for usage of singled threaded application. diff --git a/resource/csdk/connectivity/build/Makefile b/resource/csdk/connectivity/build/Makefile new file mode 100644 index 0000000..da6eb11 --- /dev/null +++ b/resource/csdk/connectivity/build/Makefile @@ -0,0 +1,56 @@ +#/****************************************************************** +# * +# * 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. +# * +#******************************************************************/ + +## +# override with `make BUILD=debug` +# override with `make PLATFORM=arduinomega` or `make PLATFORM=arduinodue` +# default to release build +# default to build for linux +BUILD := debug +PLATFORM := linux +TRANSPORT := ALL +OBJ_DIR := ./bin +VERSION_MAJOR := 0 +VERSION_MINOR := 1 +VERSION_PATCH := 0 + +ifeq ($(PLATFORM),tizen) +$(info *******************tizen Build !!******************) +all: + sudo sh tizen/gbsbuild.sh $(TRANSPORT) + +else ifeq ($(PLATFORM),arduinomega) +$(info *********ArduinoMega Build!!**********) +all: + sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) + sudo sh arduino/build.sh make $(PLATFORM) $(TRANSPORT) + +clean: + sudo sh arduino/build.sh clean $(PLATFORM) $(TRANSPORT) + +install: + sudo sh arduino/build.sh install $(PLATFORM) $(TRANSPORT) + +else + $(info *********error**********) + $(error Wrong value for PLATFORM !!) +endif + + diff --git a/resource/csdk/connectivity/build/common.mk b/resource/csdk/connectivity/build/common.mk new file mode 100644 index 0000000..187d2e1 --- /dev/null +++ b/resource/csdk/connectivity/build/common.mk @@ -0,0 +1,59 @@ +#/****************************************************************** +# * +# * 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. +# * +#******************************************************************/ + +## +## Definitions +## +SHELL = /bin/bash +PROJECT_NAME = connectivity_abstraction +PROJECT_ROOT_PATH = .. +PROJECT_API_PATH = $(PROJECT_ROOT_PATH)/api +PROJECT_INC_PATH = $(PROJECT_ROOT_PATH)/inc +PROJECT_SRC_PATH = $(PROJECT_ROOT_PATH)/src +PROJECT_COMMON_INC_PATH = $(PROJECT_ROOT_PATH)/common/inc +PROJECT_COMMON_SRC_PATH = $(PROJECT_ROOT_PATH)/common/src +PROJECT_COMMON_PATH = $(PROJECT_ROOT_PATH)/common +PROJECT_OUT_PATH = $(PROJECT_ROOT_PATH)/build/out +PROJECT_LIB_PATH = $(PROJECT_ROOT_PATH)/lib + +## +## macro +## +define MAKE_PROJECT_OUT_PATH + @if [ ! -d $(PROJECT_OUT_PATH) ]; then \ + mkdir $(PROJECT_OUT_PATH); \ + fi +endef + + +## +## Commands +## +CC = gcc +CXX = g++ +RM = rm -rf +CP = cp +MV = mv +AR = ar +LD = ld +LN = ln +CD = cd +RANLIB = ranlib + diff --git a/resource/csdk/connectivity/build/linux/Makefile b/resource/csdk/connectivity/build/linux/Makefile index 7fb550a..bdc96c3 100644 --- a/resource/csdk/connectivity/build/linux/Makefile +++ b/resource/csdk/connectivity/build/linux/Makefile @@ -21,7 +21,7 @@ # override with `make BUILD=debug` # default to release build # default to build for linux -BUILD = release +BUILD = debug PLATFORM = linux TRANSPORT = ALL OBJ_DIR = ./$(BUILD) @@ -38,7 +38,7 @@ include $(COMMON_MAKE) EDR = NO_EDR_ADAPTER WIFI = WIFI_ADAPTER LE = NO_LE_ADAPTER -ETHERNET = NO_ETHERNET_ADAPTER +ETHERNET = ETHERNET_ADAPTER #Add Pre processor definitions DEFINE_FLAG = -D$(EDR) -D$(LE) -D$(WIFI) -D$(ETHERNET) @@ -84,7 +84,8 @@ logger.c oic_malloc.c oic_logger.c oic_console_logger.c \ caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c \ canetworkconfigurator.c caedradapter.c caleadapter.c \ caethernetadapter.c cawifiadapter.c \ -caprotocolmessage.c cawificore.c \ +caprotocolmessage.c cawificore.c caethernetcore.c\ +caqueueingthread.c \ uqueue.c uarraylist.c umutex.c uthreadpool.c \ COMPONENT_OBJS = $(COMPONENT_SRCS:%.c=$(OBJ_DIR)/%.o) @@ -105,7 +106,7 @@ IFLAGS = -I$(PROJECT_COMMON_INC_PATH) \ -I$(BLE_ADAPTER_PATH) \ -I$(libcoap_build_dir) -DFLAGS = -DLINUX \ +DFLAGS = -D__LINUX__ \ -DWITH_POSIX \ $(BUILD_FLAG)\ ## @@ -129,12 +130,14 @@ all : $(TARGET) @echo "======================" $(TARGET) : $(COMPONENT_OBJS) + cd $(libcoap_build_dir); $(MAKE) @$(MAKE_PROJECT_OUT_PATH) @$(CC) -shared -Wl,-soname,$(TARGET) -o $@ $(COMPONENT_OBJS) $(LFLAGS) $(LDFLAGS) $(LDLIBS) @$(MV) $(TARGET) $(PROJECT_OUT_PATH)/. @$(CD) $(PROJECT_OUT_PATH); $(MAKE_TARGET_ALIAS) - + clean : + cd $(libcoap_build_dir) && make clean @$(RM) $(DEBUG_DIR) $(RELEASE_DIR)\ $(PROJECT_OUT_PATH) diff --git a/resource/csdk/connectivity/build/tizen/Makefile b/resource/csdk/connectivity/build/tizen/Makefile new file mode 100644 index 0000000..b7c2f04 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/Makefile @@ -0,0 +1,54 @@ +## +# override with `make BUILD=debug` +# override with `make PLATFORM=arduinomega` or `make PLATFORM=arduinodue` +# default to release build +# default to build for linux +BUILD := debug +PLATFORM := tizen +OBJ_DIR := ./bin +VERSION_MAJOR := 0 +VERSION_MINOR := 1 +VERSION_PATCH := 0 +ADAPTER_MACRO := -DWIFI_ADAPTER + +$(info *******************tizen Build !!******************) + +CC=gcc +LIBCOAP=./lib/libcoap-4.1.1/ +LIBCOAP_OBJ_DIR=./lib/libcoap-4.1.1/obj + +# TODO : Currently Hardcoded WIFI_ADAPTER. Change it to generic +CFLAGS.debug = -DWITH_POSIX -D__TIZEN__ -Wall -DSLP_SDK_LOG -g -D_GNU_SOURCE -DTIZEN_DEBUG_ENABLE -DTB_LOG $(ADAPTER_MACRO) +CFLAGS.release = -DWITH_POSIX -D__TIZEN__ -Wall -DSLP_SDK_LOG -D_GNU_SOURCE -DTIZEN_DEBUG_ENABLE -DTB_LOG $(ADAPTER_MACRO) +COMPILEFLAG = `pkg-config --cflags --libs capi-network-wifi dlog capi-network-bluetooth glib-2.0` + +# Include files will be copied into a single folder on gbsbuild. +# NO NEED to mention the path explicitly. + +SRC = $(wildcard *.c) +OBJECTS = $(patsubst %.c, %.o, $(SRC)) + +#Currently compiling libcoap objects. If it's provided by external party. +#Then don't compile, Instead directly extract objects and create liboicinterface.a +all: $(OBJECTS) + $(MAKE) -C $(LIBCOAP) clean + $(MAKE) -C $(LIBCOAP) + -mkdir $(LIBCOAP_OBJ_DIR) + @cd $(LIBCOAP_OBJ_DIR) && $(AR) -x ../libcoap.a + ar rcs liboicinterface.a $(OBJECTS) $(LIBCOAP_OBJ_DIR)/*.o + +%.o : %.c + $(CC) -c $(CFLAGS.$(BUILD)) $(COMPILEFLAG) $< -o $@ + + +pack: +#$(CC) $(CFLAGS) $(COMPILEFLAG) WiFiInterface.c bt_interface.c tc_interface.c sample_main.c -o sample /usr/lib/liboctbstack.a -lm -pthread + $(info **************************************TEST***************************) +install: +#cp -rf sample ./usr/apps/com.samsung.oicca/bin/sample + +clean: + rm -rf *.o sample + rm -f *.o *.d *.elf *.eep core.a *.hex *.bin *.map *- + rm -rf $(OBJ_DIR) + rm -rf $(LIBCOAP_OBJ_DIR) diff --git a/resource/csdk/connectivity/build/tizen/com.samsung.oicca.pc b/resource/csdk/connectivity/build/tizen/com.samsung.oicca.pc new file mode 100644 index 0000000..2ebff57 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/com.samsung.oicca.pc @@ -0,0 +1,9 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include/interfaceHeaders + +Name: com.samsung.oicca +Description: Oic core library +Version: 1.0 +Cflags: -I${includedir} \ No newline at end of file diff --git a/resource/csdk/connectivity/build/tizen/gbsbuild.sh b/resource/csdk/connectivity/build/tizen/gbsbuild.sh new file mode 100644 index 0000000..bc77706 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/gbsbuild.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +spec=`ls tizen/packaging/*.spec` +version=`rpm --query --queryformat '%{version}\n' --specfile $spec` + +name=`echo $name|cut -d" " -f 1` +version=`echo $version|cut -d" " -f 1` + +name=cmsample + +sudo rm -rf $name-$version + +builddir=`pwd` +sourcedir=`pwd` + + +cd $sourcedir/tizen +mkdir ./tmp + +cp -R ./* $sourcedir/tizen/tmp/ +rm -rf $sourcedir/tizen/tmp/tmp/ +cp -R ../../inc/* $sourcedir/tizen/tmp/ +cp -R ../../api/* $sourcedir/tizen/tmp/ +cp ../../src/adapter_util/* $sourcedir/tizen/tmp/ +# Including All CA Adapter code for Tizen Compilation +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 ../../lib $sourcedir/tizen/tmp/ -rf +adapterMacro="" + +if echo $1 | grep -q -i "ALL" +then +echo "Building All the Transports" +cp ../../src/wifi_adapter/tizen/* $sourcedir/tizen/tmp/ +cp ../../src/bt_edr_adapter/* $sourcedir/tizen/tmp/ +cp ../../src/bt_edr_adapter/tizen/* $sourcedir/tizen/tmp/ +cp ../../src/bt_le_adapter/* $sourcedir/tizen/tmp/ +cp ../../src/bt_le_adapter/tizen/* $sourcedir/tizen/tmp/ +adapterMacro=" -DETHERNET_ADAPTER -DWIFI_ADAPTER -DEDR_ADAPTER -DLE_ADAPTER" +else +if echo $1 | grep -q -i "WIFI" +then +echo "Copying WIFI Adapter Source Codes" +cp ../../src/wifi_adapter/tizen/* $sourcedir/tizen/tmp/ +adapterMacro="$adapterMacro -DWIFI_ADAPTER" +fi + +if echo $1 | grep -q -i "BT" +then +echo "Copying BT Adapter Source Codes" +cp ../../src/bt_edr_adapter/* $sourcedir/tizen/tmp/ +cp ../../src/bt_edr_adapter/tizen/* $sourcedir/tizen/tmp/ +adapterMacro="$adapterMacro -DEDR_ADAPTER" +fi + +if echo $1 | grep -q -i "BLE" +then +echo "Copying BLE Adapter Source Codes" +cp ../../src/bt_le_adapter/* $sourcedir/tizen/tmp/ +cp ../../src/bt_le_adapter/tizen/* $sourcedir/tizen/tmp/ +adapterMacro="$adapterMacro -DLE_ADAPTER" +fi +fi + +sed "/ADAPTER_MACRO :=/ c ADAPTER_MACRO :=$adapterMacro" Makefile > Makefile_bkp +cp Makefile_bkp $sourcedir/tizen/tmp/Makefile +rm Makefile_bkp +cd $sourcedir/tizen/tmp/ + +#removing the files which needs for only arduino to avoid +#multiple definition error. +rm -rf *_singlethread.* + +#cd $builddir +#cp -R ./* $sourcedir/tmp/ + +#cd $sourcedir +#mv ./tmp $builddir/ + +#cp -R ./* $builddir/tmp + +#cd $builddir +#mv tmp $name-$version + +#build +#cd $name-$version +git init +gbs build -A armv7l --include-all + +rm -rf $sourcedir/tizen/tmp +#cd $builddir +#sudo rm -rf $name-$version diff --git a/resource/csdk/connectivity/build/tizen/packaging/com.samsung.oicca.spec b/resource/csdk/connectivity/build/tizen/packaging/com.samsung.oicca.spec new file mode 100644 index 0000000..1d28994 --- /dev/null +++ b/resource/csdk/connectivity/build/tizen/packaging/com.samsung.oicca.spec @@ -0,0 +1,66 @@ +%define PREFIX /usr/apps/com.samsung.oicca +%define ROOTDIR %{_builddir}/%{name}-%{version} +%define USR_INC_DIR /usr/include +%define DEST_INC_DIR %{buildroot}%{USR_INC_DIR}/interfaceHeaders +%define DEST_LIB_DIR %{buildroot}/usr/lib + +Name: com.samsung.oicca +Version: 0.1 +Release: 1 +Summary: Tizen oicca application +URL: http://slp-source.sec.samsung.net +Source: %{name}-%{version}.tar.gz +License: SAMSUNG +Group: Samsung/Application +#BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(capi-network-wifi) +BuildRequires: pkgconfig(capi-network-bluetooth) +BuildRequires: boost-devel +BuildRequires: boost-thread +BuildRequires: boost-system +BuildRequires: boost-filesystem +#BuildRequires: oic-core + +%description +SLP oicca application + +%prep +%setup -q + +%build + +make clean +make + +#make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +mkdir -p %{buildroot}/usr/share/packages +mkdir -p %{buildroot}/etc/smack/accesses2.d +mkdir -p %{buildroot}/usr/apps/com.samsung.oicca/bin/ +mkdir -p %{buildroot}/usr/lib +mkdir -p %{DEST_INC_DIR} +mkdir -p %{DEST_LIB_DIR}/pkgconfig + +cp -rf %{ROOTDIR}/liboicinterface.a %{buildroot}/usr/lib +cp -rf %{ROOTDIR}/cacommon.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/caadapterinterface.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/uthreadpool.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/cawifiadapter.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/caethernetadapter.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/caedradapter.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/caleadapter.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/cainterface.h* %{DEST_INC_DIR}/ +cp -rf %{ROOTDIR}/com.samsung.oicca.pc %{DEST_LIB_DIR}/pkgconfig/ + + +%files +%defattr(-,root,root,-) +%attr(-,inhouse,inhouse) +%{_libdir}/lib*.a* +%{_includedir}/interfaceHeaders/* +%{_libdir}/pkgconfig/*.pc diff --git a/resource/csdk/connectivity/common/inc/logger.h b/resource/csdk/connectivity/common/inc/logger.h index b19b037..c09c76f 100644 --- a/resource/csdk/connectivity/common/inc/logger.h +++ b/resource/csdk/connectivity/common/inc/logger.h @@ -29,6 +29,8 @@ #ifdef __ANDROID__ #include +#elif defined(__TIZEN__) +#include #elif defined ARDUINO #include "Arduino.h" #include @@ -51,13 +53,24 @@ extern "C" #define MAX_LOG_V_BUFFER_SIZE (256) // Log levels +#ifndef __TIZEN__ typedef enum { DEBUG = 0, INFO, WARNING, ERROR, FATAL } LogLevel; +#else +#define DEBUG DLOG_DEBUG +#define INFO DLOG_INFO +#define WARNING DLOG_WARNING +#define ERROR DLOG_ERROR +#define FATAL DLOG_ERROR +#endif #ifndef ARDUINO - +#ifdef __TIZEN__ +#define OICLog(level,tag,mes) LOG(level,tag,mes) +#define OICLogv(level,tag,fmt,args...) LOG(level,tag,fmt,##args) +#else /** * Configure logger to use a context that defines a custom logger function * @@ -106,6 +119,7 @@ void OICLogv(LogLevel level, const char * tag, const char * format, ...); * @param bufferSize - max number of byte in buffer */ void OICLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize); +#endif //__TIZEN__ #else /** * Initialize the serial logger for Arduino @@ -144,11 +158,14 @@ void OICLogv(LogLevel level, const char * tag, const char * format, ...); #endif #ifdef TB_LOG -// These macros are defined for Linux, Android, and Arduino + +#ifdef __TIZEN__ +#define OIC_LOG(level,tag,mes) LOG_(LOG_ID_MAIN, level, tag, mes) +#define OIC_LOG_V(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, level, tag, fmt,##args) +#else // These macros are defined for Linux, Android, and Arduino #define OIC_LOG_INIT() OICLogInit() #define OIC_LOG(level, tag, logStr) OICLog((level), (tag), (logStr)) #define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) OICLogBuffer((level), (tag), (buffer), (bufferSize)) - #ifdef ARDUINO #define OIC_LOG_CONFIG(ctx) #define OIC_LOG_SHUTDOWN() @@ -161,9 +178,11 @@ void OICLogv(LogLevel level, const char * tag, const char * format, ...); #define OIC_LOG_SHUTDOWN() OICLogShutdown() // Define variable argument log function for Linux and Android #define OIC_LOG_V(level, tag, ...) OICLogv((level), (tag), __VA_ARGS__) -#endif +#endif //ARDUINO +#endif //__TIZEN__ + +#else //TB_LOG -#else #define OIC_LOG_CONFIG(ctx) #define OIC_LOG_SHUTDOWN() #define OIC_LOG(level, tag, logStr) diff --git a/resource/csdk/connectivity/common/inc/oic_string.h b/resource/csdk/connectivity/common/inc/oic_string.h new file mode 100644 index 0000000..2dca47b --- /dev/null +++ b/resource/csdk/connectivity/common/inc/oic_string.h @@ -0,0 +1,45 @@ +/****************************************************************** + * + * 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 _OIC_STRING_H_ +#define _OIC_STRING_H_ + +#include +#include +#include "oic_malloc.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus /** + * Duplicates the source string and returns it. + * + * NOTE: Caller needs to clear this memory by calling OICFree. + * + * @param str - Original valid string which needs to be duplicated + * + * @return + * on success, a pointer to the duplicated string + * on failure, a null pointer is returned + */ +char *OICStrdup(const char *str); + +#ifdef __cplusplus +} +#endif // __cplusplus #endif /* _OIC_STRING_H_ */ diff --git a/resource/csdk/connectivity/common/inc/uthreadpool.h b/resource/csdk/connectivity/common/inc/uthreadpool.h index fefb852..908c400 100644 --- a/resource/csdk/connectivity/common/inc/uthreadpool.h +++ b/resource/csdk/connectivity/common/inc/uthreadpool.h @@ -27,7 +27,6 @@ #include #include #include -#include #include "cacommon.h" diff --git a/resource/csdk/connectivity/common/src/logger.c b/resource/csdk/connectivity/common/src/logger.c index 0d75266..be4bcae 100644 --- a/resource/csdk/connectivity/common/src/logger.c +++ b/resource/csdk/connectivity/common/src/logger.c @@ -60,8 +60,9 @@ static void OICLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const #define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';} #endif #endif // __ANDROID__ -#ifndef ARDUINO +#ifndef ARDUINO +#ifndef __TIZEN__ void OICLogConfig(oic_log_ctx_t *ctx) { logCtx = ctx; @@ -172,7 +173,7 @@ void OICLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint OICLog(level, tag, lineBuffer); } } - +#endif //__TIZEN__ #else /** * Initialize the serial logger for Arduino @@ -373,5 +374,5 @@ void OICLogv(LogLevel level, PROGMEM const char * tag, const __FlashStringHelper va_end(ap); } -#endif +#endif //ARDUINO diff --git a/resource/csdk/connectivity/common/src/oic_string.c b/resource/csdk/connectivity/common/src/oic_string.c new file mode 100644 index 0000000..d154654 --- /dev/null +++ b/resource/csdk/connectivity/common/src/oic_string.c @@ -0,0 +1,32 @@ +/****************************************************************** + * + * 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 "oic_string.h" + +char *OICStrdup(const char *str) +{ + // Allocate memory for original string length and 1 extra byte for '\0' + size_t length = strlen(str) + 1; + char *dup = OICMalloc(length); + if (NULL != dup) + { + memcpy(dup, str, length); + } + return dup; +} diff --git a/resource/csdk/connectivity/common/src/uqueue.c b/resource/csdk/connectivity/common/src/uqueue.c index 5b04830..8454c10 100644 --- a/resource/csdk/connectivity/common/src/uqueue.c +++ b/resource/csdk/connectivity/common/src/uqueue.c @@ -122,7 +122,7 @@ u_queue_message_t* u_queue_get_element(u_queue_t* queue) if (NULL == element) { - OIC_LOG(DEBUG, TAG, "QueueGetElement : FAIL, no messages"); + OIC_LOG(DEBUG, TAG, "QueueGetElement : empty, no messages"); return NULL; } diff --git a/resource/csdk/connectivity/common/src/uthreadpool.c b/resource/csdk/connectivity/common/src/uthreadpool.c index 477d5fd..0ac5a3f 100644 --- a/resource/csdk/connectivity/common/src/uthreadpool.c +++ b/resource/csdk/connectivity/common/src/uthreadpool.c @@ -46,7 +46,7 @@ CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_p gThreadpool = g_thread_pool_new(run, NULL, num_of_threads, FALSE, &error); if (NULL == gThreadpool) { - OIC_LOG_V(ERROR, TAG, "Error: g_thread_pool_new failed!"); + OIC_LOG_V(ERROR, TAG, "g_thread_pool_new failed!"); if (NULL != error) { OIC_LOG_V(ERROR, TAG, "Error is: %s", error->message); @@ -67,17 +67,23 @@ CAResult_t u_thread_pool_add_task(u_thread_pool_t thread_pool, void (*routine)(v gboolean result = FALSE; if (NULL == routine) { - OIC_LOG_V(ERROR, TAG, "Error: routine is NULL!"); + OIC_LOG_V(ERROR, TAG, "routine is NULL!"); return CA_STATUS_FAILED; } u_thread_msg_t *message = (u_thread_msg_t *) OICMalloc(sizeof(u_thread_msg_t)); + if (NULL == message) + { + OIC_LOG_V(ERROR, TAG, "Memory allocation failed!"); + return CA_MEMORY_ALLOC_FAILED; + } + message->data = data; message->func = routine; result = g_thread_pool_push((GThreadPool *) thread_pool, (void *) message, NULL); if (FALSE == result) { - OIC_LOG_V(ERROR, TAG, "Error: Failed to push the task to threadpool!"); + OIC_LOG_V(ERROR, TAG, "Failed to push the task to threadpool!"); return CA_STATUS_FAILED; } @@ -106,7 +112,7 @@ void run(void *thread_data, void *user_data) } else { - OIC_LOG_V(ERROR, TAG, "Error: Invalid task data"); + OIC_LOG_V(ERROR, TAG, "Invalid task data"); return; } diff --git a/resource/csdk/connectivity/RELEASE v0.1 b/resource/csdk/connectivity/doc/release/RELEASE v0.1 similarity index 100% rename from resource/csdk/connectivity/RELEASE v0.1 rename to resource/csdk/connectivity/doc/release/RELEASE v0.1 diff --git a/resource/csdk/connectivity/inc/caadapterinterface.h b/resource/csdk/connectivity/inc/caadapterinterface.h index 67a44cb..5acae9a 100644 --- a/resource/csdk/connectivity/inc/caadapterinterface.h +++ b/resource/csdk/connectivity/inc/caadapterinterface.h @@ -34,10 +34,11 @@ extern "C" /** * @brief Starting connectivity adapters and each adapter have transport specific behavior. - * Transport Specific Behavior: - * WIFI/ETH connectivity Starts unicast server on all available IPs and defined port number as per specification. - * EDR will not start any specific servers. - * LE will not start any specific servers. + * Transport Specific Behavior: + * WIFI/ETH connectivity Starts unicast server on all available IPs and defined + * port number as per specification. + * EDR will not start any specific servers. + * LE will not start any specific servers. * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ typedef CAResult_t (*CAAdapterStart)(); @@ -45,9 +46,10 @@ typedef CAResult_t (*CAAdapterStart)(); /** * @brief Starting listening server for receiving multicast search requests * Transport Specific Behavior: - * WIFI/ETH Starts multicast server on all available IPs and defined port number and as per specification. - * EDR Starts RFCOMM Server with prefixed UUID as per specification. - * LE Start GATT Server with prefixed UUID and Characteristics as per OIC Specification. + * WIFI/ETH Starts multicast server on all available IPs and defined + * port number and as per specification. + * EDR Starts RFCOMM Server with prefixed UUID as per specification. + * LE Start 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) */ typedef CAResult_t (*CAAdapterStartListeningServer)(); @@ -55,9 +57,10 @@ typedef CAResult_t (*CAAdapterStartListeningServer)(); /** * @brief for starting discovery servers for receiving multicast advertisements * Transport Specific Behavior: - * WIFI/ETH Starts multicast server on all available IPs and defined port number as per OIC Specification. - * EDR Starts RFCOMM Server with prefixed UUID as per OIC Specification. - * LE Starts GATT Server with prefixed UUID and Characteristics as per OIC Specification. + * WIFI/ETH Starts multicast server on all available IPs and defined port + * number as per OIC Specification. + * EDR Starts RFCOMM Server with prefixed UUID as per OIC Specification. + * 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) */ typedef CAResult_t (*CAAdapterStartDiscoveryServer)(); @@ -65,13 +68,13 @@ typedef CAResult_t (*CAAdapterStartDiscoveryServer)(); /** * @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 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. */ -typedef uint32_t (*CAAdapterSendUnitcastData)(const CARemoteEndpoint_t* endpoint, void* data, +typedef uint32_t (*CAAdapterSendUnitcastData)(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen); /** @@ -81,7 +84,7 @@ typedef uint32_t (*CAAdapterSendUnitcastData)(const CARemoteEndpoint_t* endpoint * @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. */ -typedef uint32_t (*CAAdapterSendMulticastData)(void* data, uint32_t dataLen); +typedef uint32_t (*CAAdapterSendMulticastData)(void *data, uint32_t dataLen); /** * @brief Starts notification server on adapters. @@ -92,13 +95,13 @@ typedef CAResult_t (*CAAdapterStartNotificationRecvServer)(); /** * @brief Send notification information to the given endpoint. * 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 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. */ -typedef uint32_t (*CAAdapterSendNotification)(const CARemoteEndpoint_t* endpoint, void* data, +typedef uint32_t (*CAAdapterSendNotification)(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen); /** @@ -107,7 +110,7 @@ typedef uint32_t (*CAAdapterSendNotification)(const CARemoteEndpoint_t* endpoint * @param size [OUT] Number of local connectivity structures. * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ -typedef CAResult_t (*CAAdapterGetNetworkInfo)(CALocalConnectivityt_t** info, uint32_t* size); +typedef CAResult_t (*CAAdapterGetNetworkInfo)(CALocalConnectivity_t **info, uint32_t *size); /** * @brief Read Synchronous API callback. @@ -118,15 +121,16 @@ typedef CAResult_t (*CAAdapterReadData)(); /** * @brief Stopping the adapters and close socket connections * Transport Specific Behavior: - * WIFI/ETH Stops all listening servers and close sockets. - * EDR Stops all RFCOMM servers and close sockets. - * LE Stops all GATT servers and close sockets. + * WIFI/ETH Stops all listening servers and close sockets. + * EDR Stops all RFCOMM servers and close sockets. + * LE Stops all GATT servers and close sockets. * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ typedef CAResult_t (*CAAdapterStop)(); /** - * @brief Terminate the connectivity adapter.Configuration information will be deleted from further use + * @brief Terminate the connectivity adapter.Configuration information will be deleted from + * further use */ typedef void (*CAAdapterTerminate)(); @@ -171,14 +175,14 @@ typedef void (*CARegisterConnectivityCallback)(CAConnectivityHandler_t handler, * @brief This will be used during the recive of network requests and response. * @see SendUnitcastData(), SendMulticastData() */ -typedef void (*CANetworkPacketReceivedCallback)(CARemoteEndpoint_t* endPoint, void* data, +typedef void (*CANetworkPacketReceivedCallback)(CARemoteEndpoint_t *endPoint, void *data, uint32_t dataLen); /** * @brief This will be used to intimate network changes to the connectivity common logic layer * @see SendUnitcastData(), SendMulticastData() */ -typedef void (*CANetworkChangeCallback)(CALocalConnectivityt_t* info, CANetworkStatus_t status); +typedef void (*CANetworkChangeCallback)(CALocalConnectivity_t *info, CANetworkStatus_t status); #ifdef __cplusplus } /* extern "C" */ diff --git a/resource/csdk/connectivity/inc/caadapterutils.h b/resource/csdk/connectivity/inc/caadapterutils.h new file mode 100644 index 0000000..3474442 --- /dev/null +++ b/resource/csdk/connectivity/inc/caadapterutils.h @@ -0,0 +1,101 @@ +/****************************************************************** + * + * 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 caadapterutils.h + * @brief This file contains common utility function for CA transport adaptors. + */ + +#ifndef _CA_ADAPTER_UTILS_H_ +#define _CA_ADAPTER_UTILS_H_ + +#include "cacommon.h" +#include "logger.h" +#include "oic_malloc.h" + +/** + * @def VERIFY_NON_NULL + * @brief Macro to verify the validity of input argument + */ +#define VERIFY_NON_NULL(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input: %s!", log_message); \ + return CA_STATUS_INVALID_PARAM; \ + } \ + +/** + * @def VERIFY_NON_NULL_RET + * @brief Macro to verify the validity of input argument + */ +#define VERIFY_NON_NULL_RET(arg, log_tag, log_message,ret) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input: %s!", log_message); \ + return ret; \ + } \ + +/** + * @def VERIFY_NON_NULL_VOID + * @brief Macro to verify the validity of input argument + */ +#define VERIFY_NON_NULL_VOID(arg, log_tag, log_message) \ + if (NULL == arg ){ \ + OIC_LOG_V(ERROR, log_tag, "Invalid input: %s!", log_message); \ + return; \ + } \ + +/** + * @fn CAAdapterCreateLocalEndpoint + * @brief Create CALocalConnectivity_t instance. + */ +CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type, const char *address, + const char *interfaceName); + +/** + * @fn CAAdapterCopyLocalEndpoint + * @brief Create CALocalConnectivity_t duplicate instance. + */ +CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(CALocalConnectivity_t *connectivity); + +/** + * @fn CAAdapterFreeLocalEndpoint + * @brief Deallocate CALocalConnectivity_t instance. + */ +void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndPoint); + +/** + * @fn CAAdapterCreateRemoteEndpoint + * @brief Allocate CARemoteEndpoint_t instance. + */ +CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type, const char *address, + const char *resourceUri); + +/** + * @fn CAAdapterCopyRemoteEndpoint + * @brief Create CARemoteEndpoint_t duplicate instance. + */ +CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint); + +/** + * @fn CAAdapterFreeRemoteEndpoint + * @brief Deallocate CARemoteEndpoint_t instance. + */ +void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndPoint); + +#endif // _CA_ADAPTER_UTILS_H_ diff --git a/resource/csdk/connectivity/inc/caedradapter.h b/resource/csdk/connectivity/inc/caedradapter.h index 2b68a07..4e64b09 100644 --- a/resource/csdk/connectivity/inc/caedradapter.h +++ b/resource/csdk/connectivity/inc/caedradapter.h @@ -29,15 +29,13 @@ **/ #include "cacommon.h" #include "caadapterinterface.h" +#include "uthreadpool.h" /* for thread pool */ #ifdef __cplusplus extern "C" { #endif -#ifndef BLUETOOTH_ADAPTER_TAG -#define BLUETOOTH_ADAPTER_TAG "CA_EDR" -#endif //BLUETOOTH_ADAPTER_TAG /** * @brief Initialize EDR connectivity interface. * @param registerCallback [IN] To register EDR interfaces to Connectivity Abstraction Layer @@ -46,7 +44,8 @@ extern "C" * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h) */ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback); + CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle); /** * @brief Starting EDR connectivity adapters .As its peer to peer it doesnot require to start any servers @@ -79,7 +78,7 @@ CAResult_t CAStartEDRDiscoveryServer(); * @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); +uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen); /** * @brief Sends Multicast data to the endpoint using the EDR connectivity. @@ -88,7 +87,7 @@ uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t* endpoint, void* data, ui * @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); +uint32_t CASendEDRMulticastData(void *data, uint32_t dataLen); /** * @brief Starts notification server on EDR adapters. @@ -105,7 +104,7 @@ CAResult_t CAStartEDRNotifyServer(); * @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); +uint32_t CASendEDRNotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen); /** * @brief Get EDR Connectivity network information @@ -113,7 +112,7 @@ uint32_t CASendEDRNotification(const CARemoteEndpoint_t* endpoint, void* data, u * @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(CALocalConnectivityt_t** info, uint32_t* size); +CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); /** * @brief Read Synchronous API callback. diff --git a/resource/csdk/connectivity/inc/caerrorcode.h b/resource/csdk/connectivity/inc/caerrorcode.h deleted file mode 100644 index 80905b4..0000000 --- a/resource/csdk/connectivity/inc/caerrorcode.h +++ /dev/null @@ -1,65 +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_ERROR_CODE_H_ -#define __CA_ERROR_CODE_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * Declares Stack Results & Errors - */ -typedef enum -{ - OC_STACK_OK = 0, - OC_STACK_INVALID_URI, - OC_STACK_INVALID_QUERY, - OC_STACK_INVALID_IP, - OC_STACK_INVALID_PORT, - OC_STACK_INVALID_CALLBACK, - OC_STACK_INVALID_METHOD, - OC_STACK_INVALID_PARAM, - OC_STACK_INVALID_OBSERVE_PARAM, - OC_STACK_NO_MEMORY, - OC_STACK_COMM_ERROR, - OC_STACK_NOTIMPL, - OC_STACK_NO_RESOURCE, /* resource not found*/ - OC_STACK_RESOURCE_ERROR, /*ex: not supported method or interface*/ - OC_STACK_SLOW_RESOURCE, - OC_STACK_NO_OBSERVERS, /* resource has no registered observers */ - OC_STACK_OBSERVER_NOT_FOUND, - OC_STACK_OBSERVER_NOT_ADDED, - OC_STACK_OBSERVER_NOT_REMOVED, -#ifdef WITH_PRESENCE - OC_STACK_PRESENCE_NO_UPDATE, - OC_STACK_PRESENCE_STOPPED, - OC_STACK_PRESENCE_DO_NOT_HANDLE, -#endif - OC_STACK_ERROR -} OCStackResult; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif //#ifndef __CA_ERROR_CODE_H_ diff --git a/resource/csdk/connectivity/inc/caethernetadapter.h b/resource/csdk/connectivity/inc/caethernetadapter.h index 61e8a4d..118fee1 100644 --- a/resource/csdk/connectivity/inc/caethernetadapter.h +++ b/resource/csdk/connectivity/inc/caethernetadapter.h @@ -27,6 +27,7 @@ #include "cacommon.h" #include "caadapterinterface.h" +#include "uthreadpool.h" /* for thread pool */ #ifdef __cplusplus extern "C" @@ -34,14 +35,16 @@ extern "C" #endif /** - * @brief Initialize Ethernet connectivity interface. + * @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 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); + CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle); /** * @brief Start Ethernet Interface adapter. @@ -52,7 +55,8 @@ 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. + * 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(); @@ -60,7 +64,8 @@ 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 + * 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(); @@ -68,48 +73,48 @@ 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 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); +uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *endpoint, void *data, + uint32_t dataLen); /** - * @brief Sends Multicast data to the endpoint using the WIFI connectivity. + * @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); +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 CAStartEthernetNotifyServer(); +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 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); +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(CALocalConnectivityt_t** info, uint32_t* size); +CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); /** * @brief Read Synchronous API callback. @@ -134,4 +139,4 @@ void CATerminateEthernet(); } /* extern "C" */ #endif -#endif +#endif//#ifndef __CA_ETHERNET_ADAPTER_H__ diff --git a/resource/csdk/connectivity/inc/caethernetcore.h b/resource/csdk/connectivity/inc/caethernetcore.h new file mode 100644 index 0000000..32d8ec3 --- /dev/null +++ b/resource/csdk/connectivity/inc/caethernetcore.h @@ -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. + * + ******************************************************************/ + +/** + * @file caethernetcore.h + * @brief This file contains the APIs for Ethernet communications. + */ +#ifndef __CA_ETHERNETCORE_H_ +#define __CA_ETHERNETCORE_H_ + +#include "cacommon.h" +#include "config.h" +#include "coap.h" +#include "uthreadpool.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef void (*CAPacketReceiveCallback)(const char* address, const char* data); + +void CAEthernetInitialize(u_thread_pool_t handle); + +void CAEthernetTerminate(); + +int32_t CAEthernetSendUnicastMessage(const char* address, const char* data, int32_t length); + +int32_t CAEthernetSendMulticastMessage(const char* m_address, const char* data); + +int32_t CAEthernetStartUnicastServer(); + +int32_t CAEthernetStartMulticastServer(); + +int32_t CAEthernetStopUnicastServer(); + +int32_t CAEthernetStopMulticastServer(); + +void CAEthernetSetCallback(CAPacketReceiveCallback callback); + +void CAEthernetGetLocalAddress(char* addressBuffer); + +int32_t CAEthernetSendUnicastMessageImpl(const char* address, const char* data); + +int32_t CAEthernetSendMulticastMessageImpl(const char* msg); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/resource/csdk/connectivity/inc/cainterfacecontroller.h b/resource/csdk/connectivity/inc/cainterfacecontroller.h index d2af4d2..c61900b 100644 --- a/resource/csdk/connectivity/inc/cainterfacecontroller.h +++ b/resource/csdk/connectivity/inc/cainterfacecontroller.h @@ -21,20 +21,25 @@ #define __CA_INTERFACE_CONTROLLER_H_ #include "caadapterinterface.h" +#include "uthreadpool.h" /* for thread pool */ #ifdef __cplusplus extern "C" { #endif -void CAInitializeAdapters(); +void CAInitializeAdapters(u_thread_pool_t handle); void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback); +void CASetNetworkChangeCallback(CANetworkChangeCallback callback); + void CAStartAdapter(CAConnectivityType_t connectivity); void CAStopAdapter(CAConnectivityType_t connectivity); +CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t* size); + CAResult_t CASendUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t length); CAResult_t CASendMulticastData(void* data, uint32_t length); diff --git a/resource/csdk/connectivity/inc/caleadapter.h b/resource/csdk/connectivity/inc/caleadapter.h index a99d161..bb86930 100644 --- a/resource/csdk/connectivity/inc/caleadapter.h +++ b/resource/csdk/connectivity/inc/caleadapter.h @@ -27,6 +27,7 @@ #include "cacommon.h" #include "caadapterinterface.h" +#include "uthreadpool.h" /* for thread pool */ /** * BLE Interface APIs. @@ -39,14 +40,19 @@ extern "C" /** * @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 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); + CANetworkPacketReceivedCallback reqRespCallback, + CANetworkChangeCallback netCallback, + u_thread_pool_t handle); /** - * @brief Starting LE connectivity adapters .As its peer to peer it doesnot require to start any servers + * @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(); @@ -70,13 +76,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. - * @param data [IN] Data which required to be sent. - * @param dataLen [IN] Size of data to be sent. + * @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); +uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen); /** * @brief Sends Multicast data to the endpoint using the LE connectivity. @@ -85,7 +91,7 @@ uint32_t CASendLEUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uin * @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); +uint32_t CASendLEMulticastData(void *data, uint32_t dataLen); /** * @brief Starts notification server on EDR adapters. @@ -96,13 +102,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. + * @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. + * @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 @@ -110,7 +116,7 @@ uint32_t CASendLENotification(const CARemoteEndpoint_t* endpoint, void* data, ui * @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(CALocalConnectivityt_t** info, uint32_t* size); +CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); /** * @brief Read Synchronous API callback. diff --git a/resource/csdk/connectivity/inc/camessagehandler.h b/resource/csdk/connectivity/inc/camessagehandler.h index 597da7b..0185702 100644 --- a/resource/csdk/connectivity/inc/camessagehandler.h +++ b/resource/csdk/connectivity/inc/camessagehandler.h @@ -28,20 +28,13 @@ extern "C" { #endif -typedef enum -{ - SUCCESS = 0, NETWORK_ERROR, FAIL -} CADetachErrorCode; - -typedef void (*CAMessageHandlerCallback)(int32_t id, CADetachErrorCode code); - -int32_t CADetachRequestMessage(const CARemoteEndpoint_t* object, const CARequestInfo_t* request); - -int32_t CADetachResponseMessage(const CARemoteEndpoint_t* object, const CAResponseInfo_t* response); +CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t* object, const CARequestInfo_t* request); -int32_t CADetachMessageResourceUri(const CAURI_t resourceUri); +CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t* object, + const CAResponseInfo_t* response); -void CASetMessageHandlerCallback(CAMessageHandlerCallback callback); +CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAHeaderOption_t* options, + uint8_t numOptions); void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler); diff --git a/resource/csdk/connectivity/inc/camessagequeue.h b/resource/csdk/connectivity/inc/camessagequeue.h new file mode 100644 index 0000000..7eb372c --- /dev/null +++ b/resource/csdk/connectivity/inc/camessagequeue.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. + * + ******************************************************************/ + +#ifndef _CA_MESSAGE_QUEUE_H_ +#define _CA_MESSAGE_QUEUE_H_ + +#include "umutex.h" +#include "cacommon.h" + +/** + @brief Adapter message information + */ +typedef struct CAAdapterMessage_t +{ + CARemoteEndpoint_t *remoteEndpoint; + void *data; + uint32_t dataLen; + struct CAAdapterMessage_t *next; +} CAAdapterMessage_t; + +/** + @brief Adapter message queue + */ +typedef struct +{ + u_mutex queueMutex; + CAAdapterMessage_t *begin; + CAAdapterMessage_t *end; +} 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, + 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/canetworkconfigurator.h b/resource/csdk/connectivity/inc/canetworkconfigurator.h index 4117bf7..38eea6c 100644 --- a/resource/csdk/connectivity/inc/canetworkconfigurator.h +++ b/resource/csdk/connectivity/inc/canetworkconfigurator.h @@ -20,6 +20,7 @@ #ifndef _NETWORK_CONFIGURATOR_H_ #define _NETWORK_CONFIGURATOR_H_ +#include "cacommon.h" #include "uarraylist.h" #ifdef __cplusplus @@ -38,6 +39,8 @@ CAResult_t CARemoveNetworkType(uint32_t CAConnectivityType); u_arraylist_t* CAGetSelectedNetworkList(); +CAResult_t CAGetNetworkInformationInternal(CALocalConnectivity_t **info, uint32_t* size); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/inc/caprotocolmessage.h b/resource/csdk/connectivity/inc/caprotocolmessage.h index baeb261..e2ec963 100644 --- a/resource/csdk/connectivity/inc/caprotocolmessage.h +++ b/resource/csdk/connectivity/inc/caprotocolmessage.h @@ -29,41 +29,50 @@ extern "C" { #endif -uint32_t flags = 0; - -uint8_t msgtype = COAP_MESSAGE_CON; /* usually, requests are sent confirmable */ - -coap_block_t block = -{ .num = 0, .m = 0, .szx = 6}; - typedef uint32_t code_t; /** - * function for generate + * function for generating */ coap_pdu_t* CAGeneratePdu(const char* uri, const uint32_t code, const CAInfo_t info); + /** - * function for parsing + * function for generating */ -uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t* outReqInfo); +uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t* outReqInfo, char* outUri); -uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t* outResInfo); +uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t* outResInfo, + char* outUri); coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options); coap_pdu_t* CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *optlist, const char* payload); +/** + * funtion for parsing + */ void CAParseURI(const char* uriInfo, coap_list_t **options); +/** + * funtion for parsing + */ void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist); coap_list_t* CACreateNewOptionNode(const uint16_t key, const uint32_t length, const uint8_t *data); int32_t CAOrderOpts(void *a, void *b); -void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t* outCode, CAInfo_t* outInfo); +uint32_t getOptionCount(coap_opt_iterator_t opt_iter); +/** + * funtion for get PDU information + */ +void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t* outCode, CAInfo_t* outInfo, char* outUri); + +/** + * funtion for parsing + */ coap_pdu_t* CAParsePDU(const char* data, uint32_t* outCode); /** @@ -73,6 +82,11 @@ CAResult_t CAGenerateTokenInternal(CAToken_t* token); void CADestroyTokenInternal(CAToken_t token); +/** + * Deinitialize + */ +void CADeinitialize(CAInfo_t* info); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/inc/caqueueingthread.h b/resource/csdk/connectivity/inc/caqueueingthread.h new file mode 100644 index 0000000..89bf067 --- /dev/null +++ b/resource/csdk/connectivity/inc/caqueueingthread.h @@ -0,0 +1,66 @@ +/****************************************************************** + * + * 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 caqueueingthread.h + */ +#ifndef __CA_THREAD_H_ +#define __CA_THREAD_H_ + +#include + +#include "uthreadpool.h" +#include "umutex.h" +#include "uqueue.h" +#include "cacommon.h" +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef void (*CAThreadTask)(void* threadData); + +typedef struct +{ + u_thread_pool_t threadPool; + u_mutex threadMutex; + u_cond threadCond; + CAThreadTask threadTask; + CABool_t isStop; + u_queue_t* dataQueue; +} CAQueueingThread_t; + +CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t* thread, u_thread_pool_t handle, + CAThreadTask task); + +CAResult_t CAQueueingThreadStart(CAQueueingThread_t* thread); + +// shallow copy +CAResult_t CAQueueingThreadAddData(CAQueueingThread_t* thread, void* data, uint32_t size); + +CAResult_t CAQueueingThreadStop(CAQueueingThread_t* thread); + +CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t* thread); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // __CA_THREAD_H_ diff --git a/resource/csdk/connectivity/inc/cawifiadapter.h b/resource/csdk/connectivity/inc/cawifiadapter.h index 07ad36a..674514c 100644 --- a/resource/csdk/connectivity/inc/cawifiadapter.h +++ b/resource/csdk/connectivity/inc/cawifiadapter.h @@ -27,6 +27,7 @@ #include "cacommon.h" #include "caadapterinterface.h" +#include "uthreadpool.h" /* for thread pool */ #ifdef __cplusplus extern "C" @@ -36,12 +37,14 @@ extern "C" /** * @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 networkPacketCallback [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 reqRespCallback, CANetworkChangeCallback netCallback); + CANetworkPacketReceivedCallback networkPacketCallback, + CANetworkChangeCallback netCallback, u_thread_pool_t handle); /** * @brief Start WiFi Interface adapter. @@ -52,7 +55,8 @@ 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. + * 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(); @@ -60,7 +64,8 @@ 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 + * 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(); @@ -68,13 +73,13 @@ 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 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); +uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen); /** * @brief Sends Multicast data to the endpoint using the WIFI connectivity. @@ -83,7 +88,7 @@ uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t* endpoint, void* data, u * @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); +uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLen); /** * @brief Starts notification server on WIFI adapters. @@ -94,20 +99,20 @@ 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 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); +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(CALocalConnectivityt_t** info, uint32_t* size); +CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size); /** * @brief Read Synchronous API callback. @@ -132,4 +137,4 @@ void CATerminateWIfI(); } /* extern "C" */ #endif -#endif//#ifndef __CA_WIFI_ADAPTER_H__ +#endif // #ifndef __CA_WIFI_ADAPTER_H__ diff --git a/resource/csdk/connectivity/inc/cawificore.h b/resource/csdk/connectivity/inc/cawificore.h index 64e7a20..4c75397 100644 --- a/resource/csdk/connectivity/inc/cawificore.h +++ b/resource/csdk/connectivity/inc/cawificore.h @@ -28,6 +28,7 @@ #include "cacommon.h" #include "config.h" #include "coap.h" +#include "uthreadpool.h" #ifdef __cplusplus extern "C" @@ -36,7 +37,7 @@ extern "C" typedef void (*CAPacketReceiveCallback)(const char* address, const char* data); -void CAWiFiInitialize(); +void CAWiFiInitialize(u_thread_pool_t handle); void CAWiFiTerminate(); @@ -44,38 +45,22 @@ int32_t CAWiFiSendUnicastMessage(const char* address, const char* data, int32_t int32_t CAWiFiSendMulticastMessage(const char* m_address, const char* data); -int32_t CAWiFiStartUnicastServer(const char* address, int32_t port); +int32_t CAWiFiStartUnicastServer(); -int32_t CAWiFiStartMulticastServer(const char* m_address, int32_t port); +int32_t CAWiFiStartMulticastServer(); -int32_t CAWiFiStopUnicastServer(int32_t server_id); +int32_t CAWiFiStopUnicastServer(); -int32_t CAWiFiStopMulticastServer(int32_t server_id); +int32_t CAWiFiStopMulticastServer(); void CAWiFiSetCallback(CAPacketReceiveCallback callback); -void* CAUnicastReceiveThread(void* data); - -void* CAUnicastSendThread(void* data); - -void CASendUnicastMessage(char* address, void* data); - -int32_t CASendUnicastMessageImpl(const char* address, const char* data, int32_t lengh); - -void CAStopUnicastSendThread(); - -void* CAMulticastReceiveThread(void* data); - -void* CAMulticastSendThread(void* data); +void CAGetLocalAddress(char* addressBuffer); -void CASendMulticastMessage(void* data); +int32_t CASendUnicastMessageImpl(const char* address, const char* data); int32_t CASendMulticastMessageImpl(const char* msg); -void CAStopMulticastSendThread(); - -void CAGetLocalAddress(char* addressBuffer); - #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/resource/csdk/connectivity/inc/cawifiethernetadapter.h b/resource/csdk/connectivity/inc/cawifiethernetadapter.h deleted file mode 100644 index 45dcab8..0000000 --- a/resource/csdk/connectivity/inc/cawifiethernetadapter.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 cawifiethernetadapter.h - * @brief This file contains the APIs for WiFi/Ethernet Adapter. - */ -#ifndef __CA_WIFI_ETHERNET_ADAPTER_H__ -#define __CA_WIFI_ETHERNET_ADAPTER_H__ - -#include "cacommon.h" -#include "caadapterinterface.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @brief API to initialize WiFi Interface. - * @param registerCallback to register WIFI interfaces to things communication - * @param reqRespCallback for sending responses and discovery messages from unicast , multicast servers - * @param netCallback to intimate the network additions to things communication - * @return Error Code - */ -CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback); - -/** - * @brief API to Start WiFi Interface. - * @return Error Code - */ -CAResult_t CAStartWIFI(); - -/** - * @brief starting listening server - * Transport Specific Behaviour - * IP :- Start Multicast Server on all available IPs and prefixed port number and as per OIC Specification. - * @return Error Code CAResult_t. - */ -CAResult_t CAStartWIFIListeningServer(); - -/** - * @brief for starting discovery servers. - * Transport Specific Behaviour - * IP :- Start Multicast Server on all available IPs and prefixed port number as per OIC Specification. - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFIDiscoveryServer(); - -/** - * @brief Send Multicast Data interface API callback. - * Note: length must be > 0 - * @param endpoint - Endpoint information (like ipaddress , port, reference uri and connectivity type) to which the multicast data has to be sent. - * @param data - void pointer data which will be sent via client - * @param dataLen - size of data to be sent - * @return - Will 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 API to send data to a group of remote addresses. - * @param endpoint - Endpoint information (like ipaddress , port, reference uri and connectivity type) to which the multicast data has to be sent. - * @param data - void pointer data which will be sent via client - * @param dataLen - size of data to be sent - * @return - size of data sent or -1 on error - */ -uint32_t CASendWIFIMulticastData(void* data, uint32_t dataLen); - -/** - * @brief Start Notification Server interface API callback. - * - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAStartWIFINotifyRecvServers(); - -/** - * @brief Send Notification Data interface API callback. - * Note: length must be > 0 - * @param endpoint - remote endpoint having endpoint details - * @param data - data to be sent - * @param dataLen - length of data to be sent - * @return Will 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 Network Information - * - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size); - -/** - * @brief Read Synchronous API callback. - * @return Error Code CAResult_t. - * @return CAResult_t. - * CA_STATUS_OK = 0 else ERROR CODES ( CAResult_t error codes in cacommon.h) - */ -CAResult_t CAReadWIFIData(); - -/** - * @brief API to Stop WiFi Interface. - * @return CAResult_t - */ -CAResult_t CAStopWIFI(); - -/** - * @brief API to terminate WiFi Interface. - * @return none. - */ -void CATerminateWifi(); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h index 24ebce7..ccfb490 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/address.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file address.h * @brief representation of network addresses */ @@ -117,29 +117,26 @@ _coap_is_mcast_impl(const coap_address_t *a) { if (!a) { - printf("[COAP] address - coap_address_t is false\n"); return 0; } switch (a->addr.sa.sa_family) { case AF_INET: - printf("[COAP] address - local address : %s\n", a->addr.sin.sin_addr.s_addr); return IN_MULTICAST(a->addr.sin.sin_addr.s_addr); case AF_INET6: return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr); default: /* fall through and signal error */ - printf("[COAP] address - sa_family is default value\n"); ; } return 0; } #endif /* WITH_POSIX */ -/** +/** * Resets the given coap_address_t object @p addr to its default * values. In particular, the member size must be initialized to the * available size for storing addresses. - * + * * @param addr The coap_address_t object to initialize. */ static inline void coap_address_init(coap_address_t *addr) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h index 9f6c7b0..879cb38 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/async.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file async.h * @brief state management for asynchronous messages */ @@ -32,7 +32,7 @@ typedef struct coap_async_state_t { unsigned char flags; /**< holds the flags to control behaviour */ - /** + /** * Holds the internal time when the object was registered with a * resource. This field will be updated whenever * coap_register_async() is called for a specific resource. @@ -63,7 +63,7 @@ typedef struct coap_async_state_t /** release application data on destruction */ #define COAP_ASYNC_RELEASE_DATA 0x08 -/** +/** * Allocates a new coap_async_state_t object and fills its fields * according to the given @p request. The @p flags are used to control * generation of empty ACK responses to stop retransmissions and to @@ -72,7 +72,7 @@ typedef struct coap_async_state_t * coap_async_t object or @c NULL on error. Note that this function will * return @c NULL in case that an object with the same identifier is * already registered. - * + * * @param context The context to use. * @param peer The remote peer that is to be asynchronously notified. * @param request The request that is handled asynchronously. @@ -80,7 +80,7 @@ typedef struct coap_async_state_t * @param data Opaque application data to register. Note that the * storage occupied by @p data is released on destruction * only if flag COAP_ASYNC_RELEASE_DATA is set. - * + * * @return A pointer to the registered coap_async_state_t object or * @c NULL in case of an error. */ @@ -88,52 +88,52 @@ coap_async_state_t * coap_register_async(coap_context_t *context, coap_address_t *peer, coap_pdu_t *request, unsigned char flags, void *data); -/** +/** * Removes the state object identified by @p id from @p context. The * removed object is returned in @p s, if found. Otherwise, @p s is * undefined. This function returns @c 1 if the object was removed, @c * 0 otherwise. Note that the storage allocated for the stored object * is not released by this functions. You will have to call * coap_free_async() to do so. - * + * * @param context The context where the async object is registered. * @param id The identifier of the asynchronous transaction. - * @param s Will be set to the object identified by @p id + * @param s Will be set to the object identified by @p id * after removal. - * + * * @return @c 1 if object was removed and @p s updated, or @c 0 if no * object was found with the given id. @p s is valid only if the * return value is @c 1. */ int coap_remove_async(coap_context_t *context, coap_tid_t id, coap_async_state_t **s); -/** +/** * Releases the memory that was allocated by coap_async_state_init() * for the object @p s. The registered application data will be * released automatically if COAP_ASYNC_RELEASE_DATA is set. - * + * * @param s The object to delete. */ void coap_free_async(coap_async_state_t *state); -/** +/** * Retrieves the object identified by @p id from the list of asynchronous * transactions that are registered with @p context. This function returns * a pointer to that object or @c NULL if not found. - * - * @param context The context where the asynchronous objects are + * + * @param context The context where the asynchronous objects are * registered with. * @param id The id of the object to retrieve. - * + * * @return A pointer to the object identified by @p id or @c NULL if * not found. */ coap_async_state_t *coap_find_async(coap_context_t *context, coap_tid_t id); -/** +/** * Updates the time stamp of @p s. - * + * * @param s The state object to update. */ static inline void coap_touch_async(coap_async_state_t *s) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h index 487af39..0e121ab 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/bits.h @@ -4,7 +4,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ /** @@ -18,15 +18,15 @@ #include #include -/** +/** * Sets the bit @p bit in bit-vector @p vec. This function returns @c * 1 if bit was set or @c -1 on error (i.e. when the given bit does * not fit in the vector). - * + * * @param vec The bit-vector to change. * @param size The size of @p vec in bytes. * @param bit The bit to set in @p vec. - * + * * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. */ inline static int bits_setb(uint8_t *vec, size_t size, uint8_t bit) @@ -38,15 +38,15 @@ inline static int bits_setb(uint8_t *vec, size_t size, uint8_t bit) return 1; } -/** +/** * Clears the bit @p bit from bit-vector @p vec. This function returns * @c 1 if bit was cleared or @c -1 on error (i.e. when the given bit * does not fit in the vector). - * + * * @param vec The bit-vector to change. * @param size The size of @p vec in bytes. * @param bit The bit to clear from @p vec. - * + * * @return @c -1 if @p bit does not fit into @p vec, @c 1 otherwise. */ inline static int bits_clrb(uint8_t *vec, size_t size, uint8_t bit) @@ -58,14 +58,14 @@ inline static int bits_clrb(uint8_t *vec, size_t size, uint8_t bit) return 1; } -/** +/** * Gets the status of bit @p bit from bit-vector @p vec. This function returns * @c 1 if the bit is set, @c 0 otherwise (even in case of an error).. - * + * * @param vec The bit-vector to read from.. * @param size The size of @p vec in bytes. * @param bit The bit to get from @p vec. - * + * * @return @c 1 if the bit is set, @c 0 otherwise. */ inline static int bits_getb(const uint8_t *vec, size_t size, uint8_t bit) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c index 3ad47e3..709f57c 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h index 6451383..91de631 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/block.h @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012,2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_BLOCK_H_ @@ -32,7 +32,7 @@ #endif /** - * Structure of Block options. + * Structure of Block options. */ typedef struct { @@ -42,7 +42,7 @@ typedef struct } coap_block_t; /** - * Returns the value of the least significant byte of a Block option @p opt. + * Returns the value of the least significant byte of a Block option @p opt. * For zero-length options (i.e. num == m == szx == 0), COAP_OPT_BLOCK_LAST * returns @c NULL. */ @@ -88,7 +88,7 @@ static inline void coap_opt_block_set_m(coap_opt_t *block_opt, int m) * value @c 1. Otherwise, @c 0 is returned. * * @param pdu The pdu to search for option @p type. - * @param type The option to search for (must be COAP_OPTION_BLOCK1 or + * @param type The option to search for (must be COAP_OPTION_BLOCK1 or * COAP_OPTION_BLOCK2) * @param block The block structure to initilize. * @return @c 1 on success, @c 0 otherwise. @@ -102,9 +102,9 @@ int coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block); * space is required. The actual length of the resource is specified * in @p data_length. * - * This function may change *block to reflect the values written to + * This function may change *block to reflect the values written to * @p pdu. As the function takes into consideration the remaining space - * @p pdu, no more options should be added after coap_write_block_opt() + * @p pdu, no more options should be added after coap_write_block_opt() * has returned. * * @param block The block structure to use. On return, this object @@ -120,7 +120,7 @@ int coap_get_block(coap_pdu_t *pdu, unsigned short type, coap_block_t *block); int coap_write_block_opt(coap_block_t *block, unsigned short type, coap_pdu_t *pdu, size_t data_length); -/** +/** * Adds the @p block_num block of size 1 << (@p block_szx + 4) from * source @p data to @p pdu. * diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h index d4bf9c5..0d7623b 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap.h @@ -34,3 +34,4 @@ extern "C" #endif #endif /* _COAP_H_ */ + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c index ba31c54..f2f4808 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h index 0c1334b..22d8fba 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_list.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_LIST_H_ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h index 041d9a8..a68b5af 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/coap_time.h @@ -3,10 +3,10 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file coap_time.h * @brief Clock Handling */ @@ -113,7 +113,7 @@ extern "C" clock_offset = time(NULL); #else # ifdef __GNUC__ - /* Issue a warning when using gcc. Other prepropressors do + /* Issue a warning when using gcc. Other prepropressors do * not seem to have a similar feature. */ # warning "cannot initialize clock" # endif diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure b/resource/csdk/connectivity/lib/libcoap-4.1.1/configure index b6f5dad..b322ca6 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/configure @@ -5409,3 +5409,4 @@ if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in b/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in index 77f6c8f..86881ab 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/configure.in @@ -96,3 +96,4 @@ AC_CONFIG_FILES([Makefile examples/Makefile tests/Makefile]) AC_OUTPUT + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c index eedf247..cb9a852 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -81,12 +81,12 @@ print_timestamp(char *s, size_t len, coap_tick_t t) #ifndef NDEBUG #ifndef HAVE_STRNLEN -/** - * A length-safe strlen() fake. - * +/** + * A length-safe strlen() fake. + * * @param s The string to count characters != 0. * @param maxlen The maximum length of @p s. - * + * * @return The length of @p s. */ static inline size_t diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h index 708ffc2..4c55054 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/debug.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_DEBUG_H_ @@ -36,7 +36,7 @@ coap_log_t coap_get_log_level(); /** Sets the log level to the specified value. */ void coap_set_log_level(coap_log_t level); -/** +/** * Writes the given text to @c COAP_ERR_FD (for @p level <= @c * LOG_CRIT) or @c COAP_DEBUG_FD (for @p level >= @c LOG_WARNING). The * text is output only when @p level is below or equal to the log @@ -59,6 +59,8 @@ void coap_log_impl(coap_log_t level, const char *format, ...); void coap_show_pdu(const coap_pdu_t *); struct coap_address_t; +unsigned int print_readable(const unsigned char *data, unsigned int len, unsigned char *result, + unsigned int buflen, int encode_always); size_t coap_print_addr(const struct coap_address_t *, unsigned char *, size_t); #else diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c index 9e70ea8..86a5b89 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef NDEBUG diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h index e58cad6..cde69f7 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/encode.h @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_ENCODE_H_ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile index 9f93ca3..8ea7b14 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile @@ -59,3 +59,4 @@ distclean: clean dist: $(FILES) test -d $(DISTDIR)/examples || mkdir $(DISTDIR)/examples cp $(FILES) $(DISTDIR)/examples + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in index 80445ad..a2dfb14 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/Makefile.in @@ -59,3 +59,4 @@ distclean: clean dist: $(FILES) test -d $(DISTDIR)/examples || mkdir $(DISTDIR)/examples cp $(FILES) $(DISTDIR)/examples + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c index 72a0908..89d27ff 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/client.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -284,10 +284,10 @@ get_block(coap_pdu_t *pdu, coap_opt_iterator_t *opt_iter) return coap_option_next(opt_iter); } -#define HANDLE_BLOCK1(Pdu) \ - ((method == COAP_REQUEST_PUT || method == COAP_REQUEST_POST) && \ - ((flags & FLAGS_BLOCK) == 0) && \ - ((Pdu)->hdr->code == COAP_RESPONSE_CODE(201) || \ +#define HANDLE_BLOCK1(Pdu) \ + ((method == COAP_REQUEST_PUT || method == COAP_REQUEST_POST) && \ + ((flags & FLAGS_BLOCK) == 0) && \ + ((Pdu)->hdr->code == COAP_RESPONSE_CODE(201) || \ (Pdu)->hdr->code == COAP_RESPONSE_CODE(204))) inline int check_token(coap_pdu_t *received) @@ -761,7 +761,7 @@ int cmdline_blocksize(char *arg) return 1; } -/* Called after processing the options from the commandline to set +/* Called after processing the options from the commandline to set * Block1 or Block2 depending on method. */ void set_blocksize() { diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c index 83f582e..ba68c0e 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/etsi_iot_01.c @@ -37,7 +37,7 @@ static int quit = 0; #define COAP_OPT_BLOCK_SZX_MAX 6 /**< allowed maximum for block szx value */ -#define REQUIRE_ETAG 0x01 /* flag for coap_payload_t: require ETag option */ +#define REQUIRE_ETAG 0x01 /* flag for coap_payload_t: require ETag option */ typedef struct { UT_hash_handle hh; @@ -76,7 +76,7 @@ void handle_sigint(int signum) } #define INDEX "libcoap server for ETSI CoAP Plugtest, March 2012, Paris\n" \ - "Copyright (C) 2012 Olaf Bergmann \n\n" + "Copyright (C) 2012 Olaf Bergmann \n\n" coap_payload_t * coap_new_payload(size_t size) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c index 0cc97d2..11e01ca 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/rd.c @@ -4,7 +4,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ /** diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c index 0d3e055..09b2fdc 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/server.c @@ -4,7 +4,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -54,7 +54,7 @@ void handle_sigint(int signum) } #define INDEX "This is a test server made with libcoap (see http://libcoap.sf.net)\n" \ - "Copyright (C) 2010--2013 Olaf Bergmann \n\n" + "Copyright (C) 2010--2013 Olaf Bergmann \n\n" void hnd_get_index(coap_context_t *ctx, struct coap_resource_t *resource, coap_address_t *peer, coap_pdu_t *request, str *token, coap_pdu_t *response) diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c index 6c9afe1..6bb89c8 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/examples/tiny.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c index a794292..30447e6 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "hashkey.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h index 4732a70..5ed5e03 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/hashkey.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file hashkey.h * @brief definition of hash key type and helper functions */ @@ -19,12 +19,12 @@ typedef unsigned char coap_key_t[4]; #ifndef coap_hash -/** +/** * Calculates a fast hash over the given string @p s of length @p len * and stores the result into @p h. Depending on the exact * implementation, this function cannot be used as one-way function to * check message integrity or simlar. - * + * * @param s The string used for hash calculation. * @param len The length of @p s. * @param h The result buffer to store the calculated hash key. @@ -40,18 +40,18 @@ void coap_hash_impl(const unsigned char *s, unsigned int len, coap_key_t h); #undef __COAP_DEFAULT_HASH #endif /* coap_hash */ -/** +/** * Calls coap_hash() with given @c str object as parameter. - * + * * @param Str Must contain a pointer to a coap string object. * @param H A coap_key_t object to store the result. - * + * * @hideinitializer */ -#define coap_str_hash(Str,H) { \ - assert(Str); \ - memset((H), 0, sizeof(coap_key_t)); \ - coap_hash((H), (Str)->s, (Str)->length); \ +#define coap_str_hash(Str,H) { \ + assert(Str); \ + memset((H), 0, sizeof(coap_key_t)); \ + coap_hash((H), (Str)->s, (Str)->length); \ } #endif /* _COAP_HASHKEY_H_ */ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h index a84405e..475df6a 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/mem.h @@ -4,7 +4,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_MEM_H_ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c index 7138f4a..9e533df 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -135,8 +135,7 @@ static void received_package(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip context->pending_address.addr = addr->addr; /* FIXME: this has to become address-type independent, probably there'll be an lwip function for that */ context->pending_port = port; - char* data; - coap_read(context, data); + coap_read(context); } #endif /* WITH_LWIP */ @@ -296,7 +295,7 @@ coap_pop_next(coap_context_t *context) #ifdef COAP_DEFAULT_WKC_HASHKEY /** Checks if @p Key is equal to the pre-defined hash key for.well-known/core. */ -#define is_wkc(Key) \ +#define is_wkc(Key) \ (memcmp((Key), COAP_DEFAULT_WKC_HASHKEY, sizeof(coap_key_t)) == 0) #else /* Implements a singleton to store a hash key for the .wellknown/core @@ -583,9 +582,6 @@ coap_send_impl(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu) { - - char* z = inet_ntoa(*(struct in_addr *)&(dst->addr)); - ssize_t bytes_written; coap_tid_t id = COAP_INVALID_TID; @@ -865,7 +861,7 @@ static inline int check_opt_size(coap_opt_t *opt, unsigned char *maxpos) return 0; } -int coap_read(coap_context_t *ctx, char* data) +int coap_read(coap_context_t *ctx) { #ifdef WITH_POSIX static char buf[COAP_MAX_PDU_SIZE]; @@ -1050,7 +1046,7 @@ static inline int token_match(const unsigned char *a, size_t alen, const unsigne void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst, const unsigned char *token, size_t token_length) { - /* cancel all messages in sendqueue that are for dst + /* cancel all messages in sendqueue that are for dst * and use the specified token */ coap_queue_t *p, *q; @@ -1269,7 +1265,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) need_block2 = 1; } - /* Check if there is sufficient space to add Content-Format option + /* Check if there is sufficient space to add Content-Format option * and data. We do this before adding the Content-Format option to * avoid sending error responses with that option but no actual * content. */ @@ -1346,7 +1342,7 @@ wellknown_response(coap_context_t *context, coap_pdu_t *request) return resp; } -#define WANT_WKC(Pdu,Key) \ +#define WANT_WKC(Pdu,Key) \ (((Pdu)->hdr->code == COAP_REQUEST_GET) && is_wkc(Key)) void handle_request(coap_context_t *context, coap_queue_t *node, const char* responseData) @@ -1429,8 +1425,7 @@ void handle_request(coap_context_t *context, coap_queue_t *node, const char* res str token = { node->pdu->hdr->token_length, node->pdu->hdr->token }; - //h(context, resource, &node->remote, - //node->pdu, &token, response); + h(context, resource, &node->remote, node->pdu, &token, response); unsigned char buf[3]; response->hdr->code = COAP_RESPONSE_CODE(205); @@ -1519,7 +1514,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), str token = { 0, NULL }; - /* remove observer for this resource, if any + /* remove observer for this resource, if any * get token from sent and try to find a matching resource. Uh! */ @@ -1547,7 +1542,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), } } #endif /* WITH_CONTIKI */ -#endif /* WITOUT_OBSERVE */ +#endif /* WITOUT_OBSERVE */ } void coap_dispatch(coap_context_t *context, const char* responseData) @@ -1584,7 +1579,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), if (rcvd->pdu->hdr->code == 0) goto cleanup; - /* FIXME: if sent code was >= 64 the message might have been a + /* FIXME: if sent code was >= 64 the message might have been a * notification. Then, we must flag the observer to be alive * by setting obs->fail_cnt = 0. */ if (sent && COAP_RESPONSE_CLASS(sent->pdu->hdr->code) == 2) @@ -1618,7 +1613,7 @@ handle_locally(coap_context_t *context __attribute__ ((unused)), if (coap_option_check_critical(context, rcvd->pdu, opt_filter) == 0) { - /* FIXME: send response only if we have received a request. Otherwise, + /* FIXME: send response only if we have received a request. Otherwise, * send RST. */ response = coap_new_error_response(rcvd->pdu, COAP_RESPONSE_CODE(402), opt_filter); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h index 254b2b4..37057bf 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/net.h @@ -3,7 +3,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_NET_H_ @@ -146,8 +146,8 @@ extern "C" /** * Registers a new message handler that is called whenever a response - * was received that matches an ongoing transaction. - * + * was received that matches an ongoing transaction. + * * @param context The context to register the handler for. * @param handler The response handler to register. */ @@ -157,10 +157,10 @@ extern "C" context->response_handler = handler; } - /** + /** * Registers the option type @p type with the given context object @p * ctx. - * + * * @param ctx The context to use. * @param type The option type to register. */ @@ -185,10 +185,10 @@ extern "C" /** Creates a new coap_context_t object that will hold the CoAP stack status. */ coap_context_t *coap_new_context(const coap_address_t *listen_addr); - /** + /** * Returns a new message id and updates @p context->message_id * accordingly. The message id is returned in network byte order - * to make it easier to read in tracing tools. + * to make it easier to read in tracing tools. * * @param context the current coap_context_t object * @return incremented message id in network byte order @@ -218,7 +218,7 @@ extern "C" coap_tid_t coap_send_confirmed(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu); - /** + /** * Creates a new ACK PDU with specified error @p code. The options * specified by the filter expression @p opts will be copied from the * original request contained in @p request. Unless @c @@ -227,12 +227,12 @@ extern "C" * 0. This function returns a pointer to the new response message, or * @c NULL on error. The storage allocated for the new message must be * relased with coap_free(). - * + * * @param request Specification of the received (confirmable) request. * @param code The error code to set. * @param opts An option filter that specifies which options to copy * from the original request in @p node. - * + * * @return A pointer to the new message or @c NULL on error. */ coap_pdu_t *coap_new_error_response(coap_pdu_t *request, unsigned char code, @@ -249,27 +249,27 @@ extern "C" */ coap_tid_t coap_send(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *pdu); - /** + /** * Sends an error response with code @p code for request @p request to * @p dst. @p opts will be passed to coap_new_error_response() to * copy marked options from the request. This function returns the * transaction id if the message was sent, or @c COAP_INVALID_TID * otherwise. - * + * * @param context The context to use. * @param request The original request to respond to. * @param dst The remote peer that sent the request. * @param code The reponse code. - * @param opts A filter that specifies the options to copy from the + * @param opts A filter that specifies the options to copy from the * @p request. - * + * * @return The transaction id if the message was sent, or @c * COAP_INVALID_TID otherwise. */ coap_tid_t coap_send_error(coap_context_t *context, coap_pdu_t *request, const coap_address_t *dst, unsigned char code, coap_opt_filter_t opts); - /** + /** * Helper funktion to create and send a message with @p type (usually * ACK or RST). This function returns @c COAP_INVALID_TID when the * message was not sent, a valid transaction id otherwise. @@ -283,30 +283,30 @@ extern "C" coap_tid_t coap_send_message_type(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *request, unsigned char type); - /** + /** * Sends an ACK message with code @c 0 for the specified @p request to * @p dst. This function returns the corresponding transaction id if * the message was sent or @c COAP_INVALID_TID on error. - * + * * @param context The context to use. * @param dst The destination address. * @param request The request to be acknowledged. - * + * * @return The transaction id if ACK was sent or @c COAP_INVALID_TID * on error. */ coap_tid_t coap_send_ack(coap_context_t *context, const coap_address_t *dst, coap_pdu_t *request); - /** + /** * Sends an RST message with code @c 0 for the specified @p request to * @p dst. This function returns the corresponding transaction id if * the message was sent or @c COAP_INVALID_TID on error. - * + * * @param context The context to use. * @param dst The destination address. * @param request The request to be reset. - * + * * @return The transaction id if RST was sent or @c COAP_INVALID_TID * on error. */ @@ -324,9 +324,9 @@ extern "C" * and a new node with the parsed PDU is added to the receive queue in the specified context * object. */ - int coap_read(coap_context_t *context, char* data); + int coap_read(coap_context_t *context); - /** + /** * Calculates a unique transaction id from given arguments @p peer and * @p pdu. The id is returned in @p id. * @@ -336,33 +336,33 @@ extern "C" */ void coap_transaction_id(const coap_address_t *peer, const coap_pdu_t *pdu, coap_tid_t *id); - /** + /** * This function removes the element with given @p id from the list * given list. If @p id was found, @p node is updated to point to the - * removed element. Note that the storage allocated by @p node is + * removed element. Note that the storage allocated by @p node is * @b not released. The caller must do this manually using * coap_delete_node(). This function returns @c 1 if the element with * id @p id was found, @c 0 otherwise. For a return value of @c 0, * the contents of @p node is undefined. - * + * * @param queue The queue to search for @p id. * @param id The node id to look for. - * @param node If found, @p node is updated to point to the + * @param node If found, @p node is updated to point to the * removed node. You must release the storage pointed to by * @p node manually. - * + * * @return @c 1 if @p id was found, @c 0 otherwise. */ int coap_remove_from_queue(coap_queue_t **queue, coap_tid_t id, coap_queue_t **node); - /** + /** * Removes the transaction identified by @p id from given @p queue. * This is a convenience function for coap_remove_from_queue() with * automatic deletion of the removed node. - * + * * @param queue The queue to search for @p id. * @param id The transaction id. - * + * * @return @c 1 if node was found, removed and destroyed, @c 0 otherwise. */ inline static int coap_remove_transaction(coap_queue_t **queue, coap_tid_t id) @@ -384,13 +384,13 @@ extern "C" coap_queue_t *coap_find_transaction(coap_queue_t *queue, coap_tid_t id); /** - * Cancels all outstanding messages for peer @p dst that have the + * Cancels all outstanding messages for peer @p dst that have the * specified token. * * @param context The context in use * @param dst Destination address of the messages to remove. * @param token Message token - * @param token_length Actual length of @p token + * @param token_length Actual length of @p token */ void coap_cancel_all_messages(coap_context_t *context, const coap_address_t *dst, const unsigned char *token, size_t token_length); @@ -403,11 +403,11 @@ extern "C" /** * Returns the current value of an internal tick counter. The counter - * counts \c COAP_TICKS_PER_SECOND ticks every second. + * counts \c COAP_TICKS_PER_SECOND ticks every second. */ void coap_ticks(coap_tick_t *); - /** + /** * Verifies that @p pdu contains no unknown critical options. Options * must be registered at @p ctx, using the function * coap_register_option(). A basic set of options is registered @@ -415,7 +415,7 @@ extern "C" * @p pdu is ok, @c 0 otherwise. The given filter object @p unknown * will be updated with the unknown options. As only @c COAP_MAX_OPT * options can be signalled this way, remaining options must be - * examined manually. + * examined manually. * * @code coap_opt_filter_t f = COAP_OPT_NONE; @@ -430,13 +430,13 @@ extern "C" } } } - * @endcode + * @endcode * * @param ctx The context where all known options are registered. * @param pdu The PDU to check. * @param unknown The output filter that will be updated to indicate the * unknown critical options found in @p pdu. - * + * * @return @c 1 if everything was ok, @c 0 otherwise. */ int coap_option_check_critical(coap_context_t *ctx, coap_pdu_t *pdu, coap_opt_filter_t unknown); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c index c8c8496..3255020 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.c @@ -4,7 +4,7 @@ * Copyright (C) 2010-2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -42,12 +42,12 @@ size_t coap_opt_parse(const coap_opt_t *opt, size_t length, coap_option_t *resul assert(opt); assert(result); -#define ADVANCE_OPT(o,e,step) if ((e) < step) { \ - debug("cannot advance opt past end\n"); \ - return 0; \ - } else { \ - (e) -= step; \ - (o) = ((unsigned char *)(o)) + step; \ +#define ADVANCE_OPT(o,e,step) if ((e) < step) { \ + debug("cannot advance opt past end\n"); \ + return 0; \ + } else { \ + (e) -= step; \ + (o) = ((unsigned char *)(o)) + step; \ } if (length < 1) @@ -201,7 +201,7 @@ coap_option_next(coap_opt_iterator_t *oi) /* Exit the while loop when: * - no filtering is done at all * - the filter matches for the current option - * - the filter is too small for the current option number + * - the filter is too small for the current option number */ if (!oi->filtered || (b = coap_option_getb(oi->filter, oi->type)) > 0) break; diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h index 78b2a03..13a97f0 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/option.h @@ -4,7 +4,7 @@ * Copyright (C) 2010-2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ /** @@ -18,7 +18,7 @@ #include "bits.h" #include "pdu.h" -/** +/** * Use byte-oriented access methods here because sliding a complex * struct coap_opt_t over the data buffer may cause bus error on * certain platforms. @@ -39,7 +39,7 @@ typedef struct * function returns the number of bytes that have been parsed, or @c 0 * on error. An error is signaled when illegal delta or length values * are encountered or when option parsing would result in reading past - * the option (i.e. beyond opt + length). + * the option (i.e. beyond opt + length). * * @param opt The beginning of the option to parse. * @param length The maximum length of @p opt. @@ -66,7 +66,7 @@ size_t coap_opt_size(const coap_opt_t *opt); /** * Calculates the beginning of the PDU's option section. - * + * * @param pdu The PDU containing the options. * @return A pointer to the first option if available, or @c NULL otherwise. */ @@ -85,7 +85,7 @@ coap_opt_t *options_start(coap_pdu_t *pdu); * @{ */ -/** +/** * Fixed-size bit-vector we use for option filtering. It is large * enough to hold the highest option number known at build time (20 in * the core spec). @@ -95,9 +95,9 @@ typedef unsigned char coap_opt_filter_t[(COAP_MAX_OPT >> 3) + 1]; /** Pre-defined filter that includes all options. */ #define COAP_OPT_ALL NULL -/** +/** * Clears filter @p f. - * + * * @param f The filter to clear. */ static inline void coap_option_filter_clear(coap_opt_filter_t f) @@ -105,14 +105,14 @@ static inline void coap_option_filter_clear(coap_opt_filter_t f) memset(f, 0, sizeof(coap_opt_filter_t)); } -/** +/** * Sets the corresponding bit for @p type in @p filter. This function * returns @c 1 if bit was set or @c -1 on error (i.e. when the given * type does not fit in the filter). - * + * * @param filter The filter object to change. - * @param type The type for which the bit should be set. - * + * @param type The type for which the bit should be set. + * * @return @c 1 if bit was set, @c -1 otherwise. */ inline static int coap_option_setb(coap_opt_filter_t filter, unsigned short type) @@ -120,14 +120,14 @@ inline static int coap_option_setb(coap_opt_filter_t filter, unsigned short type return bits_setb((uint8_t *) filter, sizeof(coap_opt_filter_t), type); } -/** +/** * Clears the corresponding bit for @p type in @p filter. This function * returns @c 1 if bit was cleared or @c -1 on error (i.e. when the given * type does not fit in the filter). - * + * * @param filter The filter object to change. - * @param type The type for which the bit should be cleared. - * + * @param type The type for which the bit should be cleared. + * * @return @c 1 if bit was set, @c -1 otherwise. */ inline static int coap_option_clrb(coap_opt_filter_t filter, unsigned short type) @@ -135,14 +135,14 @@ inline static int coap_option_clrb(coap_opt_filter_t filter, unsigned short type return bits_clrb((uint8_t *) filter, sizeof(coap_opt_filter_t), type); } -/** +/** * Gets the corresponding bit for @p type in @p filter. This function * returns @c 1 if the bit is set @c 0 if not, or @c -1 on error (i.e. * when the given type does not fit in the filter). - * + * * @param filter The filter object to read bit from.. * @param type The type for which the bit should be read. - * + * * @return @c 1 if bit was set, @c 0 if not, @c -1 on error. */ inline static int coap_option_getb(const coap_opt_filter_t filter, unsigned short type) @@ -150,7 +150,7 @@ inline static int coap_option_getb(const coap_opt_filter_t filter, unsigned shor return bits_getb((uint8_t *) filter, sizeof(coap_opt_filter_t), type); } -/** +/** * Iterator to run through PDU options. This object must be * initialized with coap_option_iterator_init(). Call * coap_option_next() to walk through the list of options until @@ -176,27 +176,27 @@ typedef struct coap_opt_filter_t filter; /**< option filter */ } coap_opt_iterator_t; -/** +/** * Initializes the given option iterator @p oi to point to the * beginning of the @p pdu's option list. This function returns @p oi * on success, @c NULL otherwise (i.e. when no options exist). * Note that a length check on the option list must be performed before * coap_option_iterator_init() is called. - * + * * @param pdu The PDU the options of which should be walked through. * @param oi An iterator object that will be initilized. - * @param filter An optional option type filter. - * With @p type != @c COAP_OPT_ALL, coap_option_next() - * will return only options matching this bitmask. + * @param filter An optional option type filter. + * With @p type != @c COAP_OPT_ALL, coap_option_next() + * will return only options matching this bitmask. * Fence-post options @c 14, @c 28, @c 42, ... are always * skipped. - * + * * @return The iterator object @p oi on success, @c NULL otherwise. */ coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t filter); -/** +/** * Updates the iterator @p oi to point to the next option. This * function returns a pointer to that option or @c NULL if no more * options exist. The contents of @p oi will be updated. In @@ -205,30 +205,30 @@ coap_opt_iterator_t *coap_option_iterator_init(coap_pdu_t *pdu, coap_opt_iterato * oi->option points to the beginning of the current option * itself. When advanced past the last option, @c oi->option will be * @c NULL. - * + * * Note that options are skipped whose corresponding bits in the * filter specified with coap_option_iterator_init() are @c 0. Options * with type codes that do not fit in this filter hence will always be * returned. - * + * * @param oi The option iterator to update. - * + * * @return The next option or @c NULL if no more options exist. */ coap_opt_t *coap_option_next(coap_opt_iterator_t *oi); -/** +/** * Retrieves the first option of type @p type from @p pdu. @p oi must * point to a coap_opt_iterator_t object that will be initialized by * this function to filter only options with code @p type. This * function returns the first option with this type, or @c NULL if not * found. - * + * * @param pdu The PDU to parse for options. * @param type The option type code to search for. * @param oi An iterator object to use. - * - * @return A pointer to the first option of type @p type, or @c NULL + * + * @return A pointer to the first option of type @p type, or @c NULL * if not found. */ coap_opt_t *coap_check_option(coap_pdu_t *pdu, unsigned char type, coap_opt_iterator_t *oi); @@ -281,7 +281,7 @@ unsigned short coap_opt_delta(const coap_opt_t *opt); #define COAP_OPT_DELTA(opt) coap_opt_delta(opt) /** @deprecated { Use coap_opt_encode() instead. } */ -#define COAP_OPT_SETDELTA(opt,val) \ +#define COAP_OPT_SETDELTA(opt,val) \ coap_opt_encode((opt), COAP_MAX_PDU_SIZE, (val), NULL, 0) /** @@ -304,7 +304,7 @@ unsigned short coap_opt_length(const coap_opt_t *opt); /** * Returns a pointer to the value of the given option. @p opt must - * point to an option jump or the beginning of the option. This + * point to an option jump or the beginning of the option. This * function returns @c NULL if @p opt is not a valid option. * * @param opt The option whose value should be returned. diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c index b8aaaad..9a621f1 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -299,7 +299,7 @@ typedef struct char *phrase; } error_desc_t; -/* if you change anything here, make sure, that the longest string does not +/* if you change anything here, make sure, that the longest string does not * exceed COAP_ERROR_PHRASE_LENGTH. */ error_desc_t coap_error[] = { @@ -340,7 +340,7 @@ coap_response_phrase(unsigned char code) #endif /** - * Advances *optp to next option if still in PDU. This function + * Advances *optp to next option if still in PDU. This function * returns the number of bytes opt has been advanced or @c 0 * on error. */ @@ -368,9 +368,6 @@ int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) { coap_opt_t *opt; - char optionResult[256] = - { 0, }; - assert(data); assert(pdu); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h index e01d851..c2dfdf0 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/pdu.h @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _PDU_H_ @@ -95,13 +95,13 @@ #define COAP_RESPONSE_CLASS(C) (((C) >> 5) & 0xFF) #ifndef SHORT_ERROR_RESPONSE -/** +/** * Returns a human-readable response phrase for the specified CoAP * response @p code. This function returns @c NULL if not found. - * + * * @param code The response code for which the literal phrase should * be retrieved. - * + * * @return A zero-terminated string describing the error, or @c NULL * if not found. */ @@ -178,16 +178,16 @@ typedef struct #endif #define COAP_MESSAGE_IS_EMPTY(MSG) ((MSG)->code == 0) -#define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \ - && ((MSG)->code < 32)) +#define COAP_MESSAGE_IS_REQUEST(MSG) (!COAP_MESSAGE_IS_EMPTY(MSG) \ + && ((MSG)->code < 32)) #define COAP_MESSAGE_IS_RESPONSE(MSG) ((MSG)->code >= 64 && (MSG)->code <= 191) -#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list in a - * CoAP message is limited by 0b11110000 marker */ +#define COAP_OPT_LONG 0x0F /* OC == 0b1111 indicates that the option list in a + * CoAP message is limited by 0b11110000 marker */ -#define COAP_OPT_END 0xF0 /* end marker */ +#define COAP_OPT_END 0xF0 /* end marker */ -#define COAP_PAYLOAD_START 0xFF /* payload marker */ +#define COAP_PAYLOAD_START 0xFF /* payload marker */ /** * Structures for more convenient handling of options. (To be used with ordered @@ -245,24 +245,24 @@ typedef struct coap_pdu_t * coap_pdu_from_pbuf(struct pbuf *pbuf); #endif -/** - * Creates a new CoAP PDU of given @p size (must be large enough to hold the +/** + * Creates a new CoAP PDU of given @p size (must be large enough to hold the * basic CoAP message header (coap_hdr_t). The function returns a pointer to * the node coap_pdu_t object on success, or @c NULL on error. The storage * allocated for the result must be released with coap_delete_pdu(). - * + * * @param type The type of the PDU (one of COAP_MESSAGE_CON, - * COAP_MESSAGE_NON, COAP_MESSAGE_ACK, COAP_MESSAGE_RST). + * COAP_MESSAGE_NON, COAP_MESSAGE_ACK, COAP_MESSAGE_RST). * @param code The message code. * @param id The message id to set or COAP_INVALID_TID if unknown. * @param size The number of bytes to allocate for the actual message. - * + * * @return A pointer to the new PDU object or @c NULL on error. */ coap_pdu_t * coap_pdu_init(unsigned char type, unsigned char code, unsigned short id, size_t size); -/** +/** * Clears any contents from @p pdu and resets @c version field, @c * length and @c data pointers. @c max_size is set to @p size, any * other field is set to @c 0. Note that @p pdu must be a valid @@ -273,9 +273,9 @@ void coap_pdu_clear(coap_pdu_t *pdu, size_t size); /** * Creates a new CoAP PDU. The object is created on the heap and must be released * using coap_delete_pdu(); - * + * * @deprecated This function allocates the maximum storage for each - * PDU. Use coap_pdu_init() instead. + * PDU. Use coap_pdu_init() instead. */ coap_pdu_t *coap_new_pdu(); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h index ca86e72..25e7720 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/prng.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file prng.h * @brief Pseudo Random Numbers */ @@ -16,7 +16,7 @@ #include "config.h" -/** +/** * @defgroup prng Pseudo Random Numbers * @{ */ @@ -64,16 +64,16 @@ contiki_prng_impl(unsigned char *buf, size_t len) #endif /* WITH_CONTIKI */ #ifndef prng -/** - * Fills \p Buf with \p Length bytes of random data. - * +/** + * Fills \p Buf with \p Length bytes of random data. + * * @hideinitializer */ #define prng(Buf,Length) coap_prng_impl((Buf), (Length)) #endif #ifndef prng_init -/** +/** * Called to set the PRNG seed. You may want to re-define this to * allow for a better PRNG. * diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c index d6ae50f..624ea4f 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -74,21 +74,21 @@ coap_free_subscription(coap_subscription_t *subscription) * Adds Char to Buf if Offset is zero. Otherwise, Char is not written * and Offset is decremented. */ -#define PRINT_WITH_OFFSET(Buf,Offset,Char) \ - if ((Offset) == 0) { \ - (*(Buf)++) = (Char); \ - } else { \ - (Offset)--; \ - } \ +#define PRINT_WITH_OFFSET(Buf,Offset,Char) \ + if ((Offset) == 0) { \ + (*(Buf)++) = (Char); \ + } else { \ + (Offset)--; \ + } \ /** * Adds Char to Buf if Offset is zero and Buf is less than Bufend. */ -#define PRINT_COND_WITH_OFFSET(Buf,Bufend,Offset,Char,Result) { \ - if ((Buf) < (Bufend)) { \ - PRINT_WITH_OFFSET(Buf,Offset,Char); \ - } \ - (Result)++; \ +#define PRINT_COND_WITH_OFFSET(Buf,Bufend,Offset,Char,Result) { \ + if ((Buf) < (Bufend)) { \ + PRINT_WITH_OFFSET(Buf,Offset,Char); \ + } \ + (Result)++; \ } /** @@ -96,11 +96,11 @@ coap_free_subscription(coap_subscription_t *subscription) * characters are skipped. Output may be truncated to Bufend - Buf * characters. */ -#define COPY_COND_WITH_OFFSET(Buf,Bufend,Offset,Str,Length,Result) { \ - size_t i; \ - for (i = 0; i < (Length); i++) { \ +#define COPY_COND_WITH_OFFSET(Buf,Bufend,Offset,Str,Length,Result) { \ + size_t i; \ + for (i = 0; i < (Length); i++) { \ PRINT_COND_WITH_OFFSET((Buf), (Bufend), (Offset), (Str)[i], (Result)); \ - } \ + } \ } int match(const str *text, const str *pattern, int match_prefix, int match_substring) @@ -144,22 +144,22 @@ int match(const str *text, const str *pattern, int match_prefix, int match_subst && memcmp(text->s, pattern->s, pattern->length) == 0; } -/** +/** * Prints the names of all known resources to @p buf. This function * sets @p buflen to the number of bytes actually written and returns * @c 1 on succes. On error, the value in @p buflen is undefined and * the return value will be @c 0. - * + * * @param context The context with the resource map. * @param buf The buffer to write the result. * @param buflen Must be initialized to the maximum length of @p buf and will be * set to the length of the well-known response on return. * @param offset The offset in bytes where the output shall start and is * shifted accordingly with the characters that have been - * processed. This parameter is used to support the block - * option. + * processed. This parameter is used to support the block + * option. * @param query_filter A filter query according to Link Format - * + * * @return COAP_PRINT_STATUS_ERROR on error. Otherwise, the lower 28 bits are * set to the number of bytes that have actually been written to * @p buf. COAP_PRINT_STATUS_TRUNC is set when the output has been @@ -431,7 +431,7 @@ coap_find_attr(coap_resource_t *resource, const unsigned char *name, size_t nlen for (attr = list_head(resource->link_attr); attr; attr = list_item_next(attr)) { -#endif /* WITH_CONTIKI */ +#endif /* WITH_CONTIKI */ if (attr->name.length == nlen && memcmp(attr->name.s, name, nlen) == 0) return attr; } diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h index 5ed3583..ae3d37a 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/resource.h @@ -3,10 +3,10 @@ * Copyright (C) 2010,2011,2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ -/** +/** * @file resource.h * @brief generic resource handling */ @@ -65,7 +65,7 @@ typedef struct coap_resource_t unsigned int observable :1; /**< can be observed */ unsigned int cacheable :1; /**< can be cached */ - /** + /** * Used to store handlers for the four coap methods @c GET, @c POST, * @c PUT, and @c DELETE. coap_dispatch() will pass incoming * requests to the handler that corresponds to its request method or @@ -98,15 +98,15 @@ typedef struct coap_resource_t } coap_resource_t; -/** +/** * Creates a new resource object and initializes the link field to the * string of length @p len. This function returns the * new coap_resource_t object. - * + * * @param uri The URI path of the new resource. * @param len The length of @p uri. * @param flags Flags for memory management (in particular release of memory) - * + * * @return A pointer to the new object or @c NULL on error. */ coap_resource_t *coap_resource_init(const unsigned char *uri, size_t len, int flags); @@ -115,29 +115,29 @@ coap_resource_t *coap_resource_init(const unsigned char *uri, size_t len, int fl * Registers the given @p resource for @p context. The resource must * have been created by coap_resource_init(), the storage allocated * for the resource will be released by coap_delete_resource(). - * + * * @param context The context to use. * @param resource The resource to store. */ void coap_add_resource(coap_context_t *context, coap_resource_t *resource); -/** +/** * Deletes a resource identified by @p key. The storage allocated for * that resource is freed. - * + * * @param context The context where the resources are stored. * @param key The unique key for the resource to delete. - * + * * @return @c 1 if the resource was found (and destroyed), @c 0 otherwise. */ int coap_delete_resource(coap_context_t *context, coap_key_t key); -/** +/** * Registers a new attribute with the given @p resource. As the - * attributes str fields will point to @p name and @p val the + * attributes str fields will point to @p name and @p val the * caller must ensure that these pointers are valid during the * attribute's lifetime. - * + * * @param resource The resource to register the attribute with. * @param name The attribute's name. * @param nlen Length of @p name. @@ -162,11 +162,11 @@ coap_attr_t *coap_add_attr(coap_resource_t *resource, const unsigned char *name, */ coap_attr_t *coap_find_attr(coap_resource_t *resource, const unsigned char *name, size_t nlen); -/** +/** * Deletes an attribute - * + * * @param attr Pointer to a previously created attribute - * + * */ void coap_delete_attr(coap_attr_t *attr); @@ -187,22 +187,22 @@ typedef unsigned int coap_print_status_t; #define COAP_PRINT_STATUS_ERROR 0x80000000u #define COAP_PRINT_STATUS_TRUNC 0x40000000u -/** +/** * Writes a description of this resource in link-format to given text * buffer. @p len must be initialized to the maximum length of @p buf * and will be set to the number of characters actually written if * successful. This function returns @c 1 on success or @c 0 on * error. - * + * * @param resource The resource to describe. * @param buf The output buffer to write the description to. - * @param len Must be initialized to the length of @p buf and + * @param len Must be initialized to the length of @p buf and * will be set to the length of the printed link description. * @param offset The offset within the resource description where to * start writing into @p buf. This is useful for dealing * with the Block2 option. @p offset is updated during * output as it is consumed. - * + * * @return If COAP_PRINT_STATUS_ERROR is set, an error occured. Otherwise, * the lower 28 bits will indicate the number of characters that * have actually been output into @p buffer. The flag @@ -212,12 +212,12 @@ typedef unsigned int coap_print_status_t; coap_print_status_t coap_print_link(const coap_resource_t *resource, unsigned char *buf, size_t *len, size_t *offset); -/** +/** * Registers the specified @p handler as message handler for the request type * @p method - * + * * @param resource The resource for which the handler shall be registered. - * @param method The CoAP request method to handle. + * @param method The CoAP request method to handle. * @param handler The handler to register with @p resource. */ static inline void coap_register_handler(coap_resource_t *resource, unsigned char method, @@ -231,28 +231,28 @@ static inline void coap_register_handler(coap_resource_t *resource, unsigned cha resource->handler[method - 1] = handler; } -/** +/** * Returns the resource identified by the unique string @p key. If no * resource was found, this function returns @c NULL. - * + * * @param context The context to look for this resource. * @param key The unique key of the resource. - * + * * @return A pointer to the resource or @c NULL if not found. */ coap_resource_t *coap_get_resource_from_key(coap_context_t *context, coap_key_t key); -/** +/** * Calculates the hash key for the resource requested by the * Uri-Options of @p request. This function calls coap_hash() for * every path segment. - * + * * @param request The requesting pdu. * @param key The resulting hash is stored in @p key */ void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key); -/** +/** * @addtogroup observe */ @@ -267,7 +267,7 @@ void coap_hash_request_uri(const coap_pdu_t *request, coap_key_t key); * @param token The token that identifies this subscription. * @param token_length The actual length of @p token. Must be @c 0 when * @p token is @c NULL. - * @return A pointer to the added/updated subscription information or + * @return A pointer to the added/updated subscription information or * @c NULL on error. */ coap_subscription_t *coap_add_observer(coap_resource_t *resource, const coap_address_t *observer, @@ -290,7 +290,7 @@ coap_subscription_t *coap_find_observer(coap_resource_t *resource, const coap_ad * * @param context The CoAP context to use * @param observer The transport address of the observer - * @param token The corresponding token that has been used for + * @param token The corresponding token that has been used for * the subscription */ void coap_touch_observer(coap_context_t *context, const coap_address_t *observer, const str *token); @@ -307,7 +307,7 @@ void coap_touch_observer(coap_context_t *context, const coap_address_t *observer void coap_delete_observer(coap_resource_t *resource, const coap_address_t *observer, const str *token); -/** +/** * Checks for all known resources, if they are dirty and notifies * subscribed observers. */ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c index 8b275e3..82a5696 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.c @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h index 6405298..0a96686 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/str.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_STR_H_ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c index 295f5c5..e5c3d24 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.c @@ -4,7 +4,7 @@ * Copyright (C) 2010--2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h index 7b7dc05..eb76151 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/subscribe.h @@ -4,7 +4,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_SUBSCRIBE_H_ @@ -13,7 +13,7 @@ #include "config.h" #include "address.h" -/** +/** * @defgroup observe Resource observation * @{ */ diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h index 47653d1..5f25f96 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/t_list.h @@ -82,13 +82,13 @@ struct list #define LIST_CONCAT(s1, s2) s1##s2 -#define LIST_STRUCT(name) \ - void *LIST_CONCAT(name, _list); \ +#define LIST_STRUCT(name) \ + void *LIST_CONCAT(name, _list); \ list_t name -#define LIST_STRUCT_INIT(struct_ptr, name) { \ - (struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \ - (struct_ptr)->LIST_CONCAT(name,_list) = NULL; \ +#define LIST_STRUCT_INIT(struct_ptr, name) { \ + (struct_ptr)->name = &((struct_ptr)->LIST_CONCAT(name,_list)); \ + (struct_ptr)->LIST_CONCAT(name,_list) = NULL; \ } static inline void * diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile index 6397552..1c11937 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile @@ -55,3 +55,4 @@ distclean: clean dist: $(FILES) test -d $(DISTDIR)/tests || mkdir $(DISTDIR)/tests cp $(FILES) $(DISTDIR)/tests + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in index 95da5c0..f065c1e 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/Makefile.in @@ -55,3 +55,4 @@ distclean: clean dist: $(FILES) test -d $(DISTDIR)/tests || mkdir $(DISTDIR)/tests cp $(FILES) $(DISTDIR)/tests + diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c index fad0941..69c62bd 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.c @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -310,10 +310,10 @@ CU_pSuite t_init_error_response_tests(void) return NULL; } -#define ERROR_RESPONSE_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ +#define ERROR_RESPONSE_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ fprintf(stderr, "W: cannot add error response generator test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } ERROR_RESPONSE_TEST(suite[0], t_error_response1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h index 2bab63c..5ae3cea 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_error_response.h @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c index de5b3a6..27c12ad 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.c @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -756,10 +756,10 @@ CU_pSuite t_init_option_tests(void) return NULL; } -#define OPTION_TEST(n,s) \ - if (!CU_add_test(suite[0], s, t_parse_option##n)) { \ - fprintf(stderr, "W: cannot add option parser test (%s)\n", \ - CU_get_error_msg()); \ +#define OPTION_TEST(n,s) \ + if (!CU_add_test(suite[0], s, t_parse_option##n)) { \ + fprintf(stderr, "W: cannot add option parser test (%s)\n", \ + CU_get_error_msg()); \ } OPTION_TEST(1, "parse option #1"); @@ -779,10 +779,10 @@ CU_pSuite t_init_option_tests(void) if ((suite[1] = CU_add_suite("option encoder", NULL, NULL))) { -#define OPTION_ENCODER_TEST(n,s) \ - if (!CU_add_test(suite[1], s, t_encode_option##n)) { \ +#define OPTION_ENCODER_TEST(n,s) \ + if (!CU_add_test(suite[1], s, t_encode_option##n)) { \ fprintf(stderr, "W: cannot add option encoder test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } OPTION_ENCODER_TEST(1, "encode option #1"); @@ -802,10 +802,10 @@ CU_pSuite t_init_option_tests(void) if ((suite[2] = CU_add_suite("option accessors", NULL, NULL))) { -#define OPTION_ACCESSOR_TEST(n,s) \ - if (!CU_add_test(suite[2], s, t_access_option##n)) { \ +#define OPTION_ACCESSOR_TEST(n,s) \ + if (!CU_add_test(suite[2], s, t_access_option##n)) { \ fprintf(stderr, "W: cannot add option accessor function test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } OPTION_ACCESSOR_TEST(1, "access option #1"); @@ -825,10 +825,10 @@ CU_pSuite t_init_option_tests(void) if ((suite[3] = CU_add_suite("option iterator", NULL, NULL))) { -#define OPTION_ITERATOR_TEST(n,s) \ - if (!CU_add_test(suite[3], s, t_iterate_option##n)) { \ +#define OPTION_ITERATOR_TEST(n,s) \ + if (!CU_add_test(suite[3], s, t_iterate_option##n)) { \ fprintf(stderr, "W: cannot add option iterator test (%s)\n", \ - CU_get_error_msg()); \ + CU_get_error_msg()); \ } OPTION_ITERATOR_TEST(1, "option iterator #1"); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h index 3ffcefe..8c2be65 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_options.h @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c index 2592a32..8d004d8 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.c @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -609,10 +609,10 @@ CU_pSuite t_init_pdu_tests(void) return NULL; } -#define PDU_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add pdu parser test (%s)\n", \ - CU_get_error_msg()); \ +#define PDU_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add pdu parser test (%s)\n", \ + CU_get_error_msg()); \ } PDU_TEST(suite[0], t_parse_pdu1); @@ -633,10 +633,10 @@ CU_pSuite t_init_pdu_tests(void) suite[1] = CU_add_suite("pdu encoder", t_pdu_tests_create, t_pdu_tests_remove); if (suite[1]) { -#define PDU_ENCODER_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add pdu encoder test (%s)\n", \ - CU_get_error_msg()); \ +#define PDU_ENCODER_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add pdu encoder test (%s)\n", \ + CU_get_error_msg()); \ } PDU_ENCODER_TEST(suite[1], t_encode_pdu1); PDU_ENCODER_TEST(suite[1], t_encode_pdu2); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h index 992b377..a052240 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_pdu.h @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c index 1b6c076..5207039 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.c @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -291,7 +291,7 @@ void t_sendqueue10(void) /* This function creates a set of nodes for testing. These nodes * will exist for all tests and are modified by coap_insert_node() - * and + * and */ int t_sendqueue_tests_create(void) { @@ -357,10 +357,10 @@ CU_pSuite t_init_sendqueue_tests(void) return NULL; } -#define SENDQUEUE_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add sendqueue test (%s)\n", \ - CU_get_error_msg()); \ +#define SENDQUEUE_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add sendqueue test (%s)\n", \ + CU_get_error_msg()); \ } SENDQUEUE_TEST(suite, t_sendqueue1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h index 56f3c1e..694072b 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_sendqueue.h @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c index d5dafc5..04a3d14 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.c @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -371,10 +371,10 @@ CU_pSuite t_init_uri_tests(void) return NULL; } -#define URI_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add uri parser test (%s)\n", \ - CU_get_error_msg()); \ +#define URI_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add uri parser test (%s)\n", \ + CU_get_error_msg()); \ } URI_TEST(suite, t_parse_uri1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h index 165fad3..ca96090 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_uri.h @@ -3,7 +3,7 @@ * Copyright (C) 2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c index 97584d8..843e249 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.c @@ -3,7 +3,7 @@ * Copyright (C) 2013--2014 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include @@ -296,7 +296,7 @@ int t_wkc_tests_create(void) } } -#endif +#endif return ctx == NULL || pdu == NULL; } @@ -319,10 +319,10 @@ CU_pSuite t_init_wellknown_tests(void) return NULL; } -#define WKC_TEST(s,t) \ - if (!CU_ADD_TEST(s,t)) { \ - fprintf(stderr, "W: cannot add .well-known/core test (%s)\n", \ - CU_get_error_msg()); \ +#define WKC_TEST(s,t) \ + if (!CU_ADD_TEST(s,t)) { \ + fprintf(stderr, "W: cannot add .well-known/core test (%s)\n", \ + CU_get_error_msg()); \ } WKC_TEST(suite, t_wellknown1); diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h index 47f20b3..8ba1d6d 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/tests/test_wellknown.h @@ -3,7 +3,7 @@ * Copyright (C) 2013 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c index 1b78686..8018520 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.c @@ -3,7 +3,7 @@ * Copyright (C) 2010--2012 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #include "config.h" @@ -22,15 +22,15 @@ #include "option.h" #include "uri.h" -/** +/** * A length-safe version of strchr(). This function returns a pointer * to the first occurrence of @p c in @p s, or @c NULL if not found. - * + * * @param s The string to search for @p c. * @param len The length of @p s. * @param c The character to search. - * - * @return A pointer to the first occurence of @p c, or @c NULL + * + * @return A pointer to the first occurence of @p c, or @c NULL * if not found. */ static inline unsigned char * @@ -125,7 +125,7 @@ int coap_split_uri(unsigned char *str_var, size_t len, coap_uri_t *uri) { /* IPv4 address or FQDN */ while (len && *q != ':' && *q != '/' && *q != '?') { - // *q = tolower(*q); + *q = tolower(*q); ++q; --len; @@ -201,23 +201,23 @@ int coap_split_uri(unsigned char *str_var, size_t len, coap_uri_t *uri) error: return res; } -/** +/** * Calculates decimal value from hexadecimal ASCII character given in * @p c. The caller must ensure that @p c actually represents a valid - * heaxdecimal character, e.g. with isxdigit(3). + * heaxdecimal character, e.g. with isxdigit(3). * * @hideinitializer */ #define hexchar_to_dec(c) ((c) & 0x40 ? ((c) & 0x0F) + 9 : ((c) & 0x0F)) -/** +/** * Decodes percent-encoded characters while copying the string @p seg * of size @p length to @p buf. The caller of this function must * ensure that the percent-encodings are correct (i.e. the character * '%' is always followed by two hex digits. and that @p buf provides * sufficient space to hold the result. This function is supposed to * be called by make_decoded_option() only. - * + * * @param seg The segment to decode and copy. * @param length Length of @p seg. * @param buf The result buffer. @@ -274,7 +274,7 @@ int check_segment(const unsigned char *s, size_t length) return n; } -/** +/** * Writes a coap option from given string @p s to @p buf. @p s should * point to a (percent-encoded) path or query segment of a coap_uri_t * object. The created option will have type @c 0, and the length @@ -282,12 +282,12 @@ int check_segment(const unsigned char *s, size_t length) * On success, this function returns the option's size, or a value * less than zero on error. This function must be called from * coap_split_path_impl() only. - * + * * @param s The string to decode. * @param length The size of the percent-encoded string @p s. * @param buf The buffer to store the new coap option. * @param buflen The maximum size of @p buf. - * + * * @return The option's size, or @c -1 on error. * * @bug This function does not split segments that are bigger than 270 @@ -336,14 +336,14 @@ int make_decoded_option(const unsigned char *s, size_t length, unsigned char *bu typedef void (*segment_handler_t)(unsigned char *, size_t, void *); -/** +/** * Splits the given string into segments. You should call one of the * macros coap_split_path() or coap_split_query() instead. - * + * * @param parse_iter The iterator used for tokenizing. * @param h A handler that is called with every token. * @param data Opaque data that is passed to @p h when called. - * + * * @return The number of characters that have been parsed from @p s. */ size_t coap_split_path_impl(coap_parse_iterator_t *parse_iter, segment_handler_t h, void *data) @@ -379,7 +379,7 @@ void write_option(unsigned char *s, size_t len, void *data) assert(state); /* skip empty segments and those that consist of only one or two dots */ - if (memcmp(s, "..", min(len,2)) == 0) + if (memcmp(s, "..", min(len, 2)) == 0) return; res = make_decoded_option(s, len, state->buf.s, state->buf.length); @@ -451,8 +451,8 @@ coap_clone_uri(const coap_uri_t *uri) if (!uri) return NULL; - result = (coap_uri_t *) coap_malloc( uri->query.length + uri->host.length + - uri->path.length + sizeof(coap_uri_t) + 1); + result = (coap_uri_t *) coap_malloc( + uri->query.length + uri->host.length + uri->path.length + sizeof(coap_uri_t) + 1); if (!result) return NULL; diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h index 20dd28e..820a045 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/uri.h @@ -3,7 +3,7 @@ * Copyright (C) 2010,2011 Olaf Bergmann * * This file is part of the CoAP library libcoap. Please see - * README for terms of use. + * README for terms of use. */ #ifndef _COAP_URI_H_ @@ -19,7 +19,7 @@ typedef struct { str host; /**< host part of the URI */ unsigned short port; /**< The port in host byte order */ - str path; /**< Beginning of the first path segment. + str path; /**< Beginning of the first path segment. Use coap_split_path() to create Uri-Path options */ str query; /**< The query part if present */ } coap_uri_t; @@ -41,14 +41,14 @@ coap_uri_t *coap_new_uri(const unsigned char *uri, unsigned int length); * be released with coap_free(). */ coap_uri_t *coap_clone_uri(const coap_uri_t *uri); -/** - * Calculates a hash over the given path and stores the result in +/** + * Calculates a hash over the given path and stores the result in * @p key. This function returns @c 0 on error or @c 1 on success. - * + * * @param path The URI path to generate hash for. * @param len The length of @p path. * @param key The output buffer. - * + * * @return @c 1 if @p key was set, @c 0 otherwise. */ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key); @@ -61,7 +61,7 @@ int coap_hash_path(const unsigned char *path, size_t len, coap_key_t key); * @{ */ -/** +/** * Iterator to for tokenizing a URI path or query. This structure must * be initialized with coap_parse_iterator_init(). Call * coap_parse_next() to walk through the tokens. @@ -86,43 +86,43 @@ typedef struct size_t segment_length; /**< length of current segment */ } coap_parse_iterator_t; -/** - * Initializes the given iterator @p pi. - * +/** + * Initializes the given iterator @p pi. + * * @param s The string to tokenize. * @param n The length of @p s. * @param separator The separator character that delimits tokens. * @param delim A set of characters that delimit @s. * @param dlen The length of @p delim. * @param pi The iterator object to initialize. - * + * * @return The initialized iterator object @p pi. */ coap_parse_iterator_t * coap_parse_iterator_init(unsigned char *s, size_t n, unsigned char separator, unsigned char *delim, size_t dlen, coap_parse_iterator_t *pi); -/** +/** * Updates the iterator @p pi to point to the next token. This * function returns a pointer to that token or @c NULL if no more * tokens exist. The contents of @p pi will be updated. In particular, * @c pi->segment_length specifies the length of the current token, @c * pi->pos points to its beginning. - * + * * @param pi The iterator to update. - * + * * @return The next token or @c NULL if no more tokens exist. */ unsigned char *coap_parse_next(coap_parse_iterator_t *pi); -/** +/** * Parses a given string into URI components. The identified syntactic * components are stored in the result parameter @p uri. Optional URI * components that are not specified will be set to { 0, 0 }, except * for the port which is set to @c COAP_DEFAULT_PORT. This function * returns @p 0 if parsing succeeded, a value less than zero * otherwise. - * + * * @param str_var The string to split up. * @param len The actual length of @p str_var * @param uri The coap_uri_t object to store the result. @@ -134,32 +134,32 @@ unsigned char *coap_parse_next(coap_parse_iterator_t *pi); int coap_split_uri(unsigned char *str_var, size_t len, coap_uri_t *uri); -/** +/** * Splits the given URI path into segments. Each segment is preceded * by an option pseudo-header with delta-value 0 and the actual length * of the respective segment after percent-decoding. - * - * @param s The path string to split. + * + * @param s The path string to split. * @param length The actual length of @p s. - * @param buf Result buffer for parsed segments. + * @param buf Result buffer for parsed segments. * @param buflen Maximum length of @p buf. Will be set to the actual number * of bytes written into buf on success. - * + * * @return The number of segments created or @c -1 on error. */ int coap_split_path(const unsigned char *s, size_t length, unsigned char *buf, size_t *buflen); -/** +/** * Splits the given URI query into segments. Each segment is preceded * by an option pseudo-header with delta-value 0 and the actual length * of the respective query term. - * - * @param s The query string to split. + * + * @param s The query string to split. * @param length The actual length of @p s. - * @param buf Result buffer for parsed segments. + * @param buf Result buffer for parsed segments. * @param buflen Maximum length of @p buf. Will be set to the actual number * of bytes written into buf on success. - * + * * @return The number of segments created or @c -1 on error. * * @bug This function does not reserve additional space for delta > 12. diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h index 21e8141..be8f2bd 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/uthash.h @@ -22,7 +22,7 @@ */ #ifndef UTHASH_H -#define UTHASH_H +#define UTHASH_H #include /* memcmp,strlen */ #include /* ptrdiff_t */ @@ -48,7 +48,7 @@ do { char **_da_dst = (char**)(&(dst)); \ *_da_dst = (char*)(src); \ } while(0) -#else +#else #define DECLTYPE_ASSIGN(dst,src) \ do { \ (dst) = DECLTYPE(dst)(src); \ @@ -121,9 +121,9 @@ do { HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) #else -#define HASH_BLOOM_MAKE(tbl) -#define HASH_BLOOM_FREE(tbl) -#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) #define HASH_BLOOM_TEST(tbl,hashv) (1) #endif @@ -299,10 +299,10 @@ do { } \ } while (0) #else -#define HASH_FSCK(hh,head) +#define HASH_FSCK(hh,head) #endif -/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to * the descriptor to which this macro is defined for tuning the hash function. * The app can #include to get the prototype for write(2). */ #ifdef HASH_EMIT_KEYS @@ -312,12 +312,12 @@ do { write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ write(HASH_EMIT_KEYS, keyptr, fieldlen); \ } while (0) -#else -#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) #endif /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ -#ifdef HASH_FUNCTION +#ifdef HASH_FUNCTION #define HASH_FCN HASH_FUNCTION #else #define HASH_FCN HASH_JEN @@ -333,7 +333,7 @@ do { bkt = (hashv) & (num_bkts-1); \ } while (0) -/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ #define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ do { \ @@ -484,14 +484,14 @@ do { /* The MurmurHash exploits some CPU's (e.g. x86) tolerance for unaligned reads. * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. * So MurmurHash comes in two versions, the faster unaligned one and the slower - * aligned one. We only use the faster one on CPU's where we know it's safe. + * aligned one. We only use the faster one on CPU's where we know it's safe. * * Note the preprocessor built-in defines can be emitted using: * * gcc -m64 -dM -E - < /dev/null (on gcc) * cc -## a.c (where a.c is a simple test file) (Sun Studio) */ -#if (defined(__i386__) || defined(__x86_64__)) +#if (defined(__i386__) || defined(__x86_64__)) #define HASH_MUR HASH_MUR_UNALIGNED #else #define HASH_MUR HASH_MUR_ALIGNED @@ -630,7 +630,7 @@ do { #endif /* HASH_USING_NO_STRICT_ALIASING */ /* key comparison function; return 0 if keys equal */ -#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) /* iterate over items in a known bucket to find desired item */ #define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ @@ -671,36 +671,36 @@ do { } \ if (hh_del->hh_next) { \ hh_del->hh_next->hh_prev = hh_del->hh_prev; \ - } + } /* Bucket expansion has the effect of doubling the number of buckets * and redistributing the items into the new buckets. Ideally the * items will distribute more or less evenly into the new buckets * (the extent to which this is true is a measure of the quality of - * the hash function as it applies to the key domain). - * + * the hash function as it applies to the key domain). + * * With the items distributed into more buckets, the chain length * (item count) in each bucket is reduced. Thus by expanding buckets - * the hash keeps a bound on the chain length. This bounded chain + * the hash keeps a bound on the chain length. This bounded chain * length is the essence of how a hash provides constant time lookup. - * + * * The calculation of tbl->ideal_chain_maxlen below deserves some * explanation. First, keep in mind that we're calculating the ideal * maximum chain length based on the *new* (doubled) bucket count. * In fractions this is just n/b (n=number of items,b=new num buckets). - * Since the ideal chain length is an integer, we want to calculate + * Since the ideal chain length is an integer, we want to calculate * ceil(n/b). We don't depend on floating point arithmetic in this * hash, so to calculate ceil(n/b) with integers we could write - * + * * ceil(n/b) = (n/b) + ((n%b)?1:0) - * + * * and in fact a previous version of this hash did just that. * But now we have improved things a bit by recognizing that b is * always a power of two. We keep its base 2 log handy (call it lb), * so now we can write this with a bit shift and logical AND: - * + * * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) - * + * */ #define HASH_EXPAND_BUCKETS(tbl) \ do { \ @@ -751,7 +751,7 @@ do { } while(0) /* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ -/* Note that HASH_SORT assumes the hash handle name to be hh. +/* Note that HASH_SORT assumes the hash handle name to be hh. * HASH_SRT was added to allow the hash handle name to be passed in. */ #define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) #define HASH_SRT(hh,head,cmpfcn) \ @@ -833,10 +833,10 @@ do { } \ } while (0) -/* This function selects items from one hash into another hash. - * The end result is that the selected items have dual presence - * in both hashes. There is no copy of the items made; rather - * they are added into the new hash through a secondary hash +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash * hash handle that must be present in the structure. */ #define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ do { \ @@ -889,7 +889,7 @@ do { #ifdef NO_DECLTYPE #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ - el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) #else #define HASH_ITER(hh,head,el,tmp) \ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ @@ -897,7 +897,7 @@ for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); #endif /* obtain a count of items in the hash */ -#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_COUNT(head) HASH_CNT(hh,head) #define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) typedef struct UT_hash_bucket @@ -907,7 +907,7 @@ typedef struct UT_hash_bucket /* expand_mult is normally set to 0. In this situation, the max chain length * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If - * the bucket's chain exceeds this length, bucket expansion is triggered). + * the bucket's chain exceeds this length, bucket expansion is triggered). * However, setting expand_mult to a non-zero value delays bucket expansion * (that would be triggered by additions to this particular bucket) * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. @@ -915,7 +915,7 @@ typedef struct UT_hash_bucket * multiplier is to reduce bucket expansions, since they are expensive, in * situations where we know that a particular bucket tends to be overused. * It is better to let its chain length grow to a longer yet-still-bounded - * value, than to do an O(n) bucket expansion too often. + * value, than to do an O(n) bucket expansion too often. */ unsigned expand_mult; @@ -942,7 +942,7 @@ typedef struct UT_hash_table * hash distribution; reaching them in a chain traversal takes >ideal steps */ unsigned nonideal_items; - /* ineffective expands occur when a bucket doubling was performed, but + /* ineffective expands occur when a bucket doubling was performed, but * afterward, more than half the items in the hash had nonideal chain * positions. If this happens on two consecutive expansions we inhibit any * further expansion, as it's not helping; this happens when the hash diff --git a/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h b/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h index 4073e04..a1c739c 100644 --- a/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h +++ b/resource/csdk/connectivity/lib/libcoap-4.1.1/utlist.h @@ -26,7 +26,7 @@ #define UTLIST_VERSION 1.9.1 -/* +/* * This file contains macros to manipulate singly and doubly-linked lists. * * 1. LL_ macros: singly-linked lists. @@ -36,7 +36,7 @@ * To use singly-linked lists, your structure must have a "next" pointer. * To use doubly-linked lists, your structure must "prev" and "next" pointers. * Either way, the pointer to the head of the list must be initialized to NULL. - * + * * ----------------.EXAMPLE ------------------------- * struct item { * int id; @@ -83,7 +83,7 @@ #define _PREVASGN(elt,list,to) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } -#else +#else #define _SV(elt,list) #define _NEXT(elt,list) ((elt)->next) #define _NEXTASGN(elt,list,to) ((elt)->next)=(to) @@ -369,14 +369,14 @@ do { LL_FOREACH(head,out) { \ if ((out)->field == (val)) break; \ } \ -} while(0) +} while(0) #define LL_SEARCH(head,out,elt,cmp) \ do { \ LL_FOREACH(head,out) { \ if ((cmp(out,elt))==0) break; \ } \ -} while(0) +} while(0) /****************************************************************************** * doubly linked list macros (non-circular) * @@ -464,7 +464,7 @@ do { } while (0); #define CDL_FOREACH(head,el) \ - for(el=head;el;el=(el->next==head ? 0L : el->next)) + for(el=head;el;el=(el->next==head ? 0L : el->next)) #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ @@ -476,14 +476,14 @@ do { CDL_FOREACH(head,out) { \ if ((out)->field == (val)) break; \ } \ -} while(0) +} while(0) #define CDL_SEARCH(head,out,elt,cmp) \ do { \ CDL_FOREACH(head,out) { \ if ((cmp(out,elt))==0) break; \ } \ -} while(0) +} while(0) #endif /* UTLIST_H */ diff --git a/resource/csdk/connectivity/samples/linux/sample.sh b/resource/csdk/connectivity/samples/linux/sample.sh index 3d85b40..7bb9135 100644 --- a/resource/csdk/connectivity/samples/linux/sample.sh +++ b/resource/csdk/connectivity/samples/linux/sample.sh @@ -22,11 +22,10 @@ cd ../../lib/libcoap-4.1.1 make clean make -cd ../../build/linux +cd ../../build/linux make clean make - cd ../../samples/linux make clean make diff --git a/resource/csdk/connectivity/samples/linux/sample_main.c b/resource/csdk/connectivity/samples/linux/sample_main.c index 17992e2..0af36f2 100644 --- a/resource/csdk/connectivity/samples/linux/sample_main.c +++ b/resource/csdk/connectivity/samples/linux/sample_main.c @@ -25,6 +25,7 @@ #include "cainterface.h" #define MAX_BUF_LEN 1024 +#define MAX_OPT_LEN 16 char get_menu(); void process(); @@ -35,12 +36,13 @@ void find_resource(); void send_request(); void send_response(); void advertise_resource(); +void send_notification(); void select_network(); void unselect_network(); void handle_request_response(); -void request_handler(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo); -void response_handler(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo); +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 main() @@ -85,12 +87,12 @@ void process() printf("quit..!!\n"); return; - case 's': // start listening server + case 's': // start server case 'S': start_listening_server(); break; - case 'd': // start discovery server + case 'c': // start client case 'D': start_discovery_server(); break; @@ -110,6 +112,11 @@ void process() advertise_resource(); break; + case 'b': // send notification + case 'B': + send_notification(); + break; + case 'n': // select network case 'N': select_network(); @@ -142,7 +149,7 @@ void start_listening_server() void start_discovery_server() { - printf("start discovery server!!\n"); + printf("start discovery client!!\n"); CAStartDiscoveryServer(); } @@ -167,7 +174,7 @@ void find_resource() } else { - printf("find resource fo %s URI\n", buf); + printf("find resource to %s URI\n", buf); } printf("=============================================\n"); @@ -180,8 +187,8 @@ void send_request() memset(buf, 0, sizeof(char) * MAX_BUF_LEN); printf("\n=============================================\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"); + 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 : "); gets(buf); @@ -189,11 +196,11 @@ void send_request() // create remote endpoint CARemoteEndpoint_t* endpoint = NULL; CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint); - endpoint->connectivityType = CA_WIFI; // if (res != CA_STATUS_OK) { printf("create remote endpoint error!!"); + CADestroyRemoteEndpoint(endpoint); return; } @@ -238,11 +245,96 @@ void send_request() void advertise_resource() { + char buf[MAX_BUF_LEN]; + + memset(buf, 0, sizeof(char) * MAX_BUF_LEN); + printf("\n=============================================\n"); + printf("uri : "); - printf("not implemented yet.\n"); + scanf("%s", buf); + + int optionNum = 0; + char optionData[MAX_OPT_LEN]; + + printf("Option Num : "); + scanf("%d", &optionNum); + CAHeaderOption_t *headerOpt; + headerOpt = (CAHeaderOption_t*) malloc(sizeof(CAHeaderOption_t) * optionNum); + if (NULL == headerOpt) + { + printf("Memory allocation failed!\n"); + return; + } + memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum); + + int i; + for(i = 0 ; i < optionNum ; i++) + { + int optionID = 0; + printf("[%d] Option ID : ", i + 1); + scanf("%d", &optionID); + headerOpt[i].optionID = optionID; + + memset(optionData, 0, sizeof(char) * MAX_OPT_LEN); + printf("[%d] Option Data : ", i + 1); + scanf("%s", optionData); + memcpy(headerOpt[i].optionData, optionData, strlen(optionData)); + printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData ); + + headerOpt[i].optionLength = (uint16_t)strlen(optionData); + } + printf("\n=============================================\n"); + + CAAdvertiseResource(buf, headerOpt, (uint8_t)optionNum); + + free(headerOpt); - printf("=============================================\n"); +} + +void send_notification() +{ + 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 : "); + + gets(buf); + + // create remote endpoint + CARemoteEndpoint_t* endpoint = NULL; + CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint); + + if (res != CA_STATUS_OK) + { + printf("create remote endpoint error!!"); + CADestroyRemoteEndpoint(endpoint); + return; + } + + CAInfo_t respondeData; + memset(&respondeData, 0, sizeof(CAInfo_t)); + respondeData.token = "client token"; + respondeData.payload = "Temp Notification Data"; + + CAResponseInfo_t responseInfo; + memset(&responseInfo, 0, sizeof(CAResponseInfo_t)); + responseInfo.result = CA_CONTENT; + responseInfo.info = respondeData; + + // send request + CASendNotification(endpoint, &responseInfo); + + // destroy remote endpoint + if (endpoint != NULL) + { + CADestroyRemoteEndpoint(endpoint); + } + printf("\n=============================================\n"); } void select_network() @@ -299,11 +391,12 @@ char get_menu() printf("\n=============================================\n"); printf("\t\tMenu\n"); - printf("\ts : start listening server\n"); - printf("\td : start discovery server\n"); + printf("\ts : start server\n"); + printf("\tc : start client\n"); printf("\tf : find resource\n"); printf("\tr : send request\n"); printf("\ta : advertise resource\n"); + printf("\tb : send notification\n"); printf("\tn : select network\n"); printf("\tx : unselect network\n"); printf("\th : handle request response\n"); @@ -324,25 +417,53 @@ void handle_request_response() CAHandleRequestResponse(); } -void request_handler(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo) +void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo) { - printf("request_handler, uri : %s, data : %s\n", (object != NULL) ? object->resourceUri : "", + 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 : ""); + + if(requestInfo->info.options) + { + uint32_t len = requestInfo->info.numOptions; + 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("send response with URI\n"); send_response(object, (requestInfo != NULL) ? requestInfo->info.token : ""); } -void response_handler(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo) +void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo) { - printf("response_handler, uri : %s, data : %s\n", (object != NULL) ? object->resourceUri : "", + printf("[CALLBACK] response_handler, uri : %s, data : %s\n", (object != NULL) ? object->resourceUri : "", (responseInfo != NULL) ? responseInfo->info.payload : ""); - printf("send request after receivce response data\n"); - send_request_tmp(object, (responseInfo != NULL) ? responseInfo->info.token : ""); + printf("[CALLBACK] response_handler, address : %s\n", (object != NULL) ? object->addressInfo.IP.ipAddress : ""); + + if(responseInfo->info.options) + { + uint32_t len = responseInfo->info.numOptions; + 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("send request with URI\n"); + //send_request_tmp(object, (responseInfo != NULL) ? responseInfo->info.token : ""); } void send_response(CARemoteEndpoint_t* endpoint, CAToken_t request_token) @@ -362,8 +483,7 @@ void send_response(CARemoteEndpoint_t* endpoint, CAToken_t request_token) responseInfo.result = 203; responseInfo.info = responseData; - // send request - endpoint->connectivityType = CA_WIFI; + // send request (connectivityType from remoteEndpoint of request Info) CASendResponse(endpoint, &responseInfo); printf("=============================================\n"); diff --git a/resource/csdk/connectivity/samples/linux/threadpool/Makefile b/resource/csdk/connectivity/samples/linux/threadpool/Makefile index 74abc3d..3f2a6c1 100644 --- a/resource/csdk/connectivity/samples/linux/threadpool/Makefile +++ b/resource/csdk/connectivity/samples/linux/threadpool/Makefile @@ -4,11 +4,11 @@ INC_DIR := -I$(ROOT_DIR)/api -I$(ROOT_DIR)/inc -I$(ROOT_DIR)/common/inc SRC_DIR := $(ROOT_DIR)/common/src/ CFLAGS = -Wall COMPILEFLAGS = `pkg-config --cflags glib-2.0` -LDFLAGS = `pkg-config --libs glib-2.0` +LDFLAGS = `pkg-config --libs glib-2.0` OUT = threadpool all: - $(CC) $(CFLAGS) $(INC_DIR) $(COMPILEFLAGS) $(SRC_DIR)uthreadpool.c $(SRC_DIR)umutex.c $(SRC_DIR)/../logger.c main.c -o $(OUT) $(LDFLAGS) + $(CC) $(CFLAGS) $(INC_DIR) $(COMPILEFLAGS) $(SRC_DIR)uthreadpool.c $(SRC_DIR)umutex.c $(SRC_DIR)/logger.c $(SRC_DIR)/oic_malloc.c main.c -o $(OUT) $(LDFLAGS) clean: rm -f $(OUT) diff --git a/resource/csdk/connectivity/samples/linux/threadpool/main.c b/resource/csdk/connectivity/samples/linux/threadpool/main.c index 3b83fa0..5bbdbe5 100644 --- a/resource/csdk/connectivity/samples/linux/threadpool/main.c +++ b/resource/csdk/connectivity/samples/linux/threadpool/main.c @@ -1,3 +1,23 @@ +/****************************************************************** + * + * 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 @@ -40,6 +60,7 @@ void testThreadPool(void) if (NULL == gMutex) { printf("[testThreadPool] Failed to create mutex!\n"); + u_thread_pool_free(gThreadPoolHandle); return; } @@ -49,7 +70,7 @@ void testThreadPool(void) if (NULL == gCond) { printf("[testThreadPool] Failed to create condition!\n"); - + u_thread_pool_free(gThreadPoolHandle); u_mutex_free(gMutex); return; } @@ -63,7 +84,7 @@ void testThreadPool(void) if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPoolHandle, task, (void *) string)) { printf("[testThreadPool] thread_pool_add_task failed!\n"); - + u_thread_pool_free(gThreadPoolHandle); u_mutex_unlock(gMutex); u_mutex_free(gMutex); u_cond_free(gCond); diff --git a/resource/csdk/connectivity/samples/tizen/Makefile b/resource/csdk/connectivity/samples/tizen/Makefile new file mode 100644 index 0000000..44569db --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/Makefile @@ -0,0 +1,52 @@ +# +# override with `make BUILD=debug` +# override with `make PLATFORM=arduinomega` or `make PLATFORM=arduinodue` +# default to release build +# default to build for linux +BUILD := release +PLATFORM := linux + +ifeq ($(PLATFORM),linux) +$(info *******************linux Build !!******************) + +CC=gcc + +ROOT_DIR = inc/ +INC_DIRS := -I$(ROOT_DIR)/ + +#CFLAGS=$(INC_DIRS) -std=c99 -DWITH_POSIX +#CFLAGS=-std=c99 +#CFLAGS=$(INC_DIRS) -std=c99 -DWITH_POSIX -g +CFLAGS=$(INC_DIRS) -DWITH_POSIX -D__TIZEN__ +#COMPILEFLAG = `pkg-config --cflags --libs com.samsung.oicca com.samsung.oicca-devel` +COMPILEFLAG = `pkg-config --cflags --libs com.samsung.oicca capi-network-wifi gobject-2.0 glib-2.0 dlog capi-network-bluetooth` + +OBJECTS := interfacesample.o casample.o + +all: $(OBJECTS) + $(CC) interfacesample.o -o interface_sample /usr/lib/liboicinterface.a -lm -lpthread -lrt -ldl -lstdc++ -lgobject-2.0 -lgio-2.0 -lglib-2.0 -lcapi-network-wifi -ldlog -lcapi-network-bluetooth + $(CC) casample.o -o ca_sample /usr/lib/liboicinterface.a -lm -lpthread -lrt -ldl -lstdc++ -lgobject-2.0 -lgio-2.0 -lglib-2.0 -lcapi-network-wifi -ldlog -lcapi-network-bluetooth +interfacesample.o: interfacesample.c + $(CC) $(CFLAGS) $(COMPILEFLAG) -c interfacesample.c -o interfacesample.o +casample.o: casample.c + $(CC) $(CFLAGS) $(COMPILEFLAG) -c casample.c -o casample.o +pack: +#$(CC) $(CFLAGS) $(COMPILEFLAG) wifi_interface.c bt_interface.c tc_interface.c sample_main.c -o sample /usr/lib/liboctbstack.a -lm + $(info **************************************TEST***************************) +install: +#cp -rf sample ./usr/apps/com.samsung.oicca/bin/sample + +clean: + rm -rf *.o interface_sample + rm -rf *.o ca_sample + +else ifeq ($(PLATFORM),arduinodue) +$(info *********Arduinodue Build!!**********) + +#Make Compilation Script for arduino + + +else + $(info *********error**********) + $(error Wrong value for PLATFORM !!) +endif diff --git a/resource/csdk/connectivity/samples/tizen/README.txt b/resource/csdk/connectivity/samples/tizen/README.txt new file mode 100644 index 0000000..0a2a305 --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/README.txt @@ -0,0 +1,31 @@ +Compiling Interface APIs: +========================= +1) Get the latest interface APIs code. +2) Copy the oic-resource code to linux machine. +3) Change the ROOT_DIR in interface APIs makefile such that it points to oic-resource/csdk in local linux environment. +4) Do "make" inside the interface APIs folder. + +Compiling Sample App FOR TIZEN: +=============================== +1) Get the oic-resource code(Changes done for Logging by SRI-B) from SRI-B and build it in Tizen GBS +2) Get the latest interface APIs code from repo and build it in Tizen GBS + To Build in Tizen GBS Platform, Use this command "sudo gbs build -A armv7l --include-all" +3) For Verification, Build Sample Console App and execute in Tizen Device + +Procedure to Execute Sample App: +================================= + 1) Copy the generated rpm(com.samsung.interfacesample-0.1-1.armv7l.rpm) to Tizen Device (say /opt/usr/media/xxx/) + 2) sdb shell, + 3) su + 4) cd /opt/usr/media/xxx/ + + 5) change-booting-mode.sh --update + + 6) Install interfacesample(console app). It contains Interface API libs and OIC-CORE Libs + i) rpm -Uvh com.samsung.interfacesample-0.1-1.armv7l.rpm --force --nodeps + + 7) Execute smack_reload.sh + + 8) rpm will be installed in /usr/apps/ Execute the sample app by below commands + i) cd /usr/apps/com.samsung.interfacesample/bin + ii) ./sample \ No newline at end of file diff --git a/resource/csdk/connectivity/samples/tizen/casample.c b/resource/csdk/connectivity/samples/tizen/casample.c new file mode 100644 index 0000000..22961ff --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/casample.c @@ -0,0 +1,547 @@ +/****************************************************************** + * + * 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 +#include +#include +#include +#include "cacommon.h" +#include "cainterface.h" + +static GMainLoop *mainloop; +static GIOChannel *channel; +static guint g_test_io_watch_id; +static GError *g_err_Sample; + +pthread_t thread; + +#define MAX_BUF_LEN 1024 +#define MAX_OPT_LEN 16 + +char get_menu(); +void process(); + +void initialize(); +void start_listening_server(); +void start_discovery_server(); +void find_resource(); +void send_request(); +void send_response(); +void advertise_resource(); +void send_notification(); +void select_network(); +void unselect_network(); +void handle_request_response(); + +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 terminate(); + +void pthread_func() +{ + g_main_loop_run(mainloop); +} + +int main() +{ + system("clear"); + + printf("=============================================\n"); + printf("\t\tsample main\n"); + printf("=============================================\n"); + + process(); + + return 0; +} + +void process() +{ + while (1) + { + char menu = toupper(get_menu()); + + switch (menu) + { + case 'Q': // quits the sample program + printf("quit..!!\n"); + g_main_loop_quit(mainloop); + return; + + case 'I': // Initialize interface + initialize(); + + case 'S': // start server + start_listening_server(); + break; + + case 'C': // start client + start_discovery_server(); + break; + + case 'F': // find resource + find_resource(); + break; + + case 'R': // send request + send_request(); + break; + + case 'A': // advertise resource + advertise_resource(); + break; + + case 'N': // select network + select_network(); + break; + + case 'X': // unselect network + unselect_network(); + break; + + case 'H': // handle request response + handle_request_response(); + break; + + case 'T': // Terminate interface + terminate(); + break; + + default: + printf("not supported menu!!\n"); + break; + } + } + +} + +void initialize() +{ + mainloop = g_main_loop_new(NULL, FALSE); + pthread_create(&thread, NULL, (void *) &pthread_func, NULL); + + CAInitialize(); + + // network enable + // default + printf("select default network(WIFI)\n"); + CASelectNetwork(CA_WIFI); + + // set handler. + CARegisterHandler(request_handler, response_handler); +} + +void start_listening_server() +{ + printf("start listening server!!\n"); + + CAStartListeningServer(); +} + +void start_discovery_server() +{ + printf("start discovery server at client!!\n"); + + CAStartDiscoveryServer(); +} + +void find_resource() +{ + char buf[MAX_BUF_LEN]; + + memset(buf, 0, sizeof(char) * MAX_BUF_LEN); + + printf("\n=============================================\n"); + printf("ex) a/light\n"); + printf("reference uri : "); + + gets(buf); + + CAResult_t res = CAFindResource(buf); + + if (res != CA_STATUS_OK) + { + printf("find resource error:%d !!\n", res); + } + else + { + printf("find resource for %s URI\n", buf); + } + + 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 : "); + + gets(buf); + + // create remote endpoint + CARemoteEndpoint_t *endpoint = NULL; + CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint); + + if (res != CA_STATUS_OK) + { + printf("create remote endpoint error!!"); + CADestroyRemoteEndpoint(endpoint); + return; + } + + // create token + CAToken_t token = NULL; + res = CAGenerateToken(&token); + + if (res != CA_STATUS_OK) + { + printf("token generate error!!"); + token = NULL; + } + + printf("generated token %s\n", (token != NULL) ? token : ""); + + CAInfo_t requestData; + memset(&requestData, 0, sizeof(CAInfo_t)); + requestData.token = token; + requestData.payload = "Temp Json Payload"; + + CARequestInfo_t requestInfo; + memset(&requestInfo, 0, sizeof(CARequestInfo_t)); + requestInfo.method = CA_GET; + requestInfo.info = requestData; + + // send request + CASendRequest(endpoint, &requestInfo); + + if (token != NULL) + { + CADestroyToken(token); + } + + // destroy remote endpoint + if (endpoint != NULL) + { + CADestroyRemoteEndpoint(endpoint); + } + + printf("=============================================\n"); +} + +void advertise_resource() +{ + char buf[MAX_BUF_LEN]; + + memset(buf, 0, sizeof(char) * MAX_BUF_LEN); + + printf("\n=============================================\n"); + printf("uri : "); + + scanf("%s", buf); + + int optionNum = 0; + char optionData[MAX_OPT_LEN]; + + printf("Option Num : "); + scanf("%d", &optionNum); + CAHeaderOption_t *headerOpt; + + if (optionNum > 0) + { + headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum); + if (NULL == headerOpt) + { + printf("memory allocation failed!\n"); + return; + } + memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum); + } + + int i; + for (i = 0; i < optionNum; i++) + { + int optionID = 0; + printf("[%d] Option ID : ", i + 1); + scanf("%d", &optionID); + headerOpt[i].optionID = optionID; + + memset(optionData, 0, sizeof(char) * MAX_OPT_LEN); + printf("[%d] Option Data : ", i + 1); + scanf("%s", optionData); + memcpy(headerOpt[i].optionData, optionData, MAX_OPT_LEN); + printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData); + + headerOpt[i].optionLength = (uint16_t) strlen(optionData); + } + printf("\n=============================================\n"); + + CAAdvertiseResource(buf, headerOpt, (uint8_t) optionNum); + + free(headerOpt); + +} + +void send_notification() +{ + 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 : "); + + gets(buf); + + // create remote endpoint + CARemoteEndpoint_t *endpoint = NULL; + CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint); + + if (res != CA_STATUS_OK) + { + printf("create remote endpoint error!!"); + CADestroyRemoteEndpoint(endpoint); + return; + } + + CAInfo_t respondeData; + memset(&respondeData, 0, sizeof(CAInfo_t)); + respondeData.token = "client token"; + respondeData.payload = "Temp Notification Data"; + + CAResponseInfo_t responseInfo; + memset(&responseInfo, 0, sizeof(CAResponseInfo_t)); + responseInfo.result = CA_CONTENT; + responseInfo.info = respondeData; + + // send request + CASendNotification(endpoint, &responseInfo); + + // destroy remote endpoint + if (endpoint != NULL) + { + CADestroyRemoteEndpoint(endpoint); + } + printf("\n=============================================\n"); +} + +void select_network() +{ + char buf[MAX_BUF_LEN]; + + printf("\n=============================================\n"); + printf("\tselect network\n"); + printf("ETHERNET : 0\n"); + printf("WIFI : 1\n"); + printf("EDR : 2\n"); + printf("LE : 3\n"); + printf("select : "); + + memset(buf, 0, sizeof(char) * MAX_BUF_LEN); + gets(buf); + + int number = buf[0] - '0'; + + number = (number < 0 || number > 3) ? 1 : number; + + CASelectNetwork(1 << number); + + printf("=============================================\n"); +} + +void unselect_network() +{ + char buf[MAX_BUF_LEN]; + + printf("\n=============================================\n"); + printf("\tunselect enabled network\n"); + printf("ETHERNET : 0\n"); + printf("WIFI : 1\n"); + printf("EDR : 2\n"); + printf("LE : 3\n"); + printf("select : "); + + memset(buf, 0, sizeof(char) * MAX_BUF_LEN); + gets(buf); + + int number = buf[0] - '0'; + + number = (number < 0 || number > 3) ? 1 : number; + + CAUnSelectNetwork(1 << number); + printf("Terminating...\n"); + CATerminate(); + //pthread_join(thread, NULL); + printf("=============================================\n"); +} + +char get_menu() +{ + char buf[MAX_BUF_LEN]; + + printf("\n=============================================\n"); + printf("\t\tMenu\n"); + printf("\ti : Initialize\n"); + printf("\ts : start server\n"); + printf("\tc : start client\n"); + printf("\tf : find resource\n"); + printf("\tr : send request\n"); + printf("\ta : advertise resource\n"); + printf("\tn : select network\n"); + printf("\tx : unselect network\n"); + printf("\th : handle request response\n"); + printf("\tt : terminate\n"); + printf("\tq : quit\n"); + printf("=============================================\n"); + printf("select : "); + + memset(buf, 0, sizeof(char) * MAX_BUF_LEN); + + gets(buf); + + return buf[0]; +} + +void handle_request_response() +{ + printf("handle_request_response\n"); + CAHandleRequestResponse(); +} + +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, address : %s\n", + (object != NULL) ? object->addressInfo.IP.ipAddress : ""); + + if (requestInfo->info.options) + { + uint32_t len = requestInfo->info.numOptions; + 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("send response with URI\n"); + send_response(object, (requestInfo != NULL) ? requestInfo->info.token : ""); + +} + +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\n", + (object != NULL) ? object->addressInfo.IP.ipAddress : ""); + + if (responseInfo->info.options) + { + uint32_t len = responseInfo->info.numOptions; + 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); + } + } + +} + +void send_response(CARemoteEndpoint_t *endpoint, CAToken_t request_token) +{ + + printf("\n=============================================\n"); + + CAInfo_t responseData; + //responseData = (CAInfo*) malloc(sizeof(CAInfo)); + memset(&responseData, 0, sizeof(CAInfo_t)); + responseData.token = request_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; + + // send request (connectivityType from remoteEndpoint of request Info) + CASendResponse(endpoint, &responseInfo); + + printf("=============================================\n"); + +} + +void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token) +{ + + printf("\n=============================================\n"); + + CAInfo_t requestData; + memset(&requestData, 0, sizeof(CAInfo_t)); + requestData.token = token; + requestData.payload = "Temp Json Payload"; + + CARequestInfo_t requestInfo; + memset(&requestInfo, 0, sizeof(CARequestInfo_t)); + requestInfo.method = CA_GET; + requestInfo.info = requestData; + + // send request + endpoint->connectivityType = CA_WIFI; + CASendRequest(endpoint, &requestInfo); + + printf("=============================================\n"); + +} + +void terminate() +{ + unselect_network(); +} diff --git a/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.manifest b/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.manifest new file mode 100644 index 0000000..15fb3a1 --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.manifest @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.rule b/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.rule new file mode 100644 index 0000000..1eb8ee9 --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.rule @@ -0,0 +1,39 @@ +# all permissions +#interfacesample system::vconf rwxat +#interfacesample system::home rwxat +#interfacesample system::media rwxat +#interfacesample system::homedir rwxat +#interfacesample system::share rwxat +#interfacesample dali rwxat +#interfacesample sys-assert::core rwxat +#interfacesample dbus r +#interfacesample system::media rwxat +# system and device +#interfacesample device::hwcodec rw +#interfacesample device::video r +#interfacesample device::camera r +#interfacesample system::crash wx +interfacesample system::use_internet rw +# db +#interfacesample libaccounts-svc::db rw +#interfacesample ail::db rw +#interfacesample media-data::db rw +#interfacesample app-svc::db rw +#interfacesample email-service::db rw +#interfacesample cloud-content-sync::db rw +#others +#interfacesample media-server rwx +#interfacesample mdm-server w +#interfacesample xorg w +#interfacesample isf rwx +#interfacesample immvibed rw +#interfacesample dbus rwx +#interfacesample dali rx +#interfacesample data-provider-master r +#interfacesample smemo rx +#interfacesample crash-worker rx +#interfacesample msg-service w +#interfacesample webkit2-efl rx +#interfacesample ug-image-viewer-efl rx +#interfacesample net.wifi-qs rwx +#interfacesample sys-assert::info wx diff --git a/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.xml b/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.xml new file mode 100644 index 0000000..146d6c0 --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/com.samsung.interfacesample.xml @@ -0,0 +1,16 @@ + + + + OIC + interfacesample + + com.samsung.interfacesample.png + + + + + + http://tizen.org/privilege/socket + + + diff --git a/resource/csdk/connectivity/samples/tizen/interfacesample.c b/resource/csdk/connectivity/samples/tizen/interfacesample.c new file mode 100644 index 0000000..bd95856 --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/interfacesample.c @@ -0,0 +1,1287 @@ +/****************************************************************** +* +* 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 +#include +#include +#include + +#include "cacommon.h" +#include "caadapterinterface.h" +#include "uthreadpool.h" + +#define MOD_NAME "TizenSample" + +//Comment any below for blocking testing of specific adapters +//#define WIFI_ADAPTER_TEST +#define BT_ADAPTER_TEST +//#define BLE_ADAPTER_TEST + +#if defined(WIFI_ADAPTER_TEST) +#include "cawifiadapter.h" +#include "caethernetadapter.h" +static u_thread_pool_t gWiFiThreadPool = NULL; +#elif defined(BT_ADAPTER_TEST) +#include "caedradapter.h" +static u_thread_pool_t gBTThreadPool = NULL; +#elif defined(BLE_ADAPTER_TEST) +#include "caleadapter.h" +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 CALocalConnectivity_t *localWifiEndpoint = NULL; +//Hardcoded coap data for Test +static char coapData[500] = + "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}]}"; + +void testInitializeBTInterface(void); +void testTerminateBTInterface(void); +void testInitializeWIFIInterface(void); +void testTerminateWIFIInterface(void); +void testInitializeBLEInterface(void); +void testTerminateBLEInterface(void); + +typedef struct ConnectivityHandlerList +{ + CAConnectivityType_t type; + CAConnectivityHandler_t handler; + struct ConnectivityHandlerList *nextHandler; +} ConnectivityHandlerList; + +static ConnectivityHandlerList *gConnectivityHandlers = NULL; + +void initializeThreadPool(CAConnectivityType_t type) +{ +#ifdef BT_ADAPTER_TEST + if (CA_EDR == type && NULL == gBTThreadPool) + { + if (CA_STATUS_OK != u_thread_pool_init(3, &gBTThreadPool)) + { + printf("Failed to create thread pool for BT adapter!\n"); + return; + } + } +#endif +#ifdef WIFI_ADAPTER_TEST + if (CA_WIFI == type && NULL == gWiFiThreadPool) + { + if (CA_STATUS_OK != u_thread_pool_init(3, &gWiFiThreadPool)) + { + printf("Failed to create thread pool for BT adapter!\n"); + return; + } + } +#endif +#ifdef BLE_ADAPTER_TEST + if (CA_LE == type && NULL == gLEThreadPool) + { + if (CA_STATUS_OK != u_thread_pool_init(3, &gLEThreadPool)) + { + printf("Failed to create thread pool for BT adapter!\n"); + return; + } + } +#endif +} + + +void storeInterfaceCallbacks(ConnectivityHandlerList *newHandler) +{ + printf("storeInterfaceCallbacks Entry in Sample\n"); + newHandler->nextHandler = NULL; + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + + if (!tempConnectivityHandlers) + { + gConnectivityHandlers = newHandler; + printf("storeInterfaceCallbacks Exit in Sample\n"); + return; + } + + while (tempConnectivityHandlers->nextHandler) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + tempConnectivityHandlers->nextHandler = newHandler; + printf("storeInterfaceCallbacks Exit in Sample\n"); +} + +void interfaceRegisterCallback(CAConnectivityHandler_t handler, + CAConnectivityType_t connType) +{ + printf("interfaceRegisterCallback Entry in Sample\n"); + ConnectivityHandlerList *newConnectivityHandler = (ConnectivityHandlerList *) malloc(sizeof( + ConnectivityHandlerList)); + if (NULL == newConnectivityHandler) + { + printf("Memory allocation failed\n"); + return; + } + + newConnectivityHandler->type = connType; + newConnectivityHandler->handler = handler; + storeInterfaceCallbacks(newConnectivityHandler); + printf("interfaceRegisterCallback Exit in Sample\n"); +} + +void networkPacketHandler(CARemoteEndpoint_t *object, void *data, uint32_t dataLength) +{ + printf("networkPacketHandler Entry in Sample\n"); + if (object == NULL || data == NULL) + { + printf("NULL Object\n"); + return; + } + + printf("Data Received from: "); + if (CA_EDR == object->connectivityType) + { + printf(object->addressInfo.BT.btMacAddress); + } + else if (CA_LE == object->connectivityType) + { + printf(object->addressInfo.LE.leMacAddress); + } + else if (CA_WIFI == object->connectivityType || CA_ETHERNET == object->connectivityType) + { + printf(object->addressInfo.IP.ipAddress); + } + + printf("\nReceived Data [Length: %d]: %s\n",dataLength,(char *)data); + printf("networkPacketHandler Exit in Sample\n"); +} + +void networkInterfaceCallback(CALocalConnectivity_t *localEndPoint, + CANetworkStatus_t networkConnectivityState) +{ + printf("networkInterfaceCallback Entry in Sample\n"); + if (localEndPoint == NULL) + { + printf("NULL Object\n"); + return; + } + + if (networkConnectivityState == CA_INTERFACE_UP) + { + printf("Network Status is UP\n"); + } + else + { + printf("Network Status is DOWN\n"); + } + + printf("Address: "); + if (CA_EDR == localEndPoint->type) + { + printf("%s\n", localEndPoint->addressInfo.BT.btMacAddress); + } + else if (CA_LE == localEndPoint->type) + { + printf("%s\n", localEndPoint->addressInfo.LE.leMacAddress); + } + else if (CA_WIFI == localEndPoint->type || CA_ETHERNET == localEndPoint->type) + { + printf("%s\n", localEndPoint->addressInfo.IP.ipAddress); + } + + printf("networkInterfaceCallback Exit in Sample\n"); +} + + +void freeData(void *data) +{ + printf("freeData Entry in Sample\n"); + if (data) + { + free(data); + } + printf("freeData Exit in Sample\n"); +} + +int16_t selectConnectivityType() +{ + int32_t cType; + printf("*******Select the Connectivity Type*******\n"); + printf(" [1] WIFI \n"); + printf(" [2] BT \n"); + printf(" [3] BLE \n"); + + fflush(stdin); + scanf("%d", &cType); + if (cType < 1 && cType > 3) + { + printf("Invalid Selection!!!!\n"); + return 0; + } + return (int16_t)cType; +} + +int16_t interfaceStartAdapter(CAConnectivityType_t connType) +{ + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf("None of the interface is initialized\n"); + return 0; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d", connType); + return 0; + } + + if (CA_STATUS_OK != tempConnectivityHandlers->handler.startAdapter()) + { + printf("Failed to Start adapter\n"); + return 0; + } + + return 1; +} + +int16_t interfaceMulticastStartServer(CAConnectivityType_t connType, int serverType) +{ + printf("interfaceMulticastStartServer Starting...\n"); + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf("None of the interface is initialized\n"); + return 0; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d", connType); + return 0; + } + + CAAdapterStartDiscoveryServer startServer = NULL; + switch (serverType) + { + case 1: //Discovery server + startServer = tempConnectivityHandlers->handler.startDiscoverServer; + break; + case 2: //Listening server + startServer = tempConnectivityHandlers->handler.startListenServer; + break; + case 3: //Notification server + startServer = tempConnectivityHandlers->handler.startNotifyServer; + break; + } + + if (startServer) + { + printf("Invoking start server method\n"); + startServer(); + } +} + +int16_t interfaceSendUnicastData(CAConnectivityType_t connType) +{ + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf(" None of the interface is initialized \n"); + return 0; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d", connType); + return 0; + } + + if (CA_WIFI == connType) + { + CARemoteEndpoint_t endpoint; + char remoteIPAddress[CA_IPADDR_SIZE] = {0}; + printf("\nEnter the Remote Endpoint IP: "); + scanf("%s", remoteIPAddress); + if (strlen(remoteIPAddress) == 0) + { + printf("Invalid device address\n"); + return; + } + endpoint.connectivityType = CA_WIFI; + strncpy(endpoint.addressInfo.IP.ipAddress, remoteIPAddress, CA_IPADDR_SIZE); + endpoint.addressInfo.IP.port = 5283; /* Send the corresponding port here */ + + int sdatalen = tempConnectivityHandlers->handler.sendData(&endpoint, coapData, + strlen(coapData)); + if (sdatalen == strlen(coapData)) + { + printf("Send Unicast data success\n"); + } + else + { + printf("Send Unicast data failed\n"); + } + } + else if (CA_EDR == connType) + { + //create endpoint + CARemoteEndpoint_t endpoint; + + //Get the device address from user + char deviceaddress[100] = {0}; + printf("Enter the device address: \n"); + scanf("%s", deviceaddress); + + if (strlen(deviceaddress) == 0) + { + printf("Invlaid device address\n"); + return; + } + + endpoint.connectivityType = CA_EDR; + strncpy(endpoint.addressInfo.BT.btMacAddress, deviceaddress, CA_MACADDR_SIZE - 1); + endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + endpoint.resourceUri = NULL; + + printf("Sent Unicast data to device: %s\n", endpoint.addressInfo.BT.btMacAddress); + tempConnectivityHandlers->handler.sendData(&endpoint, coapData, strlen(coapData)+1); + } + else if (CA_LE == connType) + { + //create endpoint + CARemoteEndpoint_t endpoint; + + //Get the device address from user + char deviceaddress[100] = {0}; + printf("Enter the device address: \n"); + scanf("%s", deviceaddress); + + if (strlen(deviceaddress) == 0) + { + printf("Invlaid device address\n"); + return; + } + + //Get the service uuid from user + char uuid[100] = {0}; + printf("Enter the service uuid: \n"); + scanf("%s", uuid); + + if (strlen(uuid) == 0) + { + printf("Invlaid service uuid\n"); + return; + } + + endpoint.connectivityType = CA_LE; + strncpy(endpoint.addressInfo.BT.btMacAddress, deviceaddress, CA_MACADDR_SIZE - 1); + endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + endpoint.resourceUri = strdup(uuid); + + tempConnectivityHandlers->handler.sendData(&endpoint, coapData, strlen(coapData)); + printf("Sent Unicast data \n"); + free(endpoint.resourceUri); + } + + return 1; +} + +void interfaceSendNotification(CAConnectivityType_t connType) +{ + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf(" None of the interface is initialized \n"); + return; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d\n", connType); + return; + } + + if (CA_WIFI == connType) + { + CARemoteEndpoint_t remoteEndpoint; + tempConnectivityHandlers->handler.sendNotification(&remoteEndpoint, coapData, strlen(coapData)); + } + else if (CA_EDR == connType) + { + //create endpoint + CARemoteEndpoint_t endpoint; + + //Get the device address from user + char deviceaddress[100] = {0}; + printf("Enter the device address: \n"); + scanf("%s", deviceaddress); + + if (strlen(deviceaddress) == 0) + { + printf("Invlaid device address\n"); + return; + } + + //Get the service uuid from user + char uuid[100] = {0}; + printf("Enter the service uuid: \n"); + scanf("%s", uuid); + + if (strlen(uuid) == 0) + { + printf("Invlaid service uuid\n"); + return; + } + + endpoint.connectivityType = CA_EDR; + strncpy(endpoint.addressInfo.BT.btMacAddress, deviceaddress, CA_MACADDR_SIZE - 1); + endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + endpoint.resourceUri = strdup(uuid); + + tempConnectivityHandlers->handler.sendNotification(&endpoint, coapData, strlen(coapData)); + printf("Sent Unicast data \n"); + free(endpoint.resourceUri); + } + else if (CA_LE == connType) + { + //create endpoint + CARemoteEndpoint_t endpoint; + + //Get the device address from user + char deviceaddress[100] = {0}; + printf("Enter the device address: \n"); + scanf("%s", deviceaddress); + + if (strlen(deviceaddress) == 0) + { + printf("Invlaid device address\n"); + return; + } + + //Get the service uuid from user + char uuid[100] = {0}; + printf("Enter the service uuid: \n"); + scanf("%s", uuid); + + if (strlen(uuid) == 0) + { + printf("Invlaid service uuid\n"); + return; + } + + endpoint.connectivityType = CA_LE; + strncpy(endpoint.addressInfo.BT.btMacAddress, deviceaddress, CA_MACADDR_SIZE - 1); + endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + endpoint.resourceUri = strdup(uuid); + + tempConnectivityHandlers->handler.sendNotification(&endpoint, coapData, strlen(coapData)); + printf("Sent Unicast data \n"); + free(endpoint.resourceUri); + printf("Feature is not implemented !!\n"); + } +} + +int16_t interfaceSendMulticastData(CAConnectivityType_t connType) +{ + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf("None of the interface is initialized\n"); + return 0; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d", connType); + return 0; + } + + if (connType == CA_WIFI) + { + tempConnectivityHandlers->handler.sendDataToAll(coapData, + strlen(coapData) + 1); + } + else if (connType == CA_EDR || connType == CA_LE) + { + tempConnectivityHandlers->handler.sendDataToAll(coapData, strlen(coapData)); + } +} + +void interfaceReadData(CAConnectivityType_t connType) +{ + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf("None of the interface is initialized\n"); + return; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d", connType); + return; + } + + if (CA_STATUS_OK != tempConnectivityHandlers->handler.readData()) + { + printf("Failed to Read Data\n"); + return; + } + + printf("Read Data is successfull\n"); + return; +} + +void interfaceGetNetworkInfo(CAConnectivityType_t connType) +{ + int i = 0; + + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf("None of the interface is initialized\n"); + return; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d", connType); + return; + } + + //Get the network interface info + CALocalConnectivity_t *info = NULL; + uint32_t size = 0; + if (CA_STATUS_OK != tempConnectivityHandlers->handler.GetnetInfo(&info, &size)) + { + printf("Failed to get network info\n"); + return; + } + + if (0 >= size || info == NULL) + { + printf("No network found !!!\n"); + return; + } + + printf("Network Information: \n"); + for (; i < size; i++) + { + if (connType == CA_WIFI) + { + printf("Type : %s\n", (connType == CA_ETHERNET) ? "CA_ETHERNET" : "CA_WIFI"); + printf("Address : %s\n", info[i].addressInfo.IP.ipAddress); + } + else + { + printf("Type : %s\n", (connType == CA_EDR) ? "CA_EDR" : "CA_LE"); + printf("Address : %s\n\n", info[i].addressInfo.BT.btMacAddress); + } + } +} + +int16_t interfaceStopAdapter(CAConnectivityType_t connType) +{ + ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers; + if (NULL == tempConnectivityHandlers) + { + printf("None of the interface is initialized\n"); + return 0; + } + + while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType) + { + tempConnectivityHandlers = tempConnectivityHandlers->nextHandler; + } + + if (NULL == tempConnectivityHandlers) + { + printf( "No interface handler for type %d", connType); + return 0; + } + + if (CA_STATUS_OK != tempConnectivityHandlers->handler.stopAdapter()) + { + printf("Failed to Stop adapter\n"); + return 0; + } + + printf("Stopped the adapter\n"); + return 1; +} + +void testInitializeInterface() +{ + printf("testInitializeInterface Entry\n"); + + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + testInitializeWIFIInterface(); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + testInitializeBTInterface(); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + testInitializeBLEInterface(); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testTerminateInterface() +{ + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + +#ifdef WIFI_ADAPTER_TEST + if (1 == type) /* WIFI */ + { + testTerminateWIFIInterface(); + } +#endif +#ifdef BT_ADAPTER_TEST + if (2 == type) /*BT*/ + { + testTerminateBTInterface(); + } +#endif +#ifdef BLE_ADAPTER_TEST + if (3 == type) /*BLE*/ + { + testTerminateBLEInterface(); + } +#endif + + ConnectivityHandlerList *currentConnectivityHandler = gConnectivityHandlers; + ConnectivityHandlerList *prevConnectivityHandler = NULL; + + printf("Linked list delete start\n"); + while (currentConnectivityHandler != NULL) + { + printf("Iterating through the list to find the matching interface\n"); + if (currentConnectivityHandler->type == type) + { + printf("Matching interface found\n"); + if (prevConnectivityHandler == NULL) + { + currentConnectivityHandler = currentConnectivityHandler->nextHandler; + freeData(gConnectivityHandlers); + gConnectivityHandlers = NULL; + printf( "Node deleted with interface type %d", type); + } + else + { + prevConnectivityHandler->nextHandler = currentConnectivityHandler->nextHandler; + freeData(currentConnectivityHandler); + currentConnectivityHandler = prevConnectivityHandler->nextHandler; + printf( "Node deleted with interface type %d from linked list", type); + } + } + else + { + prevConnectivityHandler = currentConnectivityHandler; + currentConnectivityHandler = currentConnectivityHandler->nextHandler; + } + } + gConnectivityHandlers = NULL; + return; +} + +void testStartAdapter() +{ + int type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceStartAdapter(CA_WIFI); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceStartAdapter(CA_EDR); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceStartAdapter(CA_LE); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testStartServer(int serverType) +{ + int type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceMulticastStartServer(CA_WIFI, serverType); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceMulticastStartServer(CA_EDR, serverType); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceMulticastStartServer(CA_LE, serverType); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testSendUnicastData() +{ + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceSendUnicastData(CA_WIFI); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceSendUnicastData(CA_EDR); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceSendUnicastData(CA_LE); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testSendNotification() +{ + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceSendNotification(CA_WIFI); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceSendNotification(CA_EDR); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceSendNotification(CA_LE); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testSendMulticastData() +{ + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceSendMulticastData(CA_WIFI); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceSendMulticastData(CA_EDR); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceSendMulticastData(CA_LE); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testReadData(void) +{ + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceReadData(CA_WIFI); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceReadData(CA_EDR); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceReadData(CA_LE); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testGetNetworkInfo(void) +{ + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceGetNetworkInfo(CA_WIFI); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceGetNetworkInfo(CA_EDR); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceGetNetworkInfo(CA_LE); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +void testStopAdapter() +{ + int16_t type = selectConnectivityType(); + if (0 >= type || 3 < type) + { + printf("Invalid selection...\n"); + return; + } + + switch (type) + { +#ifdef WIFI_ADAPTER_TEST + case 1: //WIFI + { + interfaceStopAdapter(CA_WIFI); + } + break; +#endif +#ifdef BT_ADAPTER_TEST + case 2: //BT + { + interfaceStopAdapter(CA_EDR); + } + break; +#endif +#ifdef BLE_ADAPTER_TEST + case 3: //BLE + { + interfaceStopAdapter(CA_LE); + } + break; +#endif + default: + printf("Feature is not enabled or not implemented\n"); + } +} + +#ifdef BT_ADAPTER_TEST +void testInitializeBTInterface(void) +{ + printf("Initiazing EDR\n"); + + printf("Initializing BT Adapter threadpool\n"); + initializeThreadPool(CA_EDR); + + //Start bluetooth communication adapter + CAResult_t err = CAInitializeEDR(interfaceRegisterCallback, networkPacketHandler, + networkInterfaceCallback, gBTThreadPool); + if (CA_STATUS_OK != err && CA_ADAPTER_NOT_ENABLED != err) + { + printf("Failed to initialize bluetooth communication adapter!\n"); + } +} + +void testTerminateBTInterface(void) +{ + printf("Terminating EDR\n"); + + //Terminate the Bluetooth communication adapter + CATerminateEDR(); + + printf( "Terminating BT Adapter thread pool"); + u_thread_pool_free(gBTThreadPool); +} +#endif //BT_ADAPTER_TEST + +#ifdef WIFI_ADAPTER_TEST +void testInitializeWIFIInterface(void) +{ + printf("testInitializeWIFIInterface IN\n"); + + printf("Initializing WIFI adapter threadpool\n"); + initializeThreadPool(CA_WIFI); + + //Start Wifi communication adapter + if (0 != CAInitializeWifi(interfaceRegisterCallback, networkPacketHandler, + networkInterfaceCallback, gWiFiThreadPool)) + { + printf("testInitializeWIFIInterface Failed to initialize bluetooth communication adapter\n"); + return; + } + + printf("testInitializeWIFIInterface OUT\n"); +} + +void testTerminateWIFIInterface(void) +{ + printf("testTerminateWIFIInterface IN\n"); + + // Stop if Wifi communication adapter is running + interfaceStopAdapter(CA_WIFI); + + // Freeing threadpool for wifi communication adapter + printf( "Terminating WIFI Adapter thread pool"); + u_thread_pool_free(gWiFiThreadPool); + + //Terminate the Wifi communication adapter + CATerminateWIfI(); + + + printf("testTerminateWIFIInterface OUT\n"); +} +#endif //WIFI_ADAPTER_TEST + +#ifdef BLE_ADAPTER_TEST +void testInitializeBLEInterface(void) +{ + printf("testInitializeBLEInterface IN\n"); + + printf("Initializing BLE adapter threadpool\n"); + initializeThreadPool(CA_LE); + + //Start bluetooth communication adapter + if (0 != CAInitializeLE(interfaceRegisterCallback, networkPacketHandler, + networkInterfaceCallback, gLEThreadPool)) + { + printf("testInitializeBLEInterface Failed due to CAInitializeLE\n"); + return; + } + + printf("testInitializeBLEInterface OUT\n"); +} + +void testTerminateBLEInterface(void) +{ + printf("testTerminateBLEInterface IN\n"); + + //Terminate the BLE server & Client + CATerminateLE(); + + printf( "Terminating BLE Adapter thread pool"); + u_thread_pool_free(gLEThreadPool); + + printf("testTerminateBLEInterface OUT\n"); +} +#endif //BLE_ADAPTER_TEST + +static void testPrintHelp(void) +{ + printf(" =====================================================================\n"); + printf("| Welcome to Connectivity Abstraction |\n"); + printf("| - CA Unit Test v1.0 - |\n"); + printf("|---------------------------------------------------------------------|\n"); + printf("| ** Options ** |\n"); + printf("| i - Initialize the Interface |\n"); + printf("| d - Terminate the Interface |\n"); + printf("| a - Start adapter |\n"); + printf("| b - Stop adapter |\n"); + printf("| sd- Start Discovery Server |\n"); + printf("| sl- Start Listening Server |\n"); + printf("| sn- Start Notification Server |\n"); + printf("| u - Send Unicast Data |\n"); + printf("| m - Send Multicast Data |\n"); + printf("| n - Send Notification Data |\n"); + printf("| g - Get Network Info |\n"); + printf("| r - Read data synchronously |\n"); + printf("| x - quit the test. |\n"); + printf("| h - Help menu. |\n"); + printf(" =====================================================================\n"); +} + +static gboolean testThread(GIOChannel *source, GIOCondition condition , gpointer data) +{ + gchar buf[10] = {'\0'}; + gsize read = 0; + + + if (g_io_channel_read(channel, buf, 10, &read) != G_IO_ERROR_NONE) + { + printf("g_io_channel_read error!!!\n"); + return 1; + } + buf[read] = '\0'; + g_strstrip(buf); + + /*if ((!has_register) && (((buf[0]!= 'i') && (buf[0]!= 'h') && (buf[0]!= 'q')) || (read != 2))) { + testPrintHelp(); + printf("***Warning***: You should Register firstly!\n"); + return 1; + }*/ + switch (buf[0]) + { + case 'i': + testInitializeInterface(); + break; + case 'x': + testTerminateInterface(); + if (g_source_remove(g_test_io_watch_id)) + { + printf("g_source_remove() OK!!!\n"); + g_io_channel_shutdown(channel, TRUE, &g_err_Sample); + g_io_channel_unref(channel); + g_main_loop_quit(mainloop); + } + break; + case 'd': + testTerminateInterface(); + break; + case 'a': + testStartAdapter(); + break; + case 'b': + testStopAdapter(); + break; + case 's': + if (read == 3) + { + if (buf[1] == 'd') + { + testStartServer(1); + } + if (buf[1] == 'l') + { + testStartServer(2); + } + if (buf[1] == 'n') + { + testStartServer(3); + } + } + break; + case 'u': + testSendUnicastData(); + break; + case 'm': + testSendMulticastData(); + break; + case 'n': + testSendNotification(); + break; + case 'r': + testReadData(); + break; + case 'g': + testGetNetworkInfo(); + break; + case 'h': + testPrintHelp(); + } + return 1; +} + +int main(int argc, char *argv[]) +{ + printf("Starting sample\n"); + mainloop = g_main_loop_new(NULL, FALSE); + channel = g_io_channel_unix_new(0);/* read from stdin */ + g_test_io_watch_id = g_io_add_watch(channel, + (GIOCondition)(G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL), testThread, + NULL); + printf("CM Test Thread created...\n"); + testPrintHelp(); + g_main_loop_run(mainloop); + return 0; +} + diff --git a/resource/csdk/connectivity/samples/tizen/packaging/com.samsung.interfacesample.spec b/resource/csdk/connectivity/samples/tizen/packaging/com.samsung.interfacesample.spec new file mode 100644 index 0000000..4296b57 --- /dev/null +++ b/resource/csdk/connectivity/samples/tizen/packaging/com.samsung.interfacesample.spec @@ -0,0 +1,65 @@ +%define PREFIX /usr/apps/com.samsung.interfacesample +%define ROOTDIR %{_builddir}/%{name}-%{version} + +Name: com.samsung.interfacesample +Version: 0.1 +Release: 1 +Summary: Tizen interfacesample application +URL: http://slp-source.sec.samsung.net +Source: %{name}-%{version}.tar.gz +License: SAMSUNG +Group: Samsung/Application +#BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: boost-devel +BuildRequires: boost-thread +BuildRequires: boost-system +BuildRequires: boost-filesystem +#BuildRequires: oic-core +BuildRequires: pkgconfig(capi-network-wifi) +BuildRequires: pkgconfig(capi-network-bluetooth) +BuildRequires: com.samsung.oicca +#BuildRequires: com.samsung.oicca-devel + +%description +SLP interfacesample application + +%prep +%setup -q + +%build + +make clean +make PLATFORM=linux + +#make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +# remove later +#%make_install +mkdir -p %{buildroot}/usr/share/license +mkdir -p %{buildroot}/usr/share/license +mkdir -p %{buildroot}/usr/share/packages +mkdir -p %{buildroot}/etc/smack/accesses2.d +mkdir -p %{buildroot}/usr/apps/com.samsung.interfacesample/bin/ +mkdir -p %{buildroot}/usr/lib +#cp -rf LICENSE %{buildroot}/usr/share/license/%{name} +cp -rf %{ROOTDIR}/com.samsung.interfacesample.xml %{buildroot}/usr/share/packages +cp -rf %{ROOTDIR}/com.samsung.interfacesample.rule %{buildroot}/etc/smack/accesses2.d +cp -rf %{ROOTDIR}/interface_sample %{buildroot}/usr/apps/com.samsung.interfacesample/bin/ +cp -rf %{ROOTDIR}/ca_sample %{buildroot}/usr/apps/com.samsung.interfacesample/bin/ +#cp -rf %{ROOTDIR}/liboicinterface.a %{buildroot}/usr/lib + +%files +%manifest com.samsung.interfacesample.manifest +/etc/smack/accesses2.d/com.samsung.interfacesample.rule +%defattr(-,root,root,-) +%attr(-,inhouse,inhouse) +/usr/apps/com.samsung.interfacesample/bin/interface_sample +/usr/apps/com.samsung.interfacesample/bin/ca_sample +#%{_libdir}/lib*.a* +/usr/share/packages/com.samsung.interfacesample.xml +#/opt/share/process-info/cmsample.ini +#/usr/share/license/%{name} diff --git a/resource/csdk/connectivity/src/adapter_util/caadapterutils.c b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c new file mode 100644 index 0000000..915078e --- /dev/null +++ b/resource/csdk/connectivity/src/adapter_util/caadapterutils.c @@ -0,0 +1,202 @@ +/****************************************************************** + * + * 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 "caadapterutils.h" + +#include +#ifndef __ARDUINO__ +#include "oic_malloc.h" +#endif //#ifndef __ARDUINO__ +#define CA_ADAPTER_UTILS_TAG "CA_ADAPTER_UTILS" + +CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type, const char *address, + const char *interfaceName) +{ + CALocalConnectivity_t *info = (CALocalConnectivity_t *) OICMalloc( + sizeof(CALocalConnectivity_t)); + if (NULL == info) + { + OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !"); + return NULL; + } + memset(info, 0, sizeof(CALocalConnectivity_t)); + + info->type = type; + if (address && strlen(address)) + { + if (CA_EDR == type) + { + strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1); + info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if (CA_LE == type) + { + strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1); + info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if (CA_WIFI == type || CA_ETHERNET == type) + { + strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1); + info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0'; + } + } + + return info; +} + +CALocalConnectivity_t *CAAdapterCopyLocalEndpoint(CALocalConnectivity_t *connectivity) +{ + VERIFY_NON_NULL_RET(connectivity, CA_ADAPTER_UTILS_TAG, "connectivity is NULL", NULL); + + CALocalConnectivity_t *info = (CALocalConnectivity_t *) OICMalloc( + sizeof(CALocalConnectivity_t)); + if (NULL == info) + { + OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !"); + return NULL; + } + memset(info, 0, sizeof(CALocalConnectivity_t)); + + info->type = connectivity->type; + if (CA_EDR == info->type && strlen(connectivity->addressInfo.BT.btMacAddress)) + { + strncpy(info->addressInfo.BT.btMacAddress, connectivity->addressInfo.BT.btMacAddress, + CA_MACADDR_SIZE - 1); + info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if (CA_LE == info->type && strlen(connectivity->addressInfo.LE.leMacAddress)) + { + strncpy(info->addressInfo.LE.leMacAddress, connectivity->addressInfo.LE.leMacAddress, + CA_MACADDR_SIZE - 1); + info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if ((CA_WIFI == info->type || CA_ETHERNET == info->type) + && strlen(connectivity->addressInfo.IP.ipAddress)) + { + strncpy(info->addressInfo.IP.ipAddress, connectivity->addressInfo.IP.ipAddress, + CA_IPADDR_SIZE - 1); + info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0'; + } + + return info; +} + +void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndpoint) +{ + if (localEndpoint) + { + OICFree(localEndpoint); + } +} + +CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type, const char *address, + const char *resourceUri) +{ + CARemoteEndpoint_t *info = (CARemoteEndpoint_t *) OICMalloc(sizeof(CARemoteEndpoint_t)); + if (NULL == info) + { + OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !"); + return NULL; + } + memset(info, 0, sizeof(CARemoteEndpoint_t)); + + info->connectivityType = type; + if (address && strlen(address)) + { + if (CA_EDR == type) + { + strncpy(info->addressInfo.BT.btMacAddress, address, CA_MACADDR_SIZE - 1); + info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if (CA_LE == info->connectivityType) + { + strncpy(info->addressInfo.LE.leMacAddress, address, CA_MACADDR_SIZE - 1); + info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if (CA_WIFI == type || CA_ETHERNET == type) + { + strncpy(info->addressInfo.IP.ipAddress, address, CA_IPADDR_SIZE - 1); + info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0'; + } + } + + if (resourceUri && strlen(resourceUri)) + { + info->resourceUri = OICStrdup(resourceUri); + } + + return info; +} + +CARemoteEndpoint_t *CAAdapterCopyRemoteEndpoint(const CARemoteEndpoint_t *remoteEndpoint) +{ + VERIFY_NON_NULL_RET(remoteEndpoint, CA_ADAPTER_UTILS_TAG, "Remote endpoint is NULL", NULL); + + CARemoteEndpoint_t *info = (CARemoteEndpoint_t *) OICMalloc(sizeof(CARemoteEndpoint_t)); + if (NULL == info) + { + OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "Memory allocation failed !"); + return NULL; + } + memset(info, 0, sizeof(CARemoteEndpoint_t)); + + info->connectivityType = remoteEndpoint->connectivityType; + if (CA_EDR == info->connectivityType && strlen(remoteEndpoint->addressInfo.BT.btMacAddress)) + { + strncpy(info->addressInfo.BT.btMacAddress, remoteEndpoint->addressInfo.BT.btMacAddress, + CA_MACADDR_SIZE - 1); + info->addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if (CA_LE == info->connectivityType && strlen(remoteEndpoint->addressInfo.LE.leMacAddress)) + { + strncpy(info->addressInfo.LE.leMacAddress, remoteEndpoint->addressInfo.LE.leMacAddress, + CA_MACADDR_SIZE - 1); + info->addressInfo.LE.leMacAddress[CA_MACADDR_SIZE - 1] = '\0'; + } + else if ((CA_WIFI == info->connectivityType || CA_ETHERNET == info->connectivityType) + && strlen(remoteEndpoint->addressInfo.IP.ipAddress)) + { + strncpy(info->addressInfo.IP.ipAddress, remoteEndpoint->addressInfo.IP.ipAddress, + CA_IPADDR_SIZE - 1); + info->addressInfo.IP.ipAddress[CA_IPADDR_SIZE - 1] = '\0'; + info->addressInfo.IP.port = remoteEndpoint->addressInfo.IP.port; + } + + if (remoteEndpoint->resourceUri && strlen(remoteEndpoint->resourceUri)) + { + info->resourceUri = OICStrdup(remoteEndpoint->resourceUri); + } + + return info; +} + +void CAAdapterFreeRemoteEndpoint(CARemoteEndpoint_t *remoteEndpoint) +{ + if (remoteEndpoint) + { + if (remoteEndpoint->resourceUri) + { + OICFree(remoteEndpoint->resourceUri); + } + + OICFree(remoteEndpoint); + } +} + diff --git a/resource/csdk/connectivity/src/adapter_util/camessagequeue.c b/resource/csdk/connectivity/src/adapter_util/camessagequeue.c new file mode 100644 index 0000000..2543d30 --- /dev/null +++ b/resource/csdk/connectivity/src/adapter_util/camessagequeue.c @@ -0,0 +1,195 @@ +/****************************************************************** + * + * 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->begin = NULL; + queuePtr->end = NULL; + *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->queueMutex, TAG, "Invalid queue mutex"); + CAAdapterMessage_t *messagePtr = NULL; + CAAdapterMessage_t *toRemove = NULL; + + u_mutex_lock(queueHandle->queueMutex); + messagePtr = queueHandle->begin; + while (messagePtr) + { + toRemove = messagePtr; + messagePtr = messagePtr->next; + CAAdapterFreeMessage(toRemove); + } + + queueHandle->begin = NULL; + queueHandle->end = NULL; + 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->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.!!"); + OICFree(adapterMessage->data); + CAAdapterFreeMessage(adapterMessage); + return CA_MEMORY_ALLOC_FAILED; + } + } + //Insert at end of queue + u_mutex_lock(queueHandle->queueMutex); + if (queueHandle->end) + { + queueHandle->end->next = adapterMessage; + queueHandle->end = adapterMessage; + } + else + { + queueHandle->begin = adapterMessage; + queueHandle->end = adapterMessage; + } + u_mutex_unlock(queueHandle->queueMutex); + OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; +} + +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->queueMutex, TAG, "Invalid queue mutex"); + VERIFY_NON_NULL(message, TAG, "Invalid message handle"); + u_mutex_lock(queueHandle->queueMutex); + if (queueHandle->begin) + { + *message = queueHandle->begin; + queueHandle->begin = queueHandle->begin->next; + if (queueHandle->begin == NULL) + { + queueHandle->end = NULL; + } + // keep next as NULL for upper layer + (*message)->next = NULL; + } + else + { + u_mutex_unlock(queueHandle->queueMutex); + return CA_STATUS_FAILED; + } + u_mutex_unlock(queueHandle->queueMutex); + OIC_LOG(DEBUG, TAG, "OUT"); + return CA_STATUS_OK; +} + 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 3a31a81..28efbc5 100644 --- a/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c +++ b/resource/csdk/connectivity/src/bt_edr_adapter/linux/caedradapter.c @@ -28,13 +28,16 @@ #define TAG PCF("CA") static CANetworkPacketReceivedCallback gEDRReceivedCallback = NULL; +static u_thread_pool_t gThreadPoolHandle = NULL; CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback) + CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle) { OIC_LOG_V(DEBUG, TAG, "CAInitializeEDR"); gEDRReceivedCallback = reqRespCallback; + gThreadPoolHandle = handle; // register handlers CAConnectivityHandler_t handler; @@ -106,7 +109,7 @@ uint32_t CASendEDRNotification(const CARemoteEndpoint_t* endpoint, void* data, u return 0; } -CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivityt_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 new file mode 100644 index 0000000..1d86e88 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.c @@ -0,0 +1,63 @@ +/****************************************************************** + * + * 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 cabtclient.c + * @brief This file provides the APIs to establish RFCOMM connection with remote bluetooth device + */ + +#include "cabtclient.h" +#include "caadapterutils.h" +#include "cabtutils.h" +#include "logger.h" + +CAResult_t CABTClientConnect(const char *remoteAddress, const char *serviceUUID) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + + VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null"); + VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "Service UUID is null"); + + if (0 >= strlen(remoteAddress)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Empty remote address"); + return CA_STATUS_INVALID_PARAM; + } + + if (0 >= strlen(serviceUUID)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Empty service uuid"); + return CA_STATUS_INVALID_PARAM; + } + + if (BT_ERROR_NONE != (err = bt_socket_connect_rfcomm(remoteAddress, serviceUUID))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, + "Failed to connect!, address [%s] uuid [%s] error num [%x]", + remoteAddress, serviceUUID, err); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.h new file mode 100644 index 0000000..a385488 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.h @@ -0,0 +1,58 @@ +/****************************************************************** + * + * 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 cabtclient.h + * @brief This file provides the APIs to establish RFCOMM connection with remote bluetooth device + */ + +#ifndef __CA_BT_CLIENT_H_ +#define __CA_BT_CLIENT_H_ + +#include +#include + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @fn CABTClientConnect + * @brief Establishes RFCOMM connection with remote bluetooth device + * + * @param remoteAddress The address of remote bluetooth device to which connection needs to be established + * @param serviceUUID The UUID of service to which RFCOMM connection needs to established + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABTClientConnect(const char *remoteAddress, const char *serviceUUID); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //__CA_BT_CLIENT_H_ \ No newline at end of file diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c new file mode 100644 index 0000000..f5e503b --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.c @@ -0,0 +1,400 @@ +/****************************************************************** + * + * 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 cabtdevicelist.c + * @brief This file provides APIs to access the discovered bluetooth device list + */ + +#include "cabtdevicelist.h" +#include "caadapterutils.h" +#include "cabtutils.h" +#include "logger.h" + +CAResult_t CAAddBTDeviceToList(BTDeviceList **deviceList, BTDevice *device) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null"); + VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null"); + + BTDeviceList *node = (BTDeviceList *) OICMalloc(sizeof(BTDeviceList)); + if (NULL == node) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (device list)!"); + return CA_MEMORY_ALLOC_FAILED; + } + + node->device = device; + node->next = NULL; + + if (NULL == *deviceList) //Empty list + { + *deviceList = node; + } + else //Add at front end + { + node->next = *deviceList; + *deviceList = node; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CARemoveBTDeviceFromList(BTDeviceList **deviceList, const char *remoteAddress) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null"); + VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null"); + + BTDeviceList *cur = NULL; + BTDeviceList *prev = NULL; + + cur = *deviceList; + while (cur != NULL) + { + if (!strcasecmp(cur->device->remoteAddress, remoteAddress)) + { + if (cur == *deviceList) + { + *deviceList = cur->next; + + cur->next = NULL; + CAFreeBTDeviceList(cur); + return CA_STATUS_OK; + } + else + { + prev->next = cur->next; + + cur->next = NULL; + CAFreeBTDeviceList(cur); + return CA_STATUS_OK; + } + } + else + { + prev = cur; + cur = cur->next; + } + } + + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device not in the list !"); + return CA_STATUS_FAILED; +} + +CAResult_t CAGetBTDevice(BTDeviceList *deviceList, const char *remoteAddress, BTDevice **device) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null"); + VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null"); + VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null"); + + BTDeviceList *cur = deviceList; + *device = NULL; + while (cur != NULL) + { + if (!strcasecmp(cur->device->remoteAddress, remoteAddress)) + { + *device = cur->device; + return CA_STATUS_OK; + } + + cur = cur->next; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT [Device not found!]"); + return CA_STATUS_FAILED; +} + +CAResult_t CAGetBTDeviceBySocketId(BTDeviceList *deviceList, int32_t socketFd, BTDevice **device) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(deviceList, BLUETOOTH_ADAPTER_TAG, "Device list is null"); + VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null"); + + BTDeviceList *cur = deviceList; + *device = NULL; + while (cur != NULL) + { + if (cur->device->socketFD == socketFd) + { + *device = cur->device; + return CA_STATUS_OK; + } + + cur = cur->next; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_FAILED; +} + +CAResult_t CACreateBTDevice(const char *remoteAddress, const char *uuid, BTDevice **device) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null"); + VERIFY_NON_NULL(uuid, BLUETOOTH_ADAPTER_TAG, "uuid is null"); + VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null"); + + *device = (BTDevice *) OICMalloc(sizeof(BTDevice)); + if (NULL == *device) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (device)!"); + return CA_MEMORY_ALLOC_FAILED; + } + + //Copy bluetooth address + if (remoteAddress && strlen(remoteAddress)) + { + (*device)->remoteAddress = strndup(remoteAddress, strlen(remoteAddress)); + if (NULL == (*device)->remoteAddress) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Out of memory (remote address)!"); + + OICFree(*device); + *device = NULL; + return CA_MEMORY_ALLOC_FAILED; + } + } + + //Copy OIC service uuid + if (uuid && strlen(uuid)) + { + (*device)->serviceUUID = strndup(uuid, strlen(uuid)); + if (NULL == (*device)->serviceUUID) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, + "[createBTDevice] Out of memory (service uuid)!"); + + OICFree((*device)->remoteAddress); + OICFree(*device); + *device = NULL; + return CA_MEMORY_ALLOC_FAILED; + } + } + + (*device)->socketFD = -1; + (*device)->pendingDataList = NULL; + (*device)->serviceSearched = 0; + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CACreateAndAddToDeviceList(BTDeviceList **devicList, const char *remoteAddress, + const char *serviceUUID, BTDevice **device) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(devicList, BLUETOOTH_ADAPTER_TAG, "Device list is null"); + VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null"); + VERIFY_NON_NULL(device, BLUETOOTH_ADAPTER_TAG, "Device is null"); + + if (CA_STATUS_OK != CACreateBTDevice(remoteAddress, serviceUUID, device) || NULL == *device) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid or Not bonded device!"); + return CA_STATUS_FAILED; + } + + if (CA_STATUS_OK != CAAddBTDeviceToList(devicList, *device)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add in list!"); + + //Remove created BTDevice + CAFreeBTDevice(*device); + *device = NULL; + + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CAFreeBTDeviceList(BTDeviceList *deviceList) +{ + while (deviceList) + { + BTDeviceList *curList = deviceList; + deviceList = deviceList->next; + + CAFreeBTDevice(curList->device); + OICFree(curList); + } +} + +void CAFreeBTDevice(BTDevice *device) +{ + if (device) + { + if (device->remoteAddress) + { + OICFree(device->remoteAddress); + } + + if (device->serviceUUID) + { + OICFree(device->serviceUUID); + } + + if (device->pendingDataList) + { + CARemoveAllDataFromDevicePendingList(&device->pendingDataList); + } + + OICFree(device); + } +} + +CAResult_t CAAddDataToDevicePendingList(BTDataList **dataList, void *data, uint32_t dataLen) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(dataList, BLUETOOTH_ADAPTER_TAG, "Data list is null"); + VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null"); + + if (0 == dataLen) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: data length is zero!"); + return CA_STATUS_INVALID_PARAM; + } + + BTDataList *pending_data = (BTDataList *) OICMalloc(sizeof(BTDataList)); + if (NULL == pending_data) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "OICMalloc failed (data list)!"); + return CA_MEMORY_ALLOC_FAILED; + } + + pending_data->data = (BTData *) OICMalloc(sizeof(BTData)); + if (NULL == pending_data->data) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "OICMalloc failed (data node)!"); + + OICFree(pending_data); + return CA_MEMORY_ALLOC_FAILED; + } + pending_data->next = NULL; + + pending_data->data->data = (void *) OICMalloc(dataLen); //data + if (NULL == pending_data->data->data) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "OICMalloc failed (data)!"); + + OICFree(pending_data->data); + OICFree(pending_data); + return CA_MEMORY_ALLOC_FAILED; + } + + memcpy(pending_data->data->data, data, dataLen); + pending_data->data->dataLength = dataLen; + + if (NULL == *dataList) //Empty list + { + *dataList = pending_data; + } + else //Add at rear end + { + BTDataList *curList = *dataList; + while (curList->next != NULL) + { + curList = curList->next; + } + + curList->next = pending_data; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CARemoveDataFromDevicePendingList(BTDataList **dataList) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(dataList, BLUETOOTH_ADAPTER_TAG, "Data list is null"); + + BTDataList *cur = NULL; + BTDataList *prev = NULL; + + cur = *dataList; + if (NULL != cur->next) //next node present in list + { + prev = cur; + cur = cur->next; + CAFreeDataFromBTDataList(prev); + *dataList = cur; + } + else //last node + { + CAFreeDataFromBTDataList(cur); + *dataList = NULL; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CARemoveAllDataFromDevicePendingList(BTDataList **dataList) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(dataList, BLUETOOTH_ADAPTER_TAG, "Data list is null"); + + BTDataList *cur = NULL; + BTDataList *prev = NULL; + + cur = *dataList; + while (cur) + { + prev = cur; + cur = cur->next; + CAFreeDataFromBTDataList(prev); + } + + *dataList = NULL; + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CAFreeDataFromBTDataList(BTDataList *dataList) +{ + if (dataList) + { + if (dataList->data) + { + if (dataList->data->data) + { + OICFree(dataList->data->data); + } + OICFree(dataList->data); + } + OICFree(dataList); + dataList = NULL; + } +} + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h new file mode 100644 index 0000000..2357498 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtdevicelist.h @@ -0,0 +1,99 @@ +/****************************************************************** + * + * 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 cabtdevicelist.h + * @brief This file provides APIs to access the discovered bluetooth device list + */ + +#ifndef __CA_BT_DEVICE_LIST_H_ +#define __CA_BT_DEVICE_LIST_H_ + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @struct BTData + * @brief Structure to maintain the data needs to send to peer Bluetooth device. + */ +typedef struct +{ + void *data; /**< Data to be send to peer Bluetooth device. */ + uint32_t dataLength; /**< Length of the data. */ +} BTData; + +/** + * @struct BTDataList + * @brief Structure to maintain list of data needs to send to peer Bluetooth device. + */ +typedef struct _BTDataList +{ + BTData *data; /**< Data to be send to peer Bluetooth device. */ + struct _BTDataList *next;/**< Reference to next data in list. */ +} BTDataList; + +/** + * @struct BTDevice + * @brief Structure to maintain information of peer Bluetooth device. + */ +typedef struct +{ + char *remoteAddress; /**< Address of peer Bluetooth device. */ + char *serviceUUID; /**< OIC service UUID running in peer Bluetooth device. */ + int32_t socketFD; /**< RfComm connection socket FD. */ + BTDataList *pendingDataList;/**< List of data needs to send to peer Bluetooth device. */ + uint32_t serviceSearched; /**< Flag to indicate the status of service search. */ +} BTDevice; + +/** + * @struct BTDeviceList + * @brief Structure to maintain list of peer Bluetooth device information. + */ +typedef struct _BTDeviceList +{ + BTDevice *device; /**< Bluetooth device information. */ + struct _BTDeviceList *next; /**< Reference to next device information. */ +} BTDeviceList; + +CAResult_t CAAddBTDeviceToList(BTDeviceList **deviceList, BTDevice *device); +CAResult_t CARemoveBTDeviceFromList(BTDeviceList **deviceList, const char *remoteAddress); +CAResult_t CAGetBTDevice(BTDeviceList *deviceList, const char *remoteAddress, BTDevice **device); +CAResult_t CAGetBTDeviceBySocketId(BTDeviceList *deviceList, int32_t socket_id, BTDevice **device); +CAResult_t CACreateBTDevice(const char *remoteAddress, const char *uuid, BTDevice **device); +CAResult_t CACreateAndAddToDeviceList(BTDeviceList **deviceList, const char *remoteAddress, + const char *serviceUUID, BTDevice **device); +void CAFreeBTDeviceList(BTDeviceList *deviceList); +void CAFreeBTDevice(BTDevice *device); + +CAResult_t CAAddDataToDevicePendingList(BTDataList **dataList, void *data, uint32_t data_len); +CAResult_t CARemoveDataFromDevicePendingList(BTDataList **dataList); +CAResult_t CARemoveAllDataFromDevicePendingList(BTDataList **dataList); +void CAFreeDataFromBTDataList(BTDataList *dataList); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //__CA_BT_DEVICE_LIST_H_ + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c new file mode 100644 index 0000000..513550a --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.c @@ -0,0 +1,57 @@ +/****************************************************************** + * + * 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 cabtendpoint.c + * @brief This file provides the APIs to send data on established RFCOMM connections. + */ + +#include "cabtendpoint.h" +#include "caadapterutils.h" +#include "cabtutils.h" +#include "logger.h" + +CAResult_t CABTSendData(const int32_t serverFD, const void *data, const uint32_t dataLength, + uint32_t *sentDataLen) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null"); + VERIFY_NON_NULL(sentDataLen, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null"); + + if (0 > serverFD) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Negative socket id"); + return CA_STATUS_INVALID_PARAM; + } + + int dataLen = 0; + dataLen = bt_socket_send_data(serverFD, (const char *)data, dataLength); + if (dataLen == -1) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "sending data failed!, soketid [%d]", serverFD); + *sentDataLen = 0; + return CA_STATUS_FAILED; + } + + *sentDataLen = dataLen; + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.h new file mode 100644 index 0000000..31c38e5 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtendpoint.h @@ -0,0 +1,61 @@ +/****************************************************************** + * + * 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 cabtendpoint.h + * @brief This file provides the APIs to send data on established RFCOMM connections. + */ + +#ifndef __CA_BT_ENDPOINT_H_ +#define __CA_BT_ENDPOINT_H_ + +#include + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @fn CABTSendData + * @brief Send data over RFCOMM connection + * + * @param serverFD The RFCOMM connection socket file descriptor + * @param data The data needs to be sent + * @param dataLength The length of data + * @param sentDataLen The length of data which actually sent successful + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABTSendData(const int32_t serverFD, const void *data, const uint32_t dataLength, + uint32_t *sentDataLen); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //__CA_BT_ENDPOINT_H_ + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c new file mode 100644 index 0000000..4d9d079 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c @@ -0,0 +1,1193 @@ +/****************************************************************** + * + * 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 cabtmanager.c + * @brief This file provides the APIs to control Bluetooth transport + */ + +#include "cabtmanager.h" +#include "cabtclient.h" +#include "cabtserver.h" +#include "cabtendpoint.h" +#include "cabtdevicelist.h" +#include "cabtutils.h" +#include "caadapterutils.h" +#include "camessagequeue.h" + + +typedef struct +{ + CALocalConnectivity_t *info; + CANetworkStatus_t status; +} CABTNetworkEvent; + +typedef struct +{ + void *data; + int32_t dataLen; + CARemoteEndpoint_t *remoteEndpoint; +} CABTMessage; + +/** + * @var gNetworkPacketReceivedCallback + * @brief Maintains the callback to be notified on receival of network packets from other + * Bluetooth devices. + */ +static CANetworkPacketReceivedCallback gNetworkPacketReceivedCallback = NULL; + +/** + * @var gNetworkChangeCallback + * @brief Maintains the callback to be notified on local bluetooth adapter status change. + */ +static CANetworkChangeCallback gNetworkChangeCallback = NULL; + +/** + * @var gBTDeviceListMutex + * @brief Mutex to synchronize the access to Bluetooth device information list. + */ +static u_mutex gBTDeviceListMutex = NULL; + +/** + * @var gBTDeviceList + * @brief Peer Bluetooth device information list. + */ +static BTDeviceList *gBTDeviceList = NULL; + +/** + * @var gLocalConnectivity + * @brief Information of local Bluetooth adapter. + */ +static CALocalConnectivity_t *gLocalConnectivity = NULL; + +/** + * @var gBTThreadPool + * @brief Reference to threadpool. + */ +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 gSendDataMutex + * @brief Mutex to synchronize access to data send queue. + */ +static u_mutex gSendDataMutex = NULL; + +/** + * @var gSendDataCond + * @brief Condition used for notifying handler the presence of data in send queue. + */ +static u_cond gSendDataCond = NULL; + +/** + * @var gDataSendHandlerState + * @brief Stop condition of sendhandler. + */ +static CABool_t gDataSendHandlerState = CA_FALSE; + +/** + * @fn CABTAdapterStateChangeCallback + * @brief This callback is registered to receive bluetooth adapter state changes. + */ +static void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState, + void *userData); + +/** + * @fn CABTSocketConnectionStateCallback + * @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_s *connection, void *userData); + +/** + * @fn CABTDataRecvCallback + * @brief This callback is registered to recieve data on any open RFCOMM connection. + */ +static void CABTDataRecvCallback(bt_socket_received_data_s *data, void *userData); + +/** + * @fn CABTDeviceDiscoveryCallback + * @brief This callback is registered to recieve all bluetooth nearby devices when device + * scan is initiated. + */ +static void CABTDeviceDiscoveryCallback(int result, + bt_adapter_device_discovery_state_e discoveryState, + bt_adapter_device_discovery_info_s *discoveryInfo, void *userData); + +/** + * @fn CABTServiceSearchedCallback + * @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); + + +/** + * @fn CABTManagerInitializeQueues + * @brief This function creates send and receive message queues. + */ +static CAResult_t CABTManagerInitializeQueues(void); + +/** + * @fn CABTManagerTerminateQueues + * @brief This function releases send and receive message queues. + */ +static void CABTManagerTerminateQueues(void); + +/** + * @fn CABTManagerInitializeMutex + * @brief This function creates mutex. + */ +static void CABTManagerInitializeMutex(void); + +/** + * @fn CABTManagerTerminateMutex + * @brief This function frees mutex. + */ +static void CABTManagerTerminateMutex(void); + +/** + * @fn CABTManagerDataSendHandler + * @brief This function handles message from send queue. + */ +static void CABTManagerDataSendHandler(void *context); + +/** + * @fn CABTManagerSendUnicastData + * @brief This function send data to specified remote bluetooth device. + */ +static CAResult_t CABTManagerSendUnicastData(const char *remoteAddress, const char *serviceUUID, + void *data, uint32_t dataLength, uint32_t *sentLength); + +/** + * @fn CABTManagerSendMulticastData + * @brief This function send data to all bluetooth devices running OIC service. + */ +static CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data, + uint32_t dataLength, + uint32_t *sentLength); + +/** + * @fn CABTStartServiceSearch + * @brief This function search for OIC service for remote Bluetooth device. + */ +static CAResult_t CABTStartServiceSearch(const char *remoteAddress); + +/** + * @fn CABTNotifyNetworkStauts + * @brief This function creates notification task for network adapter status and add it to thread pool. + */ +static CAResult_t CABTNotifyNetworkStauts(CANetworkStatus_t status); + +/** + * @fn CABTOnNetworkStautsChanged + * @brief This is task callback function for notifying network adapter status to upper layer. + */ +static void CABTOnNetworkStautsChanged(void *context); + +/** + * @fn CABTCreateNetworkEvent + * @brief Creates instance of CABTNetworkEvent. + */ +static CABTNetworkEvent *CABTCreateNetworkEvent(CALocalConnectivity_t *connectivity, + CANetworkStatus_t status); + +/** + * @fn CABTFreeNetworkEvent + * @brief destroy instance of CABTNetworkEvent. + */ +static void CABTFreeNetworkEvent(CABTNetworkEvent *event); + + +CAResult_t CABTManagerIntialize(u_thread_pool_t threadPool) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + + //Initialize Bluetooth service + if (BT_ERROR_NONE != (err = bt_initialize())) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth initialization failed!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + + //Set bluetooth adapter sate change callback + if (BT_ERROR_NONE != (err = bt_adapter_set_state_changed_cb(CABTAdapterStateChangeCallback, NULL))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, + "Setting bluetooth state change callback failed!, error num [%x]", err); + + //Deinitialize the Bluetooth stack + bt_deinitialize(); + return CA_STATUS_FAILED; + } + + //Get Bluetooth adapter state + bt_adapter_state_e adapterState; + if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth get state failed!, error num [%x]", + err); + + //Reset the adapter state change callback + bt_adapter_unset_state_changed_cb(); + + //Deinitialize the Bluetooth stack + bt_deinitialize(); + return CA_STATUS_FAILED; + } + + //Initialize Send/Receive data message queues + if (CA_STATUS_OK != CABTManagerInitializeQueues()) + { + //Reset the adapter state change callback + bt_adapter_unset_state_changed_cb(); + + //Deinitialize the Bluetooth stack + bt_deinitialize(); + return CA_STATUS_FAILED; + } + + //Create and initialize the mutex + CABTManagerInitializeMutex(); + + if (NULL == gBTThreadPool) + { + gBTThreadPool = threadPool; + } + + if (BT_ADAPTER_DISABLED == adapterState) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!"); + return CA_ADAPTER_NOT_ENABLED; + } + + //Notity to upper layer + CABTNotifyNetworkStauts(CA_INTERFACE_UP); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CABTManagerTerminate(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + gNetworkPacketReceivedCallback = NULL; + gNetworkChangeCallback = NULL; + + //Stop the adpater + CABTManagerStop(); + + //Unset bluetooth adapter callbacks + bt_adapter_unset_state_changed_cb(); + + //Terminate Bluetooth service + bt_deinitialize(); + + //Terminate thread pool + gBTThreadPool = NULL; + + //Free LocalConnectivity information + CAAdapterFreeLocalEndpoint(gLocalConnectivity); + gLocalConnectivity = NULL; + + //Free BTDevices list + if (gBTDeviceListMutex) + { + u_mutex_lock(gBTDeviceListMutex); + CAFreeBTDeviceList(gBTDeviceList); + gBTDeviceList = NULL; + u_mutex_unlock(gBTDeviceListMutex); + } + + //Free the mutex + CABTManagerTerminateMutex(); + + //Terminate Send/Receive data messages queues + CABTManagerTerminateQueues(); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +CAResult_t CABTManagerStart(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + bool isDiscoveryStarted = false; + + //Get Bluetooth adapter state + bt_adapter_state_e adapterState; + if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth get state failed!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + + if (BT_ADAPTER_DISABLED == adapterState) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Bluetooth adapter is disabled!"); + return CA_ADAPTER_NOT_ENABLED; + } + + //Register for discovery and rfcomm socket connection callbacks + bt_adapter_set_device_discovery_state_changed_cb(CABTDeviceDiscoveryCallback, NULL); + bt_device_set_service_searched_cb(CABTServiceSearchedCallback, NULL); + bt_socket_set_connection_state_changed_cb(CABTSocketConnectionStateCallback, NULL); + bt_socket_set_data_received_cb(CABTDataRecvCallback, NULL); + + if (BT_ERROR_NONE != (err = bt_adapter_is_discovering(&isDiscoveryStarted))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + + //Start device discovery if its not started + if (false == isDiscoveryStarted ) + { + if (BT_ERROR_NONE != (err = bt_adapter_start_device_discovery())) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device discovery failed!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + } + + //Start data send and receive handlers + gDataSendHandlerState = CA_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!"); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CABTManagerStop(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + bool isDiscoveryStarted = false; + + //Stop data send and receive handlers + if (gSendDataMutex && gSendDataCond && gDataSendHandlerState) + { + u_mutex_lock(gSendDataMutex); + gDataSendHandlerState = CA_FALSE; + u_cond_signal(gSendDataCond); + u_mutex_unlock(gSendDataMutex); + } + + //Check discovery status + if (BT_ERROR_NONE != (err = bt_adapter_is_discovering(&isDiscoveryStarted))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to get discovery state!, error num [%x]", + err); + return; + } + + //stop the device discovery process + if (true == isDiscoveryStarted) + { + 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]", + err); + } + } + + //reset bluetooth adapter callbacks + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Resetting the callbacks"); + bt_adapter_unset_device_discovery_state_changed_cb(); + bt_device_unset_service_searched_cb(); + bt_socket_unset_connection_state_changed_cb(); + bt_socket_unset_data_received_cb(); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +void CABTManagerSetPacketReceivedCallback(CANetworkPacketReceivedCallback packetReceivedCallback) +{ + gNetworkPacketReceivedCallback = packetReceivedCallback; +} + +void CABTManagerSetNetworkChangeCallback(CANetworkChangeCallback networkChangeCallback) +{ + gNetworkChangeCallback = networkChangeCallback; +} + +CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUID, + void *data, uint32_t dataLength, uint32_t *sentLength) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + //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"); + + VERIFY_NON_NULL_RET(gSendDataQueue, BLUETOOTH_ADAPTER_TAG, "Send data queue is NULL", + CA_STATUS_FAILED); + VERIFY_NON_NULL_RET(gSendDataMutex, BLUETOOTH_ADAPTER_TAG, "Send data queue mutex is NULL", + CA_STATUS_FAILED); + VERIFY_NON_NULL_RET(gSendDataCond, BLUETOOTH_ADAPTER_TAG, "Send data queue condition is NULL", + CA_STATUS_FAILED); + + //Add message to data queue + CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress, + serviceUUID); + if (NULL == remoteEndpoint) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create remote endpoint !"); + 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 !"); + return CA_STATUS_FAILED; + } + + 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) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + return CABTServerStart(serviceUUID, serverID); +} + +CAResult_t CABTManagerStopServer(const int32_t serverID) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + return CABTServerStop(serverID); +} + +CAResult_t CABTManagerGetInterface(CALocalConnectivity_t **info) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + char *localAddress = NULL; + + //Input validation + VERIFY_NON_NULL(info, BLUETOOTH_ADAPTER_TAG, "LocalConnectivity info is null"); + + //Get the bluetooth adapter local address + if (BT_ERROR_NONE != (err = bt_adapter_get_address(&localAddress))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, + "Getting local adapter address failed!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + + //Create network info + *info = CAAdapterCreateLocalEndpoint(CA_EDR, localAddress, NULL); + if (NULL == *info) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create LocalConnectivity instance!"); + + OICFree(localAddress); + return CA_MEMORY_ALLOC_FAILED; + } + + OICFree(localAddress); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CABTManagerReadData(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +CAResult_t CABTManagerInitializeQueues(void) +{ + if (NULL == gSendDataQueue) + { + if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gSendDataQueue)) + { + return CA_STATUS_FAILED; + } + } +} + +void CABTManagerTerminateQueues(void) +{ + if (gSendDataQueue) + { + CAAdapterTerminateMessageQueue(gSendDataQueue); + gSendDataQueue = NULL; + } +} + +void CABTManagerInitializeMutex(void) +{ + u_mutex_init(); + if (NULL == gBTDeviceListMutex) + { + gBTDeviceListMutex = u_mutex_new(); + } + + if (NULL == gSendDataMutex) + { + gSendDataMutex = u_mutex_new(); + } + + if (NULL == gSendDataCond) + { + gSendDataCond = u_cond_new(); + } +} + +void CABTManagerTerminateMutex(void) +{ + if (gBTDeviceListMutex) + { + u_mutex_free(gBTDeviceListMutex); + gBTDeviceListMutex = NULL; + } + + if (gSendDataMutex) + { + u_mutex_free(gSendDataMutex); + gSendDataMutex = NULL; + } + + if (gSendDataCond) + { + u_cond_free(gSendDataCond); + gSendDataCond = NULL; + } +} + +void CABTManagerDataSendHandler(void *context) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + u_mutex_lock(gSendDataMutex); + while (gDataSendHandlerState) + { + CAAdapterMessage_t *message = NULL; + const char *remoteAddress = NULL; + const char *serviceUUID = NULL; + uint32_t sentLength = 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; + if (strlen(remoteAddress)) //Unicast data + { + if (CA_STATUS_OK != CABTManagerSendUnicastData(remoteAddress, serviceUUID, + message->data, message->dataLen, &sentLength)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send unicast data !"); + } + } + else //Multicast data + { + if (CA_STATUS_OK != CABTManagerSendMulticastData(serviceUUID, message->data, + message->dataLen, &sentLength)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send multicast data !"); + } + } + + //Free message + CAAdapterFreeMessage(message); + } + + //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"); + + if (CA_FALSE == gDataSendHandlerState) + { + break; + } + } + + u_mutex_unlock(gSendDataMutex); + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +CAResult_t CABTManagerSendUnicastData(const char *remoteAddress, const char *serviceUUID, + void *data, uint32_t dataLength, uint32_t *sentLength) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + BTDevice *device = NULL; + + //Input validation + VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null"); + 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"); + + if (0 >= dataLength) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Negative data length!"); + return CA_STATUS_INVALID_PARAM; + } + + //Check the connection existence with remote device + u_mutex_lock(gBTDeviceListMutex); + if (CA_STATUS_OK != CAGetBTDevice(gBTDeviceList, remoteAddress, &device)) + { + //Create new device and add to list + if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gBTDeviceList, remoteAddress, + OIC_BT_SERVICE_ID, &device)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed create device and add to list!"); + + u_mutex_unlock(gBTDeviceListMutex); + return CA_STATUS_FAILED; + } + + //Start the OIC service search newly created device + if (CA_STATUS_OK != CABTStartServiceSearch(remoteAddress)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to initiate service search!"); + + //Remove device from list + CARemoveBTDeviceFromList(&gBTDeviceList, remoteAddress); + + u_mutex_unlock(gBTDeviceListMutex); + return CA_STATUS_FAILED; + } + } + u_mutex_unlock(gBTDeviceListMutex); + + if (-1 == device->socketFD) + { + //Adding to pending list + if (CA_STATUS_OK != CAAddDataToDevicePendingList(&device->pendingDataList, data, + dataLength)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add data to pending list!"); + + //Remove device from list + CARemoveBTDeviceFromList(&gBTDeviceList, remoteAddress); + return CA_STATUS_FAILED; + } + + //Make a rfcomm connection with remote BT Device + if (1 == device->serviceSearched && + CA_STATUS_OK != CABTClientConnect(remoteAddress, serviceUUID)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to make RFCOMM connection!"); + + //Remove device from list + CARemoveBTDeviceFromList(&gBTDeviceList, remoteAddress); + return CA_STATUS_FAILED; + } + *sentLength = dataLength; + } + else + { + if (CA_STATUS_OK != CABTSendData(device->socketFD, data, dataLength, sentLength)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send data!"); + return CA_STATUS_FAILED; + } + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CABTManagerSendMulticastData(const char *serviceUUID, void *data, uint32_t dataLength, + uint32_t *sentLength) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + BTDeviceList *cur = NULL; + + //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"); + + if (0 >= dataLength) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Negative data length!"); + return CA_STATUS_INVALID_PARAM; + } + + *sentLength = dataLength; + + //Send the packet to all OIC devices + u_mutex_lock(gBTDeviceListMutex); + cur = gBTDeviceList; + while (cur != NULL) + { + BTDevice *device = cur->device; + cur = cur->next; + + if (-1 == device->socketFD) + { + //Check if the device service search is finished + if (0 == device->serviceSearched) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device services are still unknown!"); + continue; + } + + //Adding to pendding list + if (CA_STATUS_OK != CAAddDataToDevicePendingList(&device->pendingDataList, data, + dataLength)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add data to pending list !"); + continue; + } + + //Make a rfcomm connection with remote BT Device + if (CA_STATUS_OK != CABTClientConnect(device->remoteAddress, device->serviceUUID)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to make RFCOMM connection !"); + + //Remove the data which added to pending list + CARemoveDataFromDevicePendingList(&device->pendingDataList); + continue; + } + } + else + { + if (CA_STATUS_OK != CABTSendData(device->socketFD, data, dataLength, sentLength)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send data to [%s] !", + device->remoteAddress); + } + } + } + u_mutex_unlock(gBTDeviceListMutex); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CABTStartServiceSearch(const char *remoteAddress) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + + //Input validation + VERIFY_NON_NULL(remoteAddress, BLUETOOTH_ADAPTER_TAG, "Remote address is null"); + if (0 == strlen(remoteAddress)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Remote address is empty!"); + return CA_STATUS_INVALID_PARAM; + } + + //Start searching for OIC service + if (BT_ERROR_NONE != (err = bt_device_start_service_search(remoteAddress))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Get bonded device failed!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CABTAdapterStateChangeCallback(int result, bt_adapter_state_e adapterState, void *userData) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + if (BT_ADAPTER_ENABLED == adapterState) + { + //Notity to upper layer + CABTNotifyNetworkStauts(CA_INTERFACE_UP); + } + else if (BT_ADAPTER_DISABLED == adapterState) + { + //Notity to upper layer + CABTNotifyNetworkStauts(CA_INTERFACE_DOWN); + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +void CABTSocketConnectionStateCallback(int result, bt_socket_connection_state_e connectionState, + bt_socket_connection_s *connection, void *userData) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + BTDevice *device = NULL; + + if (BT_ERROR_NONE != result || NULL == connection) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid connection state!, error num [%x]", + result); + return; + } + + switch (connectionState) + { + case BT_SOCKET_CONNECTED: + { + u_mutex_lock(gBTDeviceListMutex); + if (CA_STATUS_OK != CAGetBTDevice(gBTDeviceList, connection->remote_address, + &device)) + { + //Create the deviceinfo and add to list + if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gBTDeviceList, + connection->remote_address, OIC_BT_SERVICE_ID, &device)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed add device to list!"); + u_mutex_unlock(gBTDeviceListMutex); + return; + } + + device->socketFD = connection->socket_fd; + u_mutex_unlock(gBTDeviceListMutex); + return; + } + + device->socketFD = connection->socket_fd; + while (device->pendingDataList) + { + uint32_t sentData = 0; + BTData *btData = device->pendingDataList->data; + if (CA_STATUS_OK != CABTSendData(device->socketFD, btData->data, + btData->dataLength, &sentData)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send pending data [%s]", + device->remoteAddress); + + //Remove all the data from pending list + CARemoveAllDataFromDevicePendingList(&device->pendingDataList); + break; + } + + //Remove the data which send from pending list + CARemoveDataFromDevicePendingList(&device->pendingDataList); + } + u_mutex_unlock(gBTDeviceListMutex); + } + break; + + case BT_SOCKET_DISCONNECTED: + { + u_mutex_lock(gBTDeviceListMutex); + CARemoveBTDeviceFromList(&gBTDeviceList, connection->remote_address); + u_mutex_unlock(gBTDeviceListMutex); + } + break; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +void CABTDataRecvCallback(bt_socket_received_data_s *data, void *userData) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + BTDevice *device = NULL; + + if (NULL == data || 0 >= data->data_size) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Data is null!"); + return; + } + + if (NULL == gNetworkPacketReceivedCallback) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Callback is not registered!"); + return; + } + + //Get BT device from list + u_mutex_lock(gBTDeviceListMutex); + if (CA_STATUS_OK != CAGetBTDeviceBySocketId(gBTDeviceList, data->socket_fd, &device)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Could not find the device!"); + + u_mutex_unlock(gBTDeviceListMutex); + return; + } + u_mutex_unlock(gBTDeviceListMutex); + + //Create RemoteEndPoint + CARemoteEndpoint_t *remoteEndpoint = NULL; + remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, device->remoteAddress, + OIC_BT_SERVICE_ID); + if (NULL == remoteEndpoint) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to crate remote endpoint!"); + return; + } + + void *copyData = OICMalloc(data->data_size); + if (NULL == copyData) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed allocate memory!"); + CAAdapterFreeRemoteEndpoint(remoteEndpoint); + return; + } + memcpy(copyData, data->data, data->data_size); + + gNetworkPacketReceivedCallback(remoteEndpoint, copyData, (uint32_t)data->data_size); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +void CABTDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_e discoveryState, + bt_adapter_device_discovery_info_s *discoveryInfo, void *userData) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + BTDevice *device = NULL; + + if (BT_ERROR_NONE != result) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Received bad state!, error num [%x]", + result); + return; + } + + switch (discoveryState) + { + case BT_ADAPTER_DEVICE_DISCOVERY_STARTED: + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Discovery started!"); + } + break; + + case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED: + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Discovery finished!"); + } + break; + + case BT_ADAPTER_DEVICE_DISCOVERY_FOUND: + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Device discovered [%s]!", + discoveryInfo->remote_name); + if (CA_TRUE == CABTIsServiceSupported((const char **)discoveryInfo->service_uuid, + discoveryInfo->service_count, + OIC_BT_SERVICE_ID)) + { + //Check if the deivce is already in the list + u_mutex_lock(gBTDeviceListMutex); + if (CA_STATUS_OK == CAGetBTDevice(gBTDeviceList, discoveryInfo->remote_address, + &device)) + { + device->serviceSearched = 1; + u_mutex_unlock(gBTDeviceListMutex); + return; + } + + //Create the deviceinfo and add to list + if (CA_STATUS_OK != CACreateAndAddToDeviceList(&gBTDeviceList, + discoveryInfo->remote_address, OIC_BT_SERVICE_ID, &device)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add device to list!"); + u_mutex_unlock(gBTDeviceListMutex); + return; + } + + device->serviceSearched = 1; + u_mutex_unlock(gBTDeviceListMutex); + } + else + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Device does not support OIC service!"); + } + } + break; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +void CABTServiceSearchedCallback(int result, bt_device_sdp_info_s *sdpInfo, void *userData) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + if (NULL == sdpInfo) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "SDP info is null!"); + return; + } + + u_mutex_lock(gBTDeviceListMutex); + + BTDevice *device = NULL; + if (CA_STATUS_OK == CAGetBTDevice(gBTDeviceList, sdpInfo->remote_address, &device) + && NULL != device) + { + if (1 == device->serviceSearched) + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Service is already searched for this device!"); + u_mutex_unlock(gBTDeviceListMutex); + return; + } + + if (CA_TRUE == CABTIsServiceSupported((const char **)sdpInfo->service_uuid, + sdpInfo->service_count, OIC_BT_SERVICE_ID)) + { + device->serviceSearched = 1; + if (CA_STATUS_OK != CABTClientConnect(sdpInfo->remote_address, OIC_BT_SERVICE_ID)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to make rfcomm connection!"); + + //Remove the device from device list + CARemoveBTDeviceFromList(&gBTDeviceList, sdpInfo->remote_address); + } + } + else + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Device does not contain OIC service!"); + + //Remove device from list as it does not support OIC service + CARemoveBTDeviceFromList(&gBTDeviceList, sdpInfo->remote_address); + } + } + + u_mutex_unlock(gBTDeviceListMutex); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +CAResult_t CABTNotifyNetworkStauts(CANetworkStatus_t status) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + //Create localconnectivity + if (NULL == gLocalConnectivity) + { + CABTManagerGetInterface(&gLocalConnectivity); + } + + //Notity to upper layer + if (gNetworkChangeCallback && gLocalConnectivity && gBTThreadPool) + { + //Add notification task to thread pool + CABTNetworkEvent *event = CABTCreateNetworkEvent(gLocalConnectivity, status); + if (NULL != event) + { + if (CA_STATUS_OK != u_thread_pool_add_task(gBTThreadPool, CABTOnNetworkStautsChanged, + event)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create threadpool!"); + return CA_STATUS_FAILED; + } + } + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CABTOnNetworkStautsChanged(void *context) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + if (NULL == context) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "context is NULL!"); + return; + } + + CABTNetworkEvent *networkEvent = (CABTNetworkEvent *) context; + + //Notity to upper layer + if (gNetworkChangeCallback) + { + gNetworkChangeCallback(networkEvent->info, networkEvent->status); + } + + //Free the created Network event + CABTFreeNetworkEvent(networkEvent); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +CABTNetworkEvent *CABTCreateNetworkEvent(CALocalConnectivity_t *connectivity, + CANetworkStatus_t status) +{ + VERIFY_NON_NULL_RET(connectivity, BLUETOOTH_ADAPTER_TAG, "connectivity is NULL", NULL); + + //Create CABTNetworkEvent + CABTNetworkEvent *event = (CABTNetworkEvent *) OICMalloc(sizeof(CABTNetworkEvent)); + if (NULL == event) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to allocate memory to network event!"); + return NULL; + } + + //Create duplicate of Local connectivity + event->info = CAAdapterCopyLocalEndpoint(connectivity); + event->status = status; + return event; +} + +void CABTFreeNetworkEvent(CABTNetworkEvent *event) +{ + if (event) + { + if (event->info) + { + CAAdapterFreeLocalEndpoint(event->info); + } + + OICFree(event); + } +} + + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h new file mode 100644 index 0000000..562503a --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.h @@ -0,0 +1,198 @@ +/****************************************************************** + * + * 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 cabtmanager.h + * @brief This file provides the APIs to control Bluetooth transport + */ + +#ifndef __CA_BT_MANAGER_H_ +#define __CA_BT_MANAGER_H_ + +#include +#include +#include + +#include "caedradapter.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @fn CABTManagerInitialize + * @brief Initializes Bluetooth adapter + * + * @param threadPool Thread pool for handling asynchronous tasks + * + * @return CA_STATUS_OK or CA_ADAPTER_NOT_ENABLED on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_ADAPTER_NOT_ENABLED Initialization is successful, but bluetooth adapter is + * not enabled. + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABTManagerInitialize(u_thread_pool_t threadPool); + +/** + * @fn CABTManagerTerminate + * @brief Deinitialize with bluetooth adapter + * + * @see CABTManagerIntialize + * + */ +void CABTManagerTerminate(void); + +/** + * @fn CABTManagerStart + * @brief Start bluetooth adapter which includes start searching for nearby OIC devices + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_FAILED Operation failed + * + * @pre CABTManagerIntialize should be invoked before using this API + * + * @see CABTManagerIntialize + * + */ +CAResult_t CABTManagerStart(void); + +/** + * @fn CABTManagerStop + * @brief Stop bluetooth adapter which includes stoping searching for nearby OIC devices + * + * @pre CABTManagerIntialize should be invoked before using this API + * + * @see CABTManagerIntialize + * @see CABTManagerStart + * + */ +void CABTManagerStop(void); + +/** + * @fn CABTManagerSetPacketReceivedCallback + * @brief Register callback for receiving packets from remote Bluetooth device. + * + * @param packetReceivedCallback Callback function to register for receiving network packets + * + * @return none. + * + * @see CBNetworkPacketReceived + * + */ +void CABTManagerSetPacketReceivedCallback(CANetworkPacketReceivedCallback packetReceivedCallback); + +/** + * @fn CABTManagerSetNetworkChangeCallback + * @brief Register callback for receiving network chang state of local Bluetooth adapter. + * + * @param networkChangeCallback Callback function to register for receiving network adapter status + * + * @return none + * + * @see CBNetworkChange + * + */ +void CABTManagerSetNetworkChangeCallback(CANetworkChangeCallback networkChangeCallback); + +/** + * @fn CABTManagerSendData + * @brief Send unicast/multicast data to remote bluetooth device + * + * @param remoteAddress The address of remote bluetooth device to which data needs to be sent. + * This will be NULL in case of sending multicast data. + * @param serviceUUID The UUID of service to which RFCOMM connection needs to established + * @param data The data needs to be send to remote bluetooth device + * @param dataLength Length of data + * @param sentLength Length of data actually sent or added to pending list for sending + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUID, + void *data, uint32_t dataLength, uint32_t *sentLength); + +/** + * @fn CABTManagerStartServer + * @brief Start RFCOMM server for given service UUID + * + * @param serviceUUID The UUID of service with which RFCOMM server needs to be started + * @param serverID The ID for the server which started + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_SERVER_STARTED_ALREADY Service on the specified UUID is already running. + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABTManagerStartServer(const char *serviceUUID, int32_t *serverID); + +/** + * @fn CABTManagerStopServer + * @brief Stop RFCOMM server + * + * @param 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 + * + */ +CAResult_t CABTManagerStopServer(const int32_t serverID); + +/** + * @fn CABTManagerGetInterface + * @brief Get the local bluetooth adapter information. + * + * @param info Local bluetooth adapter information + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + * @see CALocalConnectivity_t + * + */ +CAResult_t CABTManagerGetInterface(CALocalConnectivity_t **info); + +/** + * @fn CABTManagerReadData + * @brief All received data will be notified to upper layer. + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABTManagerReadData(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //__CA_BT_MANAGER_H_ + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c new file mode 100644 index 0000000..637099d --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.c @@ -0,0 +1,103 @@ +/****************************************************************** + * + * 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 cabtserver.c + * @brief This file provides the APIs to start and stop RFCOMM server. + */ + +#include "cabtserver.h" +#include "caadapterutils.h" +#include "cabtutils.h" +#include "logger.h" + +static int32_t gMaxPendingConnections = 10; + +CAResult_t CABTServerStart(const char *serviceUUID, int32_t *serverFD) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + bool isRunning = false; + int socketFD; + + VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "Service UUID is null"); + VERIFY_NON_NULL(serverFD, BLUETOOTH_ADAPTER_TAG, "Server fd holder is null"); + + if (0 >= strlen(serviceUUID)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Empty service uuid!"); + return CA_STATUS_INVALID_PARAM; + } + + if (BT_ERROR_NONE != bt_adapter_is_service_used(serviceUUID, &isRunning)) + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, + "Unable to find whether service is already running or not!"); + return CA_STATUS_FAILED; + } + + if (true == isRunning) + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Service is already running with this UUID!"); + return CA_SERVER_STARTED_ALREADY; + } + + //Registers a rfcomm socket with a specific service_uuid . + if (BT_ERROR_NONE != (err = bt_socket_create_rfcomm(serviceUUID, &socketFD))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create rfcomm socket!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + + //Start listening and accepting + if (BT_ERROR_NONE != (err = bt_socket_listen_and_accept_rfcomm(socketFD, + gMaxPendingConnections))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed in listen rfcomm socket!, error num [%x]", + err); + + bt_socket_destroy_rfcomm(socketFD); + return CA_STATUS_FAILED; + } + + *serverFD = socketFD; + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CABTServerStop(const int32_t serverFD) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + int err = BT_ERROR_NONE; + if (BT_ERROR_NONE != (err = bt_socket_destroy_rfcomm(serverFD))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed close rfcomm server socket!, error num [%x]", + err); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.h new file mode 100644 index 0000000..59959b1 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtserver.h @@ -0,0 +1,71 @@ +/****************************************************************** + * + * 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 cabtserver.h + * @brief This file provides the APIs to start and stop RFCOMM server. + */ + +#ifndef __CA_BT_SERVER_H_ +#define __CA_BT_SERVER_H_ + +#include +#include + +#include "cacommon.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @fn CABTServerStart + * @brief Start RFCOMM server for given service UUID + * + * @param serviceUUID The UUID of service with which RFCOMM server needs to be started + * @param serverFD The RFCOMM server socket file descriptor + * + * @return CA_STATUS_OK on success otherwise proper error code. + * @retval CA_STATUS_OK Successful + * @retval CA_STATUS_INVALID_PARAM Invalid input argumets + * @retval CA_STATUS_FAILED Operation failed + * + */ +CAResult_t CABTServerStart(const char *serviceUUID, int32_t *serverFD); + +/** + * @fn CABTServerStop + * @brief Stop RFCOMM server + * + * @param serverFD The RFCOMM server socket file descriptor 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 + * + */ +CAResult_t CABTServerStop(const int32_t serverFD); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //__CA_BT_SERVER_H_ \ No newline at end of file diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c new file mode 100644 index 0000000..2bdeff3 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.c @@ -0,0 +1,56 @@ +/****************************************************************** + * + * 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 cabtutils.c + * @brief This file provides helper functions for EDR adapter. + */ + +#include "cabtutils.h" +#include "logger.h" + +#include + +CABool_t CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount, + const char *matchService) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + if (NULL == serviceUUID || 0 == serviceCount || NULL == matchService) + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Invalid input"); + return CA_FALSE; + } + + int i; + for (i = 0; i < serviceCount; i++) + { + if (!strcasecmp(serviceUUID[i], matchService)) + { + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Service found !"); + return CA_TRUE; + } + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_FALSE; +} + + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h new file mode 100644 index 0000000..54378fa --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtutils.h @@ -0,0 +1,66 @@ +/****************************************************************** + * + * 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 cabtutils.h + * @brief This file provides helper functions for EDR adapter. + */ + +#ifndef __CA_BT_UTILS_H_ +#define __CA_BT_UTILS_H_ + +#include + +#include "cacommon.h" +#include "oic_malloc.h" + +#ifndef BLUETOOTH_ADAPTER_TAG +#define BLUETOOTH_ADAPTER_TAG "CA_BLUETOOTH" +#endif //BLUETOOTH_ADAPTER_TAG + +#ifndef OIC_BT_SERVICE_ID +#define OIC_BT_SERVICE_ID "12341234-1C25-481F-9DFB-59193D238280" +#endif //OIC_BT_SERVICE_ID + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @fn CABTIsServiceSupported + * @brief Check if the specified list of service UUIDs contains OIC service UUID. + * + * @param serviceUUID Array of service UUIDs + * @param serviceCount Size of the service UUIDs array. + * @param matchService Service UUID to be checked in the given array of service UUIDs + * + * @return CA_TRUE if service UUID found otherwise CA_FALSE. + * + */ +CABool_t CABTIsServiceSupported(const char **serviceUUID, const int32_t serviceCount, + const char *matchService); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif //__CA_BT_UTILS_H_ + diff --git a/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c new file mode 100644 index 0000000..d34895f --- /dev/null +++ b/resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedradapter.c @@ -0,0 +1,283 @@ +/****************************************************************** + * + * 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.c + * @brief This file contains the APIs for EDR adapters to be implemented + */ + +#include "caedradapter.h" +#include "cabtmanager.h" +#include "cabtutils.h" +#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); + +CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback, + CANetworkPacketReceivedCallback networkPacketCallback, + CANetworkChangeCallback netChangeCallback, + u_thread_pool_t handle) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + CAResult_t err = CA_STATUS_OK; + + //Input validation + VERIFY_NON_NULL(registerCallback, BLUETOOTH_ADAPTER_TAG, "register callback is NULL"); + VERIFY_NON_NULL(networkPacketCallback, BLUETOOTH_ADAPTER_TAG, "data receive callback is NULL"); + VERIFY_NON_NULL(netChangeCallback, BLUETOOTH_ADAPTER_TAG, "network changge callback is NULL"); + VERIFY_NON_NULL(handle, BLUETOOTH_ADAPTER_TAG, "Thread pool hanlde is NULL"); + + //Register the callbacks with BT Manager + CABTManagerSetPacketReceivedCallback(networkPacketCallback); + CABTManagerSetNetworkChangeCallback(netChangeCallback); + + //Initialize BT Manager + err = CABTManagerIntialize(handle); + if (CA_STATUS_OK != err && CA_ADAPTER_NOT_ENABLED != err) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "BT Manger initialize failed!, error number [%d]", + err); + return err; + } + + CAConnectivityHandler_t handler; + handler.startAdapter = CAStartEDR; + handler.startListenServer = CAStartEDRListeningServer; + handler.startDiscoverServer = CAStartEDRDiscoveryServer; + handler.sendData = CASendEDRUnicastData; + handler.sendDataToAll = CASendEDRMulticastData; + handler.startNotifyServer = CAStartEDRNotifyServer; + handler.sendNotification = CASendEDRNotification; + handler.GetnetInfo = CAGetEDRInterfaceInformation; + handler.readData = CAReadEDRData; + handler.stopAdapter = CAStopEDR; + handler.terminate = CATerminateEDR; + registerCallback(handler, CA_EDR); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return err; +} + +CAResult_t CAStartEDR(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + CAResult_t err = CA_STATUS_OK; + + if (CA_STATUS_OK != (err = CABTManagerStart())) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "BT Manger start failed!, error number [%d] ", + err); + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return err; +} + +CAResult_t CAStartEDRListeningServer(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + return CAStartServer(OIC_BT_SERVICE_ID, &gListeningServerID); +} + +CAResult_t CAStartEDRDiscoveryServer(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + return CAStartServer(OIC_BT_SERVICE_ID, &gDiscoveryServerID); +} + +uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + CAResult_t err = CA_STATUS_OK; + uint32_t sentLen = 0; + const char *serviceUUID = OIC_BT_SERVICE_ID; + + //Input validation + VERIFY_NON_NULL_RET(endpoint, BLUETOOTH_ADAPTER_TAG, "Remote endpoint is null", 0); + VERIFY_NON_NULL_RET(data, BLUETOOTH_ADAPTER_TAG, "Data is null", 0); + + if (0 == strlen(endpoint->addressInfo.BT.btMacAddress)) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: Address is empty!"); + return 0; + } + + if (0 == dataLen) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: data length is zero!"); + return 0; + } + + if (CA_STATUS_OK != (err = CABTManagerSendData(endpoint->addressInfo.BT.btMacAddress, + serviceUUID, data, + dataLen, &sentLen))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Send unicast data failed!, error num [%d]", err); + return 0; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return sentLen; +} + +uint32_t CASendEDRMulticastData(void *data, uint32_t dataLen) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + CAResult_t err = CA_STATUS_OK; + uint32_t sentLen = 0; + const char *serviceUUID = OIC_BT_SERVICE_ID; + + //Input validation + VERIFY_NON_NULL_RET(data, BLUETOOTH_ADAPTER_TAG, "Data is null", 0); + + if (0 == dataLen) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Invalid input: data length is zero!"); + return 0; + } + + if (CA_STATUS_OK != (err = CABTManagerSendData(NULL, serviceUUID, data, dataLen, + &sentLen))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, " Send multicast data failed!, error num [%d]", + err); + return 0; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return sentLen; +} + +CAResult_t CAStartEDRNotifyServer(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + return CAStartServer(OIC_BT_SERVICE_ID, &gNotificationServerID); +} + +uint32_t CASendEDRNotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + return CASendEDRUnicastData(endpoint, data, dataLen); +} + +CAResult_t CAGetEDRInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + VERIFY_NON_NULL(info, BLUETOOTH_ADAPTER_TAG, "LocalConnectivity info is null"); + + CAResult_t err = CA_STATUS_OK; + *size = 0; + if (CA_STATUS_OK != (err = CABTManagerGetInterface(info))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, + "Failed to get local interface information!, error num [%d]", err); + return err; + } + + *size = 1; + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return err; +} + +CAResult_t CAReadEDRData(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + return CABTManagerReadData(); +} + +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); + } + + //Stop the adapter + CABTManagerStop(); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CATerminateEDR(void) +{ + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN"); + + //Terminate BT Manager + CABTManagerTerminate(); + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); +} + +CAResult_t CAStartServer(const char *serviceUUID, int32_t *serverID) +{ + 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))) + { + OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to start RFCOMM server!, error num [%d]", + err); + return err; + } + + OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT"); + return err; +} diff --git a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c index ff60572..91f6534 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c @@ -34,6 +34,8 @@ #include "cableserver.h" #include "cableclient.h" #include "cacommon.h" +#include "umutex.h" +#include "caadapterutils.h" #else // __ARDUINO__ #include "BLEAdapterArduino.h" #include "caadapterutils.h" @@ -41,47 +43,62 @@ #define CALEADAPTER_TAG "CA_BLE_ADAPTER" static CANetworkChangeCallback gNetworkCallback = NULL; -static char gLocalBLEAddress[16] = -{ 0, }; -static int gIsServer = 0; +static char gLocalBLEAddress[16] = { 0, }; -int CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback); +static CABool_t gIsServer = CA_FALSE; -#ifdef __TIZEN__ -int CALEDeviceStateChangedCb(int result, bt_adapter_state_e adapter_state, void *user_data); -#endif //#ifdef __TIZEN__ +static u_mutex gBleIsServerMutex = NULL; + +static u_mutex gBleNetworkCbMutex = NULL; -pthread_mutex_t gBleIsServerMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +static u_mutex gBleLocalAddressMutex = NULL; -pthread_mutex_t gBleNetworkCbMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +int32_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback); -pthread_mutex_t gBleLocalAddressMutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +#ifdef __TIZEN__ +int32_t CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, + void *user_data); +CAResult_t CAInitBleAdapterMutex(); +CAResult_t CATermiateBleAdapterMutex(); + +#endif //#ifdef __TIZEN__ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback) + CANetworkPacketReceivedCallback reqRespCallback, + CANetworkChangeCallback netCallback, + u_thread_pool_t handle) { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); //Input validation VERIFY_NON_NULL(registerCallback, NULL, "RegisterConnectivity callback is null"); VERIFY_NON_NULL(reqRespCallback, NULL, "PacketReceived Callback is null"); VERIFY_NON_NULL(netCallback, NULL, "NetworkChange Callback is null"); -#ifdef __TIZEN__ + CAResult_t result = CAInitBleAdapterMutex(); - int ret = bt_initialize(); - if (0 != ret) + if (CA_STATUS_OK != result) { - OCLog(ERROR, CALEADAPTER_TAG, "bt_initialize failed!"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleAdapterMutex failed!"); return CA_STATUS_FAILED; } +#ifdef __TIZEN__ + + bt_initialize(); + #endif //#ifdef __TIZEN__ - CASetBLEReqRescallback(reqRespCallback); + + CASetBleServerThreadPoolHandle(handle); + CASetBleClientThreadPoolHandle(handle); + CASetBLEReqRespServerCallback(reqRespCallback); + CASetBLEReqRespClientCallback(reqRespCallback); CALERegisterNetworkNotifications(netCallback); CAConnectivityHandler_t connHandler; + connHandler.startAdapter = NULL; + connHandler.stopAdapter = NULL; connHandler.startListenServer = CAStartLEListeningServer; connHandler.startDiscoverServer = CAStartLEDiscoveryServer; connHandler.sendData = CASendLEUnicastData; @@ -93,20 +110,21 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, connHandler.terminate = CATerminateLE; registerCallback(connHandler, CA_LE); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } void CATerminateLE() { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - CASetBLEReqRescallback(NULL); + CASetBLEReqRespServerCallback(NULL); + CASetBLEReqRespClientCallback(NULL); CALERegisterNetworkNotifications(NULL); - pthread_mutex_lock(&gBleIsServerMutex); - if (gIsServer == 1) + u_mutex_lock(gBleIsServerMutex); + if (CA_TRUE == gIsServer) { CAStopBleGattServer(); } @@ -114,110 +132,68 @@ void CATerminateLE() { CAStopBLEGattClient(); } - pthread_mutex_unlock(&gBleIsServerMutex); + u_mutex_unlock(gBleIsServerMutex); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return; } -void CALEServerInitThreadFunc(void *param) -{ - OCLog(DEBUG, CALEADAPTER_TAG, "[CALEServerInitThreadFunc]IN"); - - CAStartBleGattServer(); - - OCLog(DEBUG, CALEADAPTER_TAG, "[CALEServerInitThreadFunc] OUT"); -} - -void CALEClientInitThreadFunc(void *param) -{ - OCLog(DEBUG, CALEADAPTER_TAG, "[CALEClientInitThreadFunc]IN"); - - CAStartBLEGattClient(); - - OCLog(DEBUG, CALEADAPTER_TAG, "[CALEClientInitThreadFunc] OUT"); -} - CAResult_t CAStartLEListeningServer() { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); - - int init_pthread_status = 0; - pthread_t pthread_id = 0; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - init_pthread_status = pthread_create(&pthread_id, &attr, CALEServerInitThreadFunc, NULL); - - if (init_pthread_status != 0) - { - OCLog(ERROR, CALEADAPTER_TAG, "pthread_create failed!"); - return CA_STATUS_FAILED; - } + CAStartBleGattServer(); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); - pthread_mutex_lock(&gBleIsServerMutex); - gIsServer = 1; - pthread_mutex_unlock(&gBleIsServerMutex); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + u_mutex_lock(gBleIsServerMutex); + gIsServer = CA_TRUE; + u_mutex_unlock(gBleIsServerMutex); return CA_STATUS_OK; } CAResult_t CAStartLEDiscoveryServer() { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - int init_pthread_status = 0; - pthread_t pthread_id = 0; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - init_pthread_status = pthread_create(&pthread_id, &attr, CALEClientInitThreadFunc, NULL); - - if (init_pthread_status != 0) - { - OCLog(ERROR, CALEADAPTER_TAG, "pthread_create failed!"); - return CA_STATUS_FAILED; - } + CAStartBLEGattClient(); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); - pthread_mutex_lock(&gBleIsServerMutex); - gIsServer = 0; - pthread_mutex_unlock(&gBleIsServerMutex); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + u_mutex_lock(gBleIsServerMutex); + gIsServer = CA_FALSE; + u_mutex_unlock(gBleIsServerMutex); return CA_STATUS_OK; } CAResult_t CAStartLENotifyServer() { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen) { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } CAResult_t CAReadLEData() { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen) { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); //Input validation VERIFY_NON_NULL(endpoint, NULL, "Remote endpoint is null"); @@ -226,99 +202,93 @@ uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uin CAResult_t result = CA_STATUS_FAILED; #ifdef __TIZEN__ - pthread_mutex_lock(&gBleIsServerMutex); - if (gIsServer) + u_mutex_lock(gBleIsServerMutex); + if (CA_TRUE == gIsServer) { - result = CAUpdateCharacteristicsInGattServer(data, dataLen); + result = CABleServerSenderQueueEnqueueMessage(endpoint, data, dataLen); if (CA_STATUS_OK != result) { - OCLogv(ERROR, CALEADAPTER_TAG, - "[SendLEUnicastData] sending unicast data to [%s] failed\n", endpoint->addressInfo.BT.btMacAddress); - pthread_mutex_unlock(&gBleIsServerMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, + "[SendLEUnicastData] CABleServerSenderQueueEnqueueMessage failed \n"); + u_mutex_unlock(gBleIsServerMutex); return 0; } } else { - result = CAUpdateCharacteristicsToGattServer(endpoint->addressInfo.BT.btMacAddress, data, - dataLen, UNICAST, 0); + result = CABleClientSenderQueueEnqueueMessage(endpoint, data, dataLen); if (CA_STATUS_OK != result) { - OCLogv(ERROR, CALEADAPTER_TAG, - "[SendLEUnicastData] sending unicast data to [%s] failed\n", endpoint->addressInfo.BT.btMacAddress); - pthread_mutex_unlock(&gBleIsServerMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, + "[SendLEUnicastData] CABleClientSenderQueueEnqueueMessage failed \n"); + u_mutex_unlock(gBleIsServerMutex); return 0; } } - pthread_mutex_unlock(&gBleIsServerMutex); + u_mutex_unlock(gBleIsServerMutex); #else char *tempPath = "temp_path"; updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen); #endif //#ifdef __TIZEN__ - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return dataLen; } uint32_t CASendLEMulticastData(void *data, uint32_t dataLen) { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); //Input validation VERIFY_NON_NULL(data, NULL, "Data is null"); if (0 >= dataLen) { - OCLog(ERROR, CALEADAPTER_TAG, "Invalid Parameter"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid Parameter"); return 0; } CAResult_t result = CA_STATUS_FAILED; #ifdef __TIZEN__ - pthread_mutex_lock(&gBleIsServerMutex); - if (gIsServer) + u_mutex_lock(gBleIsServerMutex); + if (CA_TRUE == gIsServer) { - result = CAUpdateCharacteristicsInGattServer(data, dataLen); + result = CABleServerSenderQueueEnqueueMessage(NULL, data, dataLen); if (CA_STATUS_OK != result) { - OCLogv(ERROR, CALEADAPTER_TAG, - "[CASendLEMulticastData] updating data in server is failed"); - pthread_mutex_unlock(&gBleIsServerMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, + "[SendLEMulticastDataToAll] CABleServerSenderQueueEnqueueMessage failed" ); + u_mutex_unlock(gBleIsServerMutex); return 0; } } else { - result = CAUpdateCharacteristicsToAllGattServers(data, dataLen); + result = CABleClientSenderQueueEnqueueMessage(NULL, data, dataLen); if (CA_STATUS_OK != result) { - OCLogv(ERROR, CALEADAPTER_TAG, - "[SendLEMulticastDataToAll] multicasting data to servers failed" ); - pthread_mutex_unlock(&gBleIsServerMutex); + OIC_LOG(ERROR, CALEADAPTER_TAG, + "[SendLEMulticastDataToAll] CABleClientSenderQueueEnqueueMessage failed" ); + u_mutex_unlock(gBleIsServerMutex); return 0; } } - pthread_mutex_unlock(&gBleIsServerMutex); + u_mutex_unlock(gBleIsServerMutex); #else char *tempPath = "temp_path"; updateCharacteristicsInGattServer(tempPath, (char *) data, dataLen); #endif //#ifdef __TIZEN__ - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return dataLen; } -CAResult_t CAGetLEInterfaceInformation(CALocalConnectivityt_t **info, uint32_t *size) +CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size) { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); VERIFY_NON_NULL(info, NULL, "CALocalConnectivity info is null"); -#ifdef OIC_ARDUINODUE - OCLog(DEBUG, CALEADAPTER_TAG, "Info from ARDUINO"); - //1: call corresponding Arduino API -#endif - #if __TIZEN__ char *local_address = NULL; @@ -326,68 +296,68 @@ CAResult_t CAGetLEInterfaceInformation(CALocalConnectivityt_t **info, uint32_t * bt_adapter_get_address(&local_address); if (NULL == local_address) { - OCLog(ERROR, CALEADAPTER_TAG, "Get local bt adapter address failed"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Get local bt adapter address failed"); return CA_STATUS_FAILED; } #endif //#if ARDUINODUE *size = 0; - (*info) = (CALocalConnectivityt_t *) OICMalloc(sizeof(CALocalConnectivityt_t)); + (*info) = (CALocalConnectivity_t *) OICMalloc(sizeof(CALocalConnectivity_t)); if (NULL == (*info)) { - OCLog(ERROR, CALEADAPTER_TAG, "Malloc failure!"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "Malloc failure!"); return CA_STATUS_FAILED; } - memset((*info), 0x0, sizeof(CALocalConnectivityt_t)); + memset((*info), 0x0, sizeof(CALocalConnectivity_t)); strncpy((*info)->addressInfo.BT.btMacAddress, local_address, strlen(local_address)); - pthread_mutex_lock(&gBleLocalAddressMutex); + u_mutex_lock(gBleLocalAddressMutex); strncpy(gLocalBLEAddress, local_address, sizeof(gLocalBLEAddress)); - pthread_mutex_unlock(&gBleLocalAddressMutex); + u_mutex_unlock(gBleLocalAddressMutex); (*info)->type = CA_LE; *size = 1; OICFree(local_address); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } -int CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback) +int32_t CALERegisterNetworkNotifications(CANetworkChangeCallback netCallback) { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); - pthread_mutex_lock(&gBleNetworkCbMutex); + u_mutex_lock(gBleNetworkCbMutex); gNetworkCallback = netCallback; - pthread_mutex_unlock(&gBleNetworkCbMutex); - int ret = 0; + u_mutex_unlock(gBleNetworkCbMutex); + int32_t ret = 0; #ifdef __TIZEN__ if (netCallback) { ret = bt_adapter_set_state_changed_cb(CALEDeviceStateChangedCb, NULL); - if(ret != 0) + if (ret != 0) { - OCLog(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!"); } } else { ret = bt_adapter_unset_state_changed_cb(); - if(ret != 0) + if (ret != 0) { - OCLog(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "bt_adapter_set_state_changed_cb failed!"); } } #endif //#ifdef __TIZEN__ - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } #ifdef __TIZEN__ -int CALEDeviceStateChangedCb(int result, bt_adapter_state_e adapter_state, void *user_data) +int32_t CALEDeviceStateChangedCb(int32_t result, bt_adapter_state_e adapter_state, void *user_data) { - OCLog(DEBUG, CALEADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); bt_adapter_state_e btAdaptorState = BT_ADAPTER_DISABLED; if (BT_ADAPTER_ENABLED == adapter_state) @@ -395,23 +365,73 @@ int CALEDeviceStateChangedCb(int result, bt_adapter_state_e adapter_state, void btAdaptorState = BT_ADAPTER_ENABLED; } - CALocalConnectivityt_t localEndpoint; + CALocalConnectivity_t localEndpoint; - pthread_mutex_lock(&gBleLocalAddressMutex); + u_mutex_lock(gBleLocalAddressMutex); strncpy(localEndpoint.addressInfo.BT.btMacAddress, gLocalBLEAddress, strlen(gLocalBLEAddress)); - pthread_mutex_unlock(&gBleLocalAddressMutex); + u_mutex_unlock(gBleLocalAddressMutex); - pthread_mutex_lock(&gBleNetworkCbMutex); - if(NULL != gNetworkCallback) + u_mutex_lock(gBleNetworkCbMutex); + if (NULL != gNetworkCallback) { gNetworkCallback(&localEndpoint, adapter_state); } else { - OCLog(ERROR, CALEADAPTER_TAG, "gNetworkCallback is NULL"); + OIC_LOG(ERROR, CALEADAPTER_TAG, "gNetworkCallback is NULL"); } - pthread_mutex_unlock(&gBleNetworkCbMutex); - OCLog(DEBUG, CALEADAPTER_TAG, "OUT"); + u_mutex_unlock(gBleNetworkCbMutex); + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CAInitBleAdapterMutex() +{ + OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN"); + + u_mutex_init(); + if (NULL == gBleIsServerMutex) + { + gBleIsServerMutex = u_mutex_new(); + if (NULL == gBleIsServerMutex) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleNetworkCbMutex) + { + gBleNetworkCbMutex = u_mutex_new(); + if (NULL == gBleNetworkCbMutex) + { + OIC_LOG(ERROR, CALEADAPTER_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleLocalAddressMutex) + { + gBleLocalAddressMutex = u_mutex_new(); + if (NULL == gBleLocalAddressMutex) + { + 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; + OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT"); return CA_STATUS_OK; } #endif //#ifdef OIC_TIZEN diff --git a/resource/csdk/connectivity/src/bt_le_adapter/linux/README.txt b/resource/csdk/connectivity/src/bt_le_adapter/linux/README.txt new file mode 100644 index 0000000..e69de29 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 fb7ec92..9f9ac9e 100644 --- a/resource/csdk/connectivity/src/bt_le_adapter/linux/caleadapter.c +++ b/resource/csdk/connectivity/src/bt_le_adapter/linux/caleadapter.c @@ -28,13 +28,16 @@ #define TAG PCF("CA") static CANetworkPacketReceivedCallback gLEReceivedCallback = NULL; +static u_thread_pool_t gThreadPoolHandle = NULL; CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback) + CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle) { OIC_LOG_V(DEBUG, TAG, "CAInitializeLE"); gLEReceivedCallback = reqRespCallback; + gThreadPoolHandle = handle; // register handlers CAConnectivityHandler_t handler; @@ -106,7 +109,7 @@ uint32_t CASendLENotification(const CARemoteEndpoint_t* endpoint, void* data, ui return 0; } -CAResult_t CAGetLEInterfaceInformation(CALocalConnectivityt_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 new file mode 100644 index 0000000..f28fdd2 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c @@ -0,0 +1,1703 @@ +/****************************************************************** + * + * 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 "cableclient.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "umutex.h" +#include "camessagequeue.h" +#include "caadapterutils.h" + +/** + * @def TZ_BLE_CLIENT_TAG + * @brief Logging tag for module name + */ +#define TZ_BLE_CLIENT_TAG "TZ_BLE_GATT_CLIENT" + +static BLEServiceList *gBLEServiceList = NULL; + +static CABool_t gIsBleGattClientStarted = CA_FALSE; + +static CAAdapterMessageQueue_t *gCABleClientSenderQueue = NULL; + +static CAAdapterMessageQueue_t *gCABleClientReceiverQueue = NULL; + +static u_mutex gBleServiceListMutex = NULL; + +static u_mutex gBleReqRespClientCbMutex = NULL; + +static u_mutex gBleClientStateMutex = NULL; + +static u_mutex gBleClientSendDataMutex = NULL; + +static u_cond gBleClientSendCondWait = NULL; + +static u_mutex gBleClientReceiveDataMutex = NULL; + +static u_mutex gBleClientThreadPoolMutex = NULL; + +static CANetworkPacketReceivedCallback gReqRespClientCallback = NULL; + +static CABool_t gClientUp = CA_FALSE; + +static GMainLoop *g_event_loop = NULL; + +static u_thread_pool_t gBleClientThreadPool = NULL; + +typedef struct gattService +{ + bt_gatt_attribute_h serviceInfo; + char *address; +} stGattServiceInfo_t; + +void CABleGattCharacteristicWriteCb(bt_gatt_attribute_h handle) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN "); + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT "); +} + +void *CABleClientSenderQueueProcessor() +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN "); + + while (gClientUp) + { + CAAdapterMessage_t *senderData = NULL; + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " conditional wait"); + + u_mutex_lock(gBleClientSendDataMutex); + u_cond_wait(gBleClientSendCondWait, gBleClientSendDataMutex); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "wait unlocked"); + + CAResult_t result = CA_STATUS_FAILED; + + while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleClientSenderQueue, &senderData)) + { + if (NULL == senderData) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "senderData is NULL"); + continue; + } + if (NULL != senderData->remoteEndpoint) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending Unicast data"); + const char *bdAddress = senderData->remoteEndpoint->addressInfo.LE.leMacAddress; + + if (NULL == bdAddress) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "bdAddress is NULL"); + continue; + } + + result = CAUpdateCharacteristicsToGattServer(bdAddress, senderData->data, + senderData->dataLen, 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(senderData->data, + senderData->dataLen); + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "Failed to UpdateCharacteristicsToAllGattServers !"); + } + } + + CAAdapterFreeMessage(senderData); + } + + u_mutex_unlock(gBleClientSendDataMutex); + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT "); + return NULL; +} + +CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescriptorInfo) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + uint8_t desc[stGattCharDescriptorInfo->total]; + unsigned char noti[4] = + { 0, }; + char *strUUID = NULL; + + memcpy(desc, (uint8_t *) stGattCharDescriptorInfo->descriptor, stGattCharDescriptorInfo->total); + + strUUID = (char *) OICMalloc(sizeof(char) * 5); + if (NULL == strUUID) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failure!"); + return CA_STATUS_FAILED; + } + memset(strUUID, 0x0, sizeof(char) * 5); + snprintf(strUUID, 4, "%x%x", desc[3], desc[2]); + noti[0] = desc[0]; + noti[1] = desc[1]; + noti[2] = 0x01; + noti[3] = 0x00; + + if (!strncmp(strUUID, "2902", 2)) + { + int32_t ret = 0; + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor"); + + ret = bt_gatt_set_characteristic_desc_value_request( + stGattCharDescriptorInfo->characteristic, noti, 4, CABleGattCharacteristicWriteCb); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "bt_gatt_set_characteristic_desc_value_request failed with return[%s] \n", + CABTGetErrorMsg(ret)); + OICFree(strUUID); + return CA_STATUS_FAILED; + } + } + bt_gatt_destroy_attribute_handle(stGattCharDescriptorInfo->characteristic); + bt_gatt_destroy_attribute_handle(stGattCharDescriptorInfo->descriptor); + OICFree(stGattCharDescriptorInfo); + OICFree(strUUID); + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return CA_STATUS_OK; +} + +void *CASetCharacteristicDescriptorValueThread(void *stServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == stServiceInfo) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param stServiceInfo is NULL"); + return NULL; + } + + stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *) stServiceInfo; + + if (NULL == stTemp) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "stTemp is NULL"); + return NULL; + } + + CAResult_t result = CASetCharacteristicDescriptorValue(stTemp); + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!"); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return NULL; +} + +void CABleGattDescriptorDiscoveredCb(int result, unsigned char format, int total, + bt_gatt_attribute_h descriptor, bt_gatt_attribute_h characteristic, void *userData) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *) OICMalloc( + sizeof(stGattCharDescriptor_t)); + + if (NULL == stTemp) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "stTemp is NULL"); + return; + } + bt_gatt_clone_attribute_handle(&(stTemp->descriptor), descriptor); + + bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic); + + stTemp->total = total; + u_mutex_lock(gBleClientThreadPoolMutex); + if (NULL == gBleClientThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL"); + OICFree(stTemp); + u_mutex_unlock(gBleClientThreadPoolMutex); + return; + } + + CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, + (void *) CASetCharacteristicDescriptorValueThread, (void *) stTemp); + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret); + OICFree(stTemp); + u_mutex_unlock(gBleClientThreadPoolMutex); + //CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress); + return; + } + + sleep(2); + 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); + //CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress); + return; + } + u_mutex_unlock(gBleClientThreadPoolMutex); + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, + "LE Client initialization complete. Enabling gClientUp state to TRUE "); + gClientUp = CA_TRUE; + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return; +} + +void *CADiscoverDescriptorThread(void *stServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN"); + + if (NULL == stServiceInfo) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL"); + return NULL; + } + stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *) stServiceInfo; + + int32_t ret = bt_gatt_discover_characteristic_descriptor(stTemp->serviceInfo, + CABleGattDescriptorDiscoveredCb, NULL); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "bt_gatt_discover_characteristic_descriptor failed with returns[%s] \n", + CABTGetErrorMsg(ret)); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return NULL; +} + +void *CADiscoverCharThread(void *stServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == stServiceInfo) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param stServiceInfo is NULL"); + return NULL; + } + + stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *) stServiceInfo; + + if (NULL == stTemp) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "stTemp is NULL"); + return NULL; + } + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address); + + CAResult_t result = CABleDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address); + + bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); + + OICFree(stTemp->address); + + OICFree(stTemp); + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CABleDiscoverCharacteristics failed!"); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return NULL; +} + +void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *user_data) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + if (result == BT_ERROR_NONE) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "A bond with chat_server is created.");OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Callback: The number of service : %d.", + device_info->service_count); + + int32_t i = 0; + + char *bdAddress = device_info->remote_address; + + int32_t len = strlen(bdAddress); + + char *addr = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == addr) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + return; + } + memset(addr, 0x0, len + 1); + + strncpy(addr, bdAddress, len); + + BLEServiceInfo *bleServiceInfo = NULL; + + u_mutex_lock(gBleServiceListMutex); + CAResult_t retVal = CAGetBLEServiceInfo(gBLEServiceList, addr, &bleServiceInfo); + + u_mutex_unlock(gBleServiceListMutex); + OICFree(addr); + + if (CA_STATUS_OK != retVal) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAGetBLEServiceInfo failed! "); + bleServiceInfo = NULL; + return; + } + + int32_t ret = CAVerifyOICService(bleServiceInfo->service_clone); + + if (CA_STATUS_OK == ret) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service"); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG , + " serviceInfo remote address [%s]", bleServiceInfo->bdAddress); + + stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *) OICMalloc( + sizeof(stGattServiceInfo_t)); + if (NULL == stTemp) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + return; + } + + bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), bleServiceInfo->service_clone); + + len = strlen(bleServiceInfo->bdAddress); + + stTemp->address = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == stTemp->address) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); + OICFree(stTemp); + return; + } + memset(stTemp->address, 0x0, len + 1); + + strncpy(stTemp->address, bleServiceInfo->bdAddress, len); + + u_mutex_lock(gBleClientThreadPoolMutex); + if (NULL == gBleClientThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL"); + bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); + OICFree(stTemp->address); + OICFree(stTemp); + u_mutex_unlock(gBleClientThreadPoolMutex); + /*CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, + * bleServiceInfo->bdAddress); */ + return; + } + + CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, + (void *) CADiscoverCharThread, (void *) stTemp); + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "u_thread_pool_add_task failed with ret [%d]", ret); + bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); + OICFree(stTemp->address); + OICFree(stTemp); + u_mutex_unlock(gBleClientThreadPoolMutex); + return; + } + u_mutex_unlock(gBleClientThreadPoolMutex); + } + else + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its not OIC service!! "); + } + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, + "Callback: is_bonded - %d.", device_info->is_bonded);OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, + "Callback: is_connected - %d.", device_info->is_connected); + + } + else + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + " create_bond Failed as [%s ]", CABTGetErrorMsg(result)); + }OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +void *CAGATTCreateBondThread(void *stServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == stServiceInfo) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param stServiceInfo is NULL"); + return NULL; + } + + stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *) stServiceInfo; + + if (NULL == stTemp) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "stTemp is NULL"); + return NULL; + } + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", + stTemp->address); + + CAResult_t result = CABleGATTCreateBond(stTemp->address); + + OICFree(stTemp->address); + + OICFree(stTemp); + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , + "CABleDiscoverCharacteristics failed!"); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return NULL; +} + +void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic, unsigned char *value, + int32_t valueLen, void *userData) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + int32_t i = 0; + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic is [%s]", (char *)characteristic); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value length [%d]", valueLen); + + for (i = 0; i < valueLen; i++) + { + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value %c", value[i]); + } + + CARemoteEndpoint_t *remoteEndPoint = (CARemoteEndpoint_t *) OICMalloc( + sizeof(CARemoteEndpoint_t)); + if (NULL == remoteEndPoint) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Malloc Failure!"); + return; + } + memset(remoteEndPoint, 0x0, sizeof(CARemoteEndpoint_t)); + + ///TODO: Currently Empty endpoint is being sent. + ///TODO:Later proper remote address has to be added when tizen team changed their code +#if 0 + VERIFY_NON_NULL(gCABleClientReceiverQueue, TZ_BLE_CLIENT_TAG, + "BleClientReceiverQueue is NULL"); + u_mutex_lock(gBleClientReceiveDataMutex); + CAResult_t retVal = CAAdapterEnqueueMessage(gCABleClientReceiverQueue, + remoteEndPoint, value, + valueLen); + if (CA_STATUS_OK != retVal ) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterEnqueueMessage failed!"); + u_mutex_unlock(gBleClientReceiveDataMutex); + CATerminateBLEGattClient(); + return; + } + u_mutex_unlock(gBleClientReceiveDataMutex); +#endif + + char *data = (char *) OICMalloc(sizeof(char) * valueLen + 1); + if (NULL == data) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Malloc failed!"); + OICFree(remoteEndPoint); + return; + } + + memset(data, 0x0, valueLen + 1); + + strncpy(data, value, valueLen); + + u_mutex_lock(gBleReqRespClientCbMutex); + if (NULL == gReqRespClientCallback) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!"); + OICFree(value); + OICFree(remoteEndPoint); + u_mutex_unlock(gBleReqRespClientCbMutex); + return; + } + + gReqRespClientCallback(remoteEndPoint, data, valueLen); + + u_mutex_unlock(gBleReqRespClientCbMutex); + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return; +} + +CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, void *userData) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == service || NULL == userData) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param service or userData is NULL"); + return false; + } + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s]", (char *)service); + + int32_t ret = CAVerifyOICService(service); + + if (CA_STATUS_OK == ret) + { + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service"); + + char *bdAddress = (char *) userData; + + int32_t len = strlen(bdAddress); + + char *addr = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == addr) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "malloc failed! "); + return false; + } + memset(addr, 0x0, len + 1); + + strncpy(addr, bdAddress, len); + + BLEServiceInfo *bleServiceInfo = NULL; + + CAResult_t result = CACreateBLEServiceInfo(addr, service, &bleServiceInfo); + + OICFree(addr); + + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! "); + bleServiceInfo = NULL; + return false; + } + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG , + " serviceInfo remote address [%s]", bleServiceInfo->bdAddress); + + u_mutex_lock(gBleServiceListMutex); + result = CAAddBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo); + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!"); + bleServiceInfo = NULL; + u_mutex_unlock(gBleServiceListMutex); + return false; + } + u_mutex_unlock(gBleServiceListMutex); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes \n"); + + int32_t ret = bt_gatt_watch_characteristic_changes(bleServiceInfo->service_clone); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "bt_gatt_watch_characteristic_changes failed with [%s] \n", CABTGetErrorMsg(ret)); + u_mutex_lock(gBleServiceListMutex); + CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, + bleServiceInfo->bdAddress); + u_mutex_unlock(gBleServiceListMutex); + return false; + } + + stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *) OICMalloc( + sizeof(stGattServiceInfo_t)); + + if (NULL == stTemp) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + u_mutex_lock(gBleServiceListMutex); + CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, + bleServiceInfo->bdAddress); + u_mutex_unlock(gBleServiceListMutex); + return false; + } + + memset(stTemp, 0x0, sizeof(stGattServiceInfo_t)); + + len = strlen(bleServiceInfo->bdAddress); + + stTemp->address = (char *) OICMalloc(sizeof(char) * len + 1); + + if (NULL == stTemp->address) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + u_mutex_lock(gBleServiceListMutex); + CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, + bleServiceInfo->bdAddress); + u_mutex_unlock(gBleServiceListMutex); + OICFree(stTemp); + return false; + } + + memset(stTemp->address, 0x0, len + 1); + + strncpy(stTemp->address, bleServiceInfo->bdAddress, len); + + u_mutex_lock(gBleClientThreadPoolMutex); + if (NULL == gBleClientThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL"); + OICFree(stTemp->address); + OICFree(stTemp); + u_mutex_lock(gBleServiceListMutex); + CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, + bleServiceInfo->bdAddress); + u_mutex_unlock(gBleServiceListMutex); + u_mutex_unlock(gBleClientThreadPoolMutex); + return false; + } + + result = u_thread_pool_add_task(gBleClientThreadPool, (void *) CAGATTCreateBondThread, + (void *) stTemp); + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "u_thread_pool_add_task failed with ret [%d]", result); + OICFree(stTemp->address); + OICFree(stTemp); + u_mutex_lock(gBleServiceListMutex); + CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, + bleServiceInfo->bdAddress); + u_mutex_unlock(gBleServiceListMutex); + u_mutex_unlock(gBleClientThreadPoolMutex); + return false; + } + u_mutex_unlock(gBleClientThreadPoolMutex); + } + else + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its not OIC service!! "); + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT "); + return true;; +} + +CABool_t CABleGattCharacteristicsDiscoveredCb(int32_t result, int32_t inputIndex, int32_t total, + bt_gatt_attribute_h characteristic, void *userData) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == characteristic || NULL == userData) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param characteristic and userData is NULL"); + return false; + } + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, + "result [%d] input_index [%d] total [%d]", + result, inputIndex, total); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, + "new characteristic found is [%s]", (char *)characteristic); + + char *bdAddress = (char *) userData; + + BLEServiceInfo *bleServiceInfo = NULL; + + u_mutex_lock(gBleServiceListMutex); + + CAGetBLEServiceInfo(gBLEServiceList, bdAddress, &bleServiceInfo); + + u_mutex_unlock(gBleServiceListMutex); + + if (1 == inputIndex) + { + CAResult_t retVal = CAAppendBLECharInfo(characteristic, READ_CHAR, bleServiceInfo); + if (CA_STATUS_OK != retVal) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed "); + return false; + } + } + else if (2 == inputIndex) + { + CAResult_t retVal = CAAppendBLECharInfo(characteristic, WRITE_CHAR, bleServiceInfo); + if (CA_STATUS_OK != retVal) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! "); + return false; + } + + } + + stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *) OICMalloc(sizeof(stGattServiceInfo_t)); + + if (NULL == stTemp) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + return false; + } + + memset(stTemp, 0x0, sizeof(stGattServiceInfo_t)); + + bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic); + + int32_t len = strlen(bleServiceInfo->bdAddress); + + stTemp->address = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == stTemp->address) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); + OICFree(stTemp); + return false; + } + memset(stTemp->address, 0x0, len + 1); + + strncpy(stTemp->address, bleServiceInfo->bdAddress, len); + + u_mutex_lock(gBleClientThreadPoolMutex); + if (NULL == gBleClientThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL"); + bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); + OICFree(stTemp->address); + OICFree(stTemp); + u_mutex_unlock(gBleClientThreadPoolMutex); + return false; + } + + CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, + (void *) CADiscoverDescriptorThread, (void *) stTemp); + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret); + bt_gatt_destroy_attribute_handle(stTemp->serviceInfo); + OICFree(stTemp->address); + OICFree(stTemp); + u_mutex_unlock(gBleClientThreadPoolMutex); + //CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress); + return false; + } + u_mutex_unlock(gBleClientThreadPoolMutex); + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return true; + +} + +CAResult_t CABleClientSenderQueueEnqueueMessage(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; +} + +CAResult_t CALEReadDataFromLEClient() +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN "); +#if 0 + CAAdapterMessage_t *receiverData = NULL; + + u_mutex_lock(gBleClientReceiveDataMutex); + CAResult_t result = CAAdapterDequeueMessage(gCABleClientReceiverQueue, &receiverData); + + if (CA_STATUS_OK != result) + { + u_mutex_lock(gBleReqRespClientCbMutex); + if (NULL == gReqRespClientCallback) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespClientCallback is NULL!"); + CAAdapterFreeMessage(receiverData); + u_mutex_unlock(gBleReqRespClientCbMutex); + u_mutex_unlock(gBleClientReceiveDataMutex); + return; + } + + gReqRespClientCallback(receiverData->remoteEndpoint, receiverData->data, receiverData->dataLen); + + CAAdapterFreeMessage(receiverData); + } + u_mutex_unlock(gBleClientReceiveDataMutex); + +#endif + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT "); + + return CA_STATUS_OK; +} + +void *CAGattConnectThread(void *remoteAddress) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN "); + + if (NULL == remoteAddress) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param remoteAddress is NULL "); + return NULL; + } + + char *address = (char *) remoteAddress; + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address); + + CAResult_t result = bt_gatt_connect(address, true); + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address); + return NULL; + } + + OICFree(address); + address = NULL; + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return NULL; +} + +void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == discoveryInfo) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL "); + return; + } + + if (discoveryInfo->remote_address) + { + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address); + } + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, + " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ", + discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi, + discoveryInfo->address_type);OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result, + bt_adapter_le_device_discovery_state_e discoveryState, + bt_adapter_le_device_discovery_info_s *discoveryInfo, void *userData) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (discoveryInfo == NULL && discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL"); + return; + } + + if (discoveryState != BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND) + { + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, + " LE Discovery state is [%s]", + discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished" ); + } + else + { + + CAPrintDiscoveryInformation(discoveryInfo); + + if (NULL == discoveryInfo->remote_address) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo->remote_address is NULL"); + return; + } + + int32_t len = strlen(discoveryInfo->remote_address); + + char *addr = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == addr) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + return; + } + memset(addr, 0x0, len + 1); + + strncpy(addr, discoveryInfo->remote_address, len); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, + "Trying to do Gatt connection to [%s] ", addr); + + u_mutex_lock(gBleClientThreadPoolMutex); + if (NULL == gBleClientThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL"); + OICFree(addr); + u_mutex_unlock(gBleClientThreadPoolMutex); + return; + } + + CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CAGattConnectThread, + (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); + OICFree(addr); + u_mutex_unlock(gBleClientThreadPoolMutex); + return; + } + u_mutex_unlock(gBleClientThreadPoolMutex); + if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31) + { + bt_adapter_le_stop_device_discovery(); + return; + } + + }OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +void *CADiscoverBLEServicesThread(void *remoteAddress) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == remoteAddress) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param remoteAddress is NULL "); + return NULL; + } + + char *address = (char *) remoteAddress; + + CAResult_t result = CABleDiscoverServices(remoteAddress); + + OICFree(address); + address = NULL; + + if (CA_STATUS_OK != result) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleDiscoverServices Failed"); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT "); + return NULL; +} + +void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress, + void *userData) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN "); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result); + + if (NULL == remoteAddress) + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param remoteAddress is NULL "); + return; + } + + if (connected) + { + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress); + + int32_t len = strlen(remoteAddress); + + char *addr = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == addr) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + return; + } + memset(addr, 0x0, len + 1); + + strncpy(addr, remoteAddress, len); + + u_mutex_lock(gBleClientThreadPoolMutex); + if (NULL == gBleClientThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL"); + OICFree(addr); + u_mutex_unlock(gBleClientThreadPoolMutex); + return; + } + + CAResult_t 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); + OICFree(addr); + u_mutex_unlock(gBleClientThreadPoolMutex); + return; + } + u_mutex_unlock(gBleClientThreadPoolMutex); + } + else + { + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress); + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +CAResult_t CABleGATTCreateBond(const char *remoteAddress) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + if (NULL == remoteAddress) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "remoteAddress is NULL! "); + return CA_STATUS_FAILED; + } + + VERIFY_NON_NULL(remoteAddress, NULL, "Param remoteAddress is NULL"); + + int32_t ret = bt_device_create_bond(remoteAddress); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_device_create_bond Failed with ret value [%d] ", ret); + return CA_STATUS_FAILED; + } + else + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + " bt_device_create_bond query success for address [%s]", remoteAddress); + }OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + + return CA_STATUS_OK; + +} + +CAResult_t CABleDiscoverServices(const char *remoteAddress) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + VERIFY_NON_NULL(remoteAddress, NULL, "Param remoteAddress is NULL"); + + sleep(2); + + int32_t len = strlen(remoteAddress); + + char *addr = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == addr) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + return CA_STATUS_FAILED; + } + memset(addr, 0x0, len + 1); + + strncpy(addr, remoteAddress, len); + + int32_t ret = bt_gatt_foreach_primary_services(remoteAddress, CABleGattPrimaryServiceCb, + (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] ", + ret); + OICFree(addr); + return CA_STATUS_FAILED; + } + else + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "bt_gatt_foreach_primary_services success for address [%s]", remoteAddress); + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + + return CA_STATUS_OK; + +} + +CAResult_t CABleDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress) +{ + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + VERIFY_NON_NULL(service, NULL, "service is NULL"); + + VERIFY_NON_NULL(remoteAddress, NULL, "remoteAddress is NULL"); + + int32_t len = strlen(remoteAddress); + + char *addr = (char *) OICMalloc(sizeof(char) * len + 1); + if (NULL == addr) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc failed! "); + return CA_STATUS_FAILED; + } + memset(addr, 0x0, len + 1); + + strncpy(addr, remoteAddress, len); + + int32_t ret = bt_gatt_discover_characteristics(service, CABleGattCharacteristicsDiscoveredCb, + (void *) addr); // addr will be freed in callback. + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "bt_gatt_discover_characteristics failed with error [%d]", ret); + OICFree(addr); + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + + return CA_STATUS_OK; + +} + +CAResult_t CAStartBLEGattClient() +{ + CAResult_t retVal = CAInitGattClientMutexVaraibles(); + + if (retVal != CA_STATUS_OK) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVaraibles failed!"); + CATerminateGattClientMutexVariables(); + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + u_mutex_unlock(gBleClientThreadPoolMutex); + if (NULL == gBleClientThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL"); + u_mutex_unlock(gBleClientThreadPoolMutex); + return CA_STATUS_FAILED; + } + + CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, + (void *) CAStartBleGattClientThread, (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 CA_STATUS_FAILED; + } + u_mutex_unlock(gBleClientThreadPoolMutex); + return CA_STATUS_OK; +} + +void *CAStartBleGattClientThread(void *data) +{ + u_mutex_lock(gBleClientStateMutex); + + if (CA_TRUE == gIsBleGattClientStarted) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running"); + u_mutex_unlock(gBleClientStateMutex); + CATerminateBLEGattClient(); + return NULL; + } + + bt_adapter_le_scan_params_s scan_param = + { 0, }; + scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN; + scan_param.interval = 1560; + scan_param.window = 160; + + int32_t ret = bt_adapter_le_set_scan_parameter(&scan_param); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed"); + u_mutex_unlock(gBleClientStateMutex); + CATerminateBLEGattClient(); + return NULL; + } + + ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, + "bt_gatt_set_connection_state_changed_cb Failed"); + u_mutex_unlock(gBleClientStateMutex); + CATerminateBLEGattClient(); + return NULL; + } + + ret = bt_adapter_le_set_device_discovery_state_changed_cb( + CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, + "bt_adapter_le_set_device_discovery_state_changed_cb Failed"); + u_mutex_unlock(gBleClientStateMutex); + CATerminateBLEGattClient(); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Setting characteristic_changed cb \n"); + + ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]", + CABTGetErrorMsg(ret)); + u_mutex_unlock(gBleClientStateMutex); + CATerminateBLEGattClient(); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Setting bt_device_set_bond_created_cb \n"); + + ret = bt_device_set_bond_created_cb(CABtGattBondCreatedCb, NULL); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, " bt_device_set_bond_created_cb Failed as [%s ]", + CABTGetErrorMsg(ret)); + u_mutex_unlock(gBleClientStateMutex); + return NULL; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery"); + + ret = bt_adapter_le_start_device_discovery(); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed"); + u_mutex_unlock(gBleClientStateMutex); + CATerminateBLEGattClient(); + return NULL; + } + else + { + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, + "bt_adapter_le_start_device_discovery Success"); + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + + u_mutex_unlock(gBleClientStateMutex); + + CAResult_t retVal = CAAdapterInitializeMessageQueue(&gCABleClientSenderQueue); + if (CA_STATUS_OK != retVal) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!"); + CATerminateBLEGattClient(); + return NULL; + } + + retVal = CAAdapterInitializeMessageQueue(&gCABleClientReceiverQueue); + if (CA_STATUS_OK != retVal) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!"); + CATerminateBLEGattClient(); + return NULL; + } + gIsBleGattClientStarted = CA_TRUE; + GMainContext *thread_context = NULL; + + thread_context = g_main_context_new(); + + g_event_loop = g_main_loop_new(thread_context, FALSE); + + g_main_context_push_thread_default(thread_context); + + g_main_loop_run(g_event_loop); + + return NULL; + +} + +void CAStopBLEGattClient() +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + u_mutex_lock(gBleClientStateMutex); + + if (CA_FALSE == gIsBleGattClientStarted) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop"); + + u_mutex_unlock(gBleClientStateMutex); + return; + } + u_mutex_unlock(gBleClientStateMutex); + + CATerminateBLEGattClient(); + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +void CATerminateBLEGattClient() +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + 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); + + if (context_event_loop) + { + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "g_event_loop context %x", context_event_loop); + + g_main_context_wakeup(context_event_loop); + + } + else + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_event_loop context is NULL"); + } + + // Kill g main loops and kill threads + g_main_loop_quit(g_event_loop); + + gClientUp = CA_FALSE; + + bt_gatt_unset_connection_state_changed_cb(); + + bt_adapter_le_stop_device_discovery(); + + bt_gatt_unset_characteristic_changed_cb(); + + bt_adapter_le_unset_device_discovery_state_changed_cb(); + + bt_gatt_unset_connection_state_changed_cb(); + + bt_adapter_le_disable(); + + bt_device_unset_bond_created_cb(); + bt_gatt_unset_characteristic_changed_cb(); + u_mutex_lock(gBleServiceListMutex); + + CAFreeBLEServiceList(gBLEServiceList); + + gBLEServiceList = NULL; + + u_mutex_unlock(gBleServiceListMutex); + + gIsBleGattClientStarted = CA_FALSE; + + u_mutex_unlock(gBleClientStateMutex); + + CAResetRegisteredServiceCount(); + + 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); + + CATerminateGattClientMutexVaraibles(); + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +CAResult_t CAInitGattClientMutexVaraibles() +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + u_mutex_init(); + if (NULL == gBleClientStateMutex) + { + gBleClientStateMutex = u_mutex_new(); + if (NULL == gBleClientStateMutex) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleServiceListMutex) + { + gBleServiceListMutex = u_mutex_new(); + if (NULL == gBleServiceListMutex) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleReqRespClientCbMutex) + { + gBleReqRespClientCbMutex = u_mutex_new(); + if (NULL == gBleReqRespClientCbMutex) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + 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(); + if (NULL == gBleClientThreadPoolMutex) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleClientSendCondWait) + { + gBleClientSendCondWait = u_cond_new(); + if (NULL == gBleClientSendCondWait) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_cond_new failed"); + return CA_STATUS_FAILED; + } + }OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CATerminateGattClientMutexVariables() +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + u_mutex_free(gBleClientReceiveDataMutex); + gBleClientReceiveDataMutex = NULL; + u_mutex_free(gBleClientStateMutex); + gBleClientStateMutex = NULL; + u_mutex_free(gBleServiceListMutex); + gBleServiceListMutex = NULL; + u_mutex_free(gBleReqRespClientCbMutex); + gBleReqRespClientCbMutex = NULL; + u_mutex_free(gBleClientSendDataMutex); + gBleClientSendDataMutex = NULL; + u_mutex_free(gBleClientThreadPoolMutex); + gBleClientThreadPoolMutex = NULL; + u_mutex_free(gBleClientSendCondWait); + gBleClientSendCondWait = NULL; + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +void CASetBleClientThreadPoolHandle(u_thread_pool_t handle) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + u_mutex_unlock(gBleClientThreadPoolMutex); + gBleClientThreadPool = handle; + u_mutex_unlock(gBleClientThreadPoolMutex); + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + +CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char *data, + int32_t dataLen, TRANSFER_TYPE type, int32_t position) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + VERIFY_NON_NULL(data, NULL, "data is NULL"); + + if (0 >= dataLen) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input!"); + return CA_STATUS_INVALID_PARAM; + } + + BLEServiceInfo *bleServiceInfo = NULL; + if (UNICAST == type) + { + VERIFY_NON_NULL(remoteAddress, NULL, "remoteAddress is NULL"); + u_mutex_lock(gBleServiceListMutex); + CAResult_t ret = CAGetBLEServiceInfo(gBLEServiceList, remoteAddress, &bleServiceInfo); + + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfo is failed!"); + u_mutex_unlock(gBleServiceListMutex); + return CA_STATUS_FAILED; + } + u_mutex_unlock(gBleServiceListMutex); + } + else if (MULTICAST == type) + { + u_mutex_lock(gBleServiceListMutex); + CAResult_t ret = CAGetBLEServiceInfoByPosition(gBLEServiceList, position, &bleServiceInfo); + + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed"); + u_mutex_unlock(gBleServiceListMutex); + return CA_STATUS_FAILED; + } + u_mutex_unlock(gBleServiceListMutex); + } + + VERIFY_NON_NULL(bleServiceInfo, NULL, "bleServiceInfo is NULL"); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen, + bleServiceInfo->bdAddress); + + char *value = (char *) OICMalloc(sizeof(char) * (dataLen + 1)); + + if (NULL == value) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed!"); + return CA_STATUS_FAILED; + } + memset(value, 0x0, (dataLen + 1)); + + strncpy(value, data, dataLen); + + int32_t ret = bt_gatt_set_characteristic_value_request(bleServiceInfo->write_char, value, + dataLen, CABleGattCharacteristicWriteCb); + + OICFree(value); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "bt_gatt_set_characteristic_value_request Failed with return val [%d]", + ret); + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CAUpdateCharacteristicsToAllGattServers(const char *data, int32_t dataLen) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + VERIFY_NON_NULL(data, NULL, "data is NULL"); + + if (0 >= dataLen) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "dataLen is less than or equal zero. Invalid input !"); + return CA_STATUS_INVALID_PARAM; + } + + int32_t pos = 0; + + int32_t NumberOfServersConnected = CAGetRegisteredServiceCount(); + + for (pos = 0; pos < NumberOfServersConnected; pos++) + { + /*remoteAddress will be NULL. + Since we have to send to all the address. pos will be used for getting remote address. + */ + int32_t ret = CAUpdateCharacteristicsToGattServer(NULL, data, dataLen, MULTICAST, pos); + + if (CA_STATUS_OK != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, + "CAUpdateCharacteristicsToGattServer Failed with return val [%d] ", ret); + } + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT "); + + return CA_STATUS_OK; +} +void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN"); + + u_mutex_lock(gBleReqRespClientCbMutex); + + gReqRespClientCallback = callback; + + u_mutex_unlock(gBleReqRespClientCbMutex); + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT"); +} + diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h new file mode 100644 index 0000000..2abc414 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h @@ -0,0 +1,448 @@ +/****************************************************************** +* +* 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 _BLE_CLIENT_ +#define _BLE_CLIENT_ + +#include +#include +#include + +#include "cacommon.h" +#include "caadapterutils.h" +#include "cableclientutil.h" +#include "caadapterinterface.h" +#include "logger.h" +#include "uthreadpool.h" + + +/** +* @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. +* 3. Start device discovery +* +* @param[in] data - Currently it will be NULL(no parameter) +* +* @return NULL on success or failure. +* +*/ +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. +* +* @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 CAInitGattClientMutexVaraibles(); + +/** +* @fn CATerminateGattClientMutexVaraibles +* @brief Used to terminate all required mutex variable for Gatt Client implementation. +* +* @return void +* +*/ +void CATerminateGattClientMutexVariables(); + +/** +* @fn CASetBleClientThreadPoolHandle +* @brief Used to Set the gThreadPool handle which is required for spawning new thread. +* +* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task. +* +* @return void +* +*/ +void CASetBleClientThreadPoolHandle(u_thread_pool_t handle); + + +/** +* @fn CABleGATTCreateBond +* @brief Used to make LE bond with remote device(pairng the device) using bt_device_create_bond api. +* +* @param[in] remoteAddress - mac address of remote device which we want to bond with +* +* @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 CABleGATTCreateBond(const char *remoteAddress); + + +/** +* @fn CABleDiscoverServices +* @brief Used to discover the services that is advertised by Gatt Server asynchrounously. +* +* @param[in] remoteAddress - mac address of remote device inwhich we want to discover the services. +* +* @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 CABleDiscoverServices(const char *remoteAddress); + +/** +* @fn CABleDiscoverCharacteristics +* @brief Used to discover the characteristics in specific service in remote device. +* +* @param[in] service -The attribute handle of service. Unique identifier for service. +* @param[in] remoteAddress - mac address of remote device inwhich we want to discover the services. +* +* @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 CABleDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress); + +/** +* @fn CARegisterForChangeInCharacterstics +* @brief Used to register a callback function that will be invoked when a characteristic value is changed. +* +* @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 CARegisterForChangeInCharacterstics(); + +/** +* @fn CABleGattPrimaryServiceCb +* @brief This is the callback which will be called when we get the primary services repeatedly. +* +* @param[in] service -The attribute handle of service. Unique identifier for service. +* @param[in] userData - user data +* +* @return 0 on failure and 1 on success. +* +*/ +CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, void *userData); + +/** +* @fn CABtGattCharacteristicsDiscoveredCb +* @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 +* @param[in] total The total number of characteristics in a service +* @param[in] characteristic The attribute handle of characteristic +* @param[in] userData The user data passed from the request function +* +* @return 0 on failure and 1 on success. +* +*/ +int32_t CABtGattCharacteristicsDiscoveredCb(int32_t result, int32_t inputIndex, int32_t total, + bt_gatt_attribute_h characteristic, void *userData); + + +/** +* @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 CAUpdateCharacteristicsToGattServer + * @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 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 CALEReadDataFromLEClient +* @brief synchronous function for reading characteristic 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 CALEReadDataFromLEClient(); + +/** +* @fn CABleClientSenderQueueEnqueueMessage +* @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 +* @param[in] dataLen Length of 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 CABleClientSenderQueueEnqueueMessage(CARemoteEndpoint_t *remoteEndpoint, + void *data, uint32_t dataLen); + +/** +* @fn CABleGattCharacteristicWriteCb +* @brief This is the callback which will be called after the characteristics changed. +* +* @param[in] handle The attribute handle of characteristic +* +* @return void +* +*/ +void CABleGattCharacteristicWriteCb(bt_gatt_attribute_h handle); + +/** +* @fn CABleClientSenderQueueProcessor +* @brief This is the thread which will be used for processing sender queue. +* +* @return NULL on success or failure. +* +*/ +void *CABleClientSenderQueueProcessor(); + +/** +* @fn CABleGattDescriptorDiscoveredCb +* @brief This is the callback which will be called when descriptor of characteristics is found. +* +* @param[in] result The result of discovering +* @param[in] format format of descriptor. +* @param[in] total The total number of descriptor in a characteristic +* @param[in] descriptor The attribute handle of descriptor +* @param[in] characteristic The attribute handle of characteristic +* @param[in] userData The user data passed from the request function +* +* @return void +* +*/ +void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32_t total, + bt_gatt_attribute_h descriptor, bt_gatt_attribute_h characteristic, void *userData); +/** +* @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. +* +* @return NULL on success or failure. +* +*/ +void *CADiscoverDescriptorThread(void *stServiceInfo); + +/** +* @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. +* +* @return NULL on success or failure. +* +*/ +void *CADiscoverCharThread(void *stServiceInfo); + +/** +* @fn CABtGattBondCreatedCb +* @brief This is the callback which will be called when bond created with remote device. +* +* @param[in] result The result of bond creation. +* @param[in] device_info remote device information +* @param[in] userData The user data passed from the request function +* +* @return void +* +*/ +void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *user_data); + +/** +* @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. +* +* @return NULL on success or failure. +* +*/ +void *CAGATTCreateBondThread(void *stServiceInfo); + +/** +* @fn CABleGattCharacteristicChangedCb +* @brief This is the callback which will be called after the characteristic value changes happen. +* +* @param[in] characteristic The attribute handle of characteristic +* @param[in] value Value of the characteristics of a service. +* @param[in] valueLen length of data. +* @param[in] userData The user data passed from the request function +* +* @return 0 on failure and 1 on success. +* +*/ +void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic, unsigned char *value, + int32_t valueLen, void *userData); + +/** +* @fn CABleGattCharacteristicsDiscoveredCb +* @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 +* @param[in] total The total number of characteristics in a service +* @param[in] characteristic The attribute handle of characteristic +* @param[in] userData The user data passed from the request function +* +* @return 0 on failure and 1 on success. +* +*/ +CABool_t CABleGattCharacteristicsDiscoveredCb(int32_t result, int32_t inputIndex, int32_t total, + bt_gatt_attribute_h characteristic, void *userData); + +/** +* @fn CAGATTCreateBondThread +* @brief This is the thread which will be used for making gatt connection with remote devices +* +* @param[in] remoteAddress Mac address of remote device which wants to connect with. +* +* @return NULL on success or failure. +* +*/ +void *CAGattConnectThread (void *remoteAddress); +/** +* @fn CAPrintDiscoveryInformation +* @brief Used to print device information(Util method) +* +* @param[in] discoveryInfo Device information structure. +* +* @return void +* +*/ +void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo); +/** +* @fn CABtAdapterLeDeviceDiscoveryStateChangedCb +* @brief This is the callback which will be called when the device discovery state changes. +* +* @param[in] result The result of discovering +* @param[in] discoveryState State of the discovery(FOUND/STARTED/ FINISHED) +* @param[in] discoveryInfo Remote Device information. +* @param[in] userData The user data passed from the request function +* +* @return void +* +*/ +void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result, + bt_adapter_le_device_discovery_state_e discoveryState, + bt_adapter_le_device_discovery_info_s *discoveryInfo, + void *userData); +/** +* @fn CADiscoverBLEServicesThread +* @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. +* +* @return NULL for success or failure. +* +*/ +void *CADiscoverBLEServicesThread (void *remoteAddress); + +/** +* @fn CABleGattConnectionStateChangedCb +* @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 +* @param[in] remoteAddress Mac address of the remote device in which we made connection. +* @param[in] userData The user data passed from the request function +* +* @return void +* +*/ +void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress, + void *userData); + + + +#endif //#ifndef _BLE_CLIENT_ diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.c new file mode 100644 index 0000000..2342bff --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.c @@ -0,0 +1,435 @@ +/****************************************************************** +* +* 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 "cableclientutil.h" + +#include +#include +#include +#include +#include +#include +#include + + +#include "caadapterutils.h" + +#define TZ_BLE_CLIENT_UTIL_TAG "TZ_BLE_GATT_CLIENT_UTIL" + +#define OIC_BLE_SERVICE_ID "000018f3-0000-1000-8000-00805f9b34fb" +///TODO: OIC_BLE_SERVICE_ID will be generated by invoking API in future. + +static BLEServiceList *gBLEServiceList = NULL; + +static int32_t gNumberOfServiceConnected = 0; + +void CAIncrementRegisteredServiceCount() +{ + gNumberOfServiceConnected++; +} + +void CADecrementRegisteredServiceCount() +{ + gNumberOfServiceConnected--; +} + +void CAResetRegisteredServiceCount() +{ + gNumberOfServiceConnected = 0; +} + +int32_t CAGetRegisteredServiceCount() +{ + return gNumberOfServiceConnected ; +} + +CAResult_t CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h service, + BLEServiceInfo **bleServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + + VERIFY_NON_NULL(bdAddress, NULL, " Param bdAddress is NULL"); + VERIFY_NON_NULL(service, NULL, " Param service is NULL"); + + *bleServiceInfo = (BLEServiceInfo *) OICMalloc(sizeof(BLEServiceInfo)); + if (NULL == *bleServiceInfo) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, " Malloc failed!"); + return CA_STATUS_FAILED; + } + memset(*bleServiceInfo, 0x0, sizeof(BLEServiceInfo)); + + int32_t len = strlen(bdAddress); + (*bleServiceInfo)->bdAddress = (char *) OICMalloc(sizeof(char) * len + 1); + + if (NULL == (*bleServiceInfo)->bdAddress) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, " Malloc failed!"); + + OICFree(*bleServiceInfo); + return CA_STATUS_FAILED; + } + memset((*bleServiceInfo)->bdAddress, 0x0, len + 1); + + strncpy((*bleServiceInfo)->bdAddress, bdAddress, len); + + if (service) + { + + int32_t ret = bt_gatt_clone_attribute_handle(&((*bleServiceInfo)->service_clone), service); + + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_UTIL_TAG, " service handle clone failed with ret [%d]", + ret); + OICFree((*bleServiceInfo)->bdAddress); + OICFree(*bleServiceInfo); + return CA_STATUS_FAILED; + } + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CAAppendBLECharInfo( bt_gatt_attribute_h characteristic, CHAR_TYPE type, + BLEServiceInfo *bleServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + + VERIFY_NON_NULL(characteristic, NULL, " Param characteristic is NULL"); + VERIFY_NON_NULL(bleServiceInfo, NULL, " Param bleServiceInfo is NULL"); + + if (READ_CHAR == type ) + { + int32_t ret = bt_gatt_clone_attribute_handle(&((bleServiceInfo)->read_char), characteristic); + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_UTIL_TAG, " read_char clone failed with ret [%d]", + ret); + return CA_STATUS_FAILED; + } + } + else if (WRITE_CHAR == type) + { + int32_t ret = bt_gatt_clone_attribute_handle(&((bleServiceInfo)->write_char), characteristic); + if (BT_ERROR_NONE != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_CLIENT_UTIL_TAG, " write_char clone failed with ret [%d]", + ret); + return CA_STATUS_FAILED; + } + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CAAddBLEServiceInfoToList(BLEServiceList **serviceList, BLEServiceInfo *bleServiceInfo) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + + VERIFY_NON_NULL(serviceList, NULL, " Param serviceList is NULL"); + VERIFY_NON_NULL(bleServiceInfo, NULL, " Param bleServiceInfo is NULL"); + + BLEServiceList *node = (BLEServiceList *) OICMalloc(sizeof(BLEServiceList)); + if (NULL == node) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "[ERROR]Malloc failed!"); + OICFree(bleServiceInfo->bdAddress); + OICFree(bleServiceInfo); + return CA_STATUS_FAILED; + } + memset(node, 0x0, sizeof(BLEServiceList)); + + node->serviceInfo = bleServiceInfo; + node->next = NULL; + + if (*serviceList == NULL) //Empty list + { + *serviceList = node; + } + else //Add at front end + { + node->next = *serviceList; + *serviceList = node; + } + + CAIncrementRegisteredServiceCount(); + + OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "Device [%s] added to list", bleServiceInfo->bdAddress); + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CARemoveBLEServiceInfoToList(BLEServiceList **serviceList, + BLEServiceInfo *bleServiceInfo, + const char *bdAddress) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + + VERIFY_NON_NULL(serviceList, NULL, "Param serviceList is NULL"); + VERIFY_NON_NULL(*serviceList, NULL, "Param *serviceList is NULL"); + VERIFY_NON_NULL(bdAddress, NULL, "Param bdAddress is NULL"); + + BLEServiceList *cur = NULL; + BLEServiceList *prev = NULL; + + cur = *serviceList; + while (cur != NULL) + { + if (!strcasecmp(cur->serviceInfo->bdAddress, bdAddress)) + { + if (cur == *serviceList) + { + *serviceList = cur->next; + + cur->next = NULL; + CAFreeBLEServiceList(cur); + CADecrementRegisteredServiceCount(); + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + return CA_STATUS_OK; + } + else + { + prev->next = cur->next; + + cur->next = NULL; + CAFreeBLEServiceList(cur); + CADecrementRegisteredServiceCount(); + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + return CA_STATUS_OK; + } + } + else + { + prev = cur; + cur = cur->next; + } + } + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, " OUT"); + return CA_STATUS_FAILED; + +} + +CAResult_t CAGetBLEServiceInfo(BLEServiceList *serviceList, const char *bdAddress, + BLEServiceInfo **bleServiceInfo) +{ + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + + VERIFY_NON_NULL(serviceList, NULL, "Param serviceList is NULL"); + VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL"); + VERIFY_NON_NULL(bdAddress, NULL, "Param bdAddress is NULL"); + + + BLEServiceList *cur = serviceList; + *bleServiceInfo = NULL; + while (cur != NULL) + { + if (!strcasecmp(cur->serviceInfo->bdAddress, bdAddress)) + { + *bleServiceInfo = cur->serviceInfo; + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + return CA_STATUS_OK; + } + + cur = cur->next; + } + + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, " OUT"); + return CA_STATUS_FAILED; +} + +CAResult_t CAGetBLEServiceInfoByPosition(BLEServiceList *serviceList, int32_t position, + BLEServiceInfo **bleServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + + VERIFY_NON_NULL(serviceList, NULL, "Param serviceList is NULL"); + VERIFY_NON_NULL(bleServiceInfo, NULL, "Param bleServiceInfo is NULL"); + + if (0 > position) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "Position Invalid input !"); + return CA_STATUS_INVALID_PARAM; + } + BLEServiceList *cur = serviceList; + *bleServiceInfo = NULL; + int32_t count = 0; + + while (cur != NULL) + { + if (position == count) + { + *bleServiceInfo = cur->serviceInfo; + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + return CA_STATUS_OK; + } + count++; + cur = cur->next; + } + return CA_STATUS_FAILED; +} + +void CAFreeBLEServiceList(BLEServiceList *serviceList) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + while (serviceList) + { + BLEServiceList *temp = serviceList; + serviceList = serviceList->next; + CAFreeBLEServiceInfo(temp->serviceInfo); + OICFree(temp); + } + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + return ; +} + +void CAFreeBLEServiceInfo(BLEServiceInfo *bleServiceInfo) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + if (bleServiceInfo) + { + if (bleServiceInfo->bdAddress) + { + bt_device_destroy_bond(bleServiceInfo->bdAddress); + bt_gatt_disconnect(bleServiceInfo->bdAddress); + OICFree(bleServiceInfo->bdAddress); + bt_gatt_destroy_attribute_handle(bleServiceInfo->service_clone); + bt_gatt_destroy_attribute_handle(bleServiceInfo->read_char); + bt_gatt_destroy_attribute_handle(bleServiceInfo->write_char); + } + OICFree(bleServiceInfo); + } + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + return ; +} + + +CAResult_t CAVerifyOICService(bt_gatt_attribute_h serviceHandle) +{ + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "IN"); + + VERIFY_NON_NULL(serviceHandle, NULL, "Param serviceHandle is NULL"); + + int32_t ret = 0; + char *uuid = NULL; + + ret = bt_gatt_get_service_uuid(serviceHandle, &uuid); + + if (0 != ret) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "bt_gatt_get_service_uuid failed !"); + return CA_STATUS_FAILED; + } + + if (strcasecmp(uuid, OIC_BLE_SERVICE_ID) != 0) + { + OIC_LOG(ERROR, TZ_BLE_CLIENT_UTIL_TAG, "It is not OIC service!"); + return CA_STATUS_FAILED; + } + OIC_LOG(DEBUG, TZ_BLE_CLIENT_UTIL_TAG, "OUT"); + return CA_STATUS_OK; +} + +const char *CABTGetErrorMsg(bt_error_e err) +{ + const char *errStr = NULL; + + switch (err) + { + case BT_ERROR_NONE: + errStr = "BT_ERROR_NONE"; + break; + case BT_ERROR_CANCELLED: + errStr = "BT_ERROR_CANCELLED"; + break; + case BT_ERROR_INVALID_PARAMETER: + errStr = "BT_ERROR_INVALID_PARAMETER"; + break; + case BT_ERROR_OUT_OF_MEMORY: + errStr = "BT_ERROR_OUT_OF_MEMORY"; + break; + case BT_ERROR_RESOURCE_BUSY: + errStr = "BT_ERROR_RESOURCE_BUSY"; + break; + case BT_ERROR_TIMED_OUT: + errStr = "BT_ERROR_TIMED_OUT"; + break; + case BT_ERROR_NOW_IN_PROGRESS: + errStr = "BT_ERROR_NOW_IN_PROGRESS"; + break; + case BT_ERROR_NOT_INITIALIZED: + errStr = "BT_ERROR_NOT_INITIALIZED"; + break; + case BT_ERROR_NOT_ENABLED: + errStr = "BT_ERROR_NOT_ENABLED"; + break; + case BT_ERROR_ALREADY_DONE: + errStr = "BT_ERROR_ALREADY_DONE"; + break; + case BT_ERROR_OPERATION_FAILED: + errStr = "BT_ERROR_OPERATION_FAILED"; + break; + case BT_ERROR_NOT_IN_PROGRESS: + errStr = "BT_ERROR_NOT_IN_PROGRESS"; + break; + case BT_ERROR_REMOTE_DEVICE_NOT_BONDED: + errStr = "BT_ERROR_REMOTE_DEVICE_NOT_BONDED"; + break; + case BT_ERROR_AUTH_REJECTED: + errStr = "BT_ERROR_AUTH_REJECTED"; + break; + case BT_ERROR_AUTH_FAILED: + errStr = "BT_ERROR_AUTH_FAILED"; + break; + case BT_ERROR_REMOTE_DEVICE_NOT_FOUND: + errStr = "BT_ERROR_REMOTE_DEVICE_NOT_FOUND"; + break; + case BT_ERROR_SERVICE_SEARCH_FAILED: + errStr = "BT_ERROR_SERVICE_SEARCH_FAILED"; + break; + case BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED: + errStr = "BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED"; + break; + case BT_ERROR_PERMISSION_DENIED: + errStr = "BT_ERROR_PERMISSION_DENIED"; + break; + case BT_ERROR_SERVICE_NOT_FOUND: + errStr = "BT_ERROR_SERVICE_NOT_FOUND"; + break; + case BT_ERROR_NOT_SUPPORTED: + errStr = "BT_ERROR_NOT_SUPPORTED"; + break; + default: + errStr = "NOT Defined"; + break; + } + + return errStr; +} + diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h new file mode 100644 index 0000000..7daf85e --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h @@ -0,0 +1,266 @@ +/****************************************************************** +* +* 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 _BLE_CLIENT_UTIL +#define _BLE_CLIENT_UTIL + +#include + +#include "cacommon.h" +#include "logger.h" + + +/** + * @struct BLEServiceInfo + * @brief Info regarding the GATTServer + * + * This structure holds the infomation about the GATTServer +* in the service and the characteristic level + */ +typedef struct +{ + bt_gatt_attribute_h service_clone; /**< gatt_attribute handler for the OIC service. */ + bt_gatt_attribute_h + read_char; /**< gatt_attribute handler for the OIC read characteristic. */ + bt_gatt_attribute_h + write_char; /**< gatt_attribute handler for the OIC write characteristic. */ + char *bdAddress; /**< BD address where OIC service is running. */ +} BLEServiceInfo; + +/** + * @struct BLEServiceList + * @brief List of the BLEServiceInfo structures. + * + * A list of BLEServiceInfo and gives the info about all the + * the registered services from the client side. + */ +typedef struct _BLEServiceList +{ + BLEServiceInfo *serviceInfo; /**< BLEServiceInfo strucutre from an OIC Server */ + struct _BLEServiceList *next; /**< next pointer */ +} BLEServiceList; + +/** + * @ENUM CHAR_TYPE + * @brief different characteristics types. + * + * This ENUM provides information of different characteristics + * which will be added to OIC service. + */ +typedef enum +{ + WRITE_CHAR, /**< write_char This will be used to get the unicast response */ + READ_CHAR, /**< read_char This will be used update value to OIC server */ + NOTIFY_CHAR /**< reserved char for the time being. */ +} CHAR_TYPE; + +/** + * @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; + +typedef struct gattCharDescriptor +{ + bt_gatt_attribute_h descriptor; + bt_gatt_attribute_h characteristic; + int total; +} stGattCharDescriptor_t; + +/** +* @fn CAIncrementRegisteredServiceCount +* @brief Used to increment the registered service count. +* +* @return void. +* +*/ +void CAIncrementRegisteredServiceCount(); + +/** +* @fn CADecrementRegisteredServiceCount +* @brief Used to decrement the registered service count. +* +* @return void. +* +*/ +void CADecrementRegisteredServiceCount(); + +/** +* @fn CAResetRegisteredServiceCount +* @brief Used to reset the registered service count. +* +* @return void. +* +*/ +void CAResetRegisteredServiceCount(); + +/** +* @fn CAGetRegisteredServiceCount +* @brief Used to get the total registered service count. +* +* @return total registered service count. +* +*/ +int32_t CAGetRegisteredServiceCount(); + +/** +* @fn CACreateBLEServiceInfo +* @brief Used to create BLEServiceInfo structure with server handler and BD address will be created. +* +* @param[in] bdAddress - BD address of the device where GATTServer is running. +* @param[in] service - service attribute handler. +* @param[in] bleServiceInfo - Pointer where serviceInfo structure needs to be stored. +* Memory will be allocated here and needs to be cleared by user. +* +* @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 CACreateBLEServiceInfo(const char *bdAddress, bt_gatt_attribute_h service, + BLEServiceInfo **bleServiceInfo); + +/** +* @fn CAAppendBLECharInfo +* @brief Used to append the characteristic info to the already created serviceInfo structure. +* +* @param[in] characteristic charecteristic attribute handler. +* @param[in] type specifies whether its READ_CHAR or WRITE_CHAR +* @param[in] bleServiceInfo Pointer where serviceInfo structure needs to be appended with char info. +* +* @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 CAAppendBLECharInfo(bt_gatt_attribute_h characteristic, CHAR_TYPE type, + BLEServiceInfo *bleServiceInfo); + +/** +* @fn CAAddBLEServiceInfoToList +* @brief Used to add the ServiceInfo structure to the Service List. +* +* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client. +* @param[in] bleServiceInfo Pointer where serviceInfo structure needs to be appended with char info. +* +* @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 CAAddBLEServiceInfoToList(BLEServiceList **serviceList, BLEServiceInfo *bleServiceInfo); + +/** +* @fn CARemoveBLEServiceInfoToList +* @brief Used to remove the ServiceInfo structure from the Service List. +* +* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client. +* @param[in] bleServiceInfo Pointer where serviceInfo structure needs to be appended with char info. +* @param[in] bdAddress BD address of the device where GATTServer is disconnected. +* +* @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 CARemoveBLEServiceInfoToList(BLEServiceList **serviceList, + BLEServiceInfo *bleServiceInfo, + const char *bdAddress); + +/** +* @fn CAGetBLEServiceInfo +* @brief Used to get the serviceInfo from the list. +* +* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client. +* @param[in] bdAddress BD address of the device where GATTServer information is required. +* @param[out] bleServiceInfo Pointer where serviceInfo structure needs to provide the service and char info. +* +* @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 CAGetBLEServiceInfo(BLEServiceList *serviceList, const char *bdAddress, + BLEServiceInfo **bleServiceInfo); + +/** +* @fn CAGetBLEServiceInfoByPosition +* @brief Used to get the serviceInfo from the list by position. +* +* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client. +* @param[in] position The service information of particular position in the list. +* @param[out] bleServiceInfo Pointer where serviceInfo structure needs to provide the service and char info. +* +* @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 CAGetBLEServiceInfoByPosition(BLEServiceList *serviceList, int32_t position, + BLEServiceInfo **bleServiceInfo); + +/** +* @fn CAFreeBLEServiceList +* @brief Used to get clear ble service list +* +* @param[in] serviceList Pointer to the ble service list which holds the info of list of service registered from client. +* +* @return void +* +*/ +void CAFreeBLEServiceList(BLEServiceList *serviceList); + +/** +* @fn CAFreeBLEServiceInfo +* @brief Used to get remove particular ble service info from list +* +* @param[in] serviceinfo Pointer to the structure which needs to be cleared. +* +* @return void +* +*/ +void CAFreeBLEServiceInfo(BLEServiceInfo *bleServiceInfo); + +/** +* @fn CAVerifyOICService +* @brief Used to check whether found handle is OIC service handle or not. +* +* @param[in] serviceHandle - Discovered service handle(unique identifier for 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 CAVerifyOICService(bt_gatt_attribute_h serviceHandle); + +#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 new file mode 100644 index 0000000..c0ce878 --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c @@ -0,0 +1,899 @@ +/****************************************************************** +* +* 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 "cableserver.h" +#include +#include "cacommon.h" +#include "caadapterutils.h" +#include +#include "umutex.h" +#include "camessagequeue.h" +#include "caadapterutils.h" + +/** + * @def TZ_BLE_SERVER_TAG + * @brief Logging tag for module name + */ +#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. + +static char *gGattSvcPath = NULL; + +static char *gGattReadCharPath = NULL; + +static char *gGattWriteCharPath = NULL; + +static bt_advertiser_h hAdvertiser = NULL; + +static CANetworkPacketReceivedCallback gReqRespCallback = NULL; + +static CAAdapterMessageQueue_t *gCABleServerSenderQueue = NULL; + +static CAAdapterMessageQueue_t *gCABleServerReceiverQueue = NULL; + +static CABool_t gIsBleGattServerStarted = CA_FALSE; + +/** + * @var gServiceStateMutex + * @brief Mutex to synchronize the process of starting Gatt Server. + */ +static u_mutex gBleServerStateMutex = NULL; + +static u_mutex gBleCharacteristicMutex = NULL; + +static u_mutex gBleServiceMutex = NULL; + +static u_mutex gBleReqRespCbMutex = NULL; + +static u_mutex gBleServerSendDataMutex = NULL; + +static u_mutex gBleServerThreadPoolMutex = NULL; + +static u_cond gBleServerSendCondWait = NULL; + +static u_mutex gBleServerReceiveDataMutex = NULL; + +static GMainLoop *g_event_loop = NULL; + +static u_thread_pool_t gBleServerThreadPool = NULL; + +static CABool_t gServerUp = CA_FALSE; + + +void *CABleServerSenderQueueProcessor() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN "); + + while (gServerUp) + { + CAAdapterMessage_t *senderData = NULL; + + 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, &senderData)) + { + if (senderData == NULL) + { + OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "senderData is NULL"); + continue; + } + result = CAUpdateCharacteristicsInGattServer(senderData->data, senderData->dataLen); + if (CA_STATUS_OK != result) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Failed to CAUpdateCharacteristicsInGattServer"); + } + else + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Failed to CAUpdateCharacteristicsInGattServer !"); + } + CAAdapterFreeMessage(senderData); + } + + u_mutex_unlock(gBleServerSendDataMutex); + } + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT "); + return NULL; +} + + +CAResult_t CAStartBleGattServer() +{ + ///TODO:: Check BT adapter is enabled or not ..if its not enabled, enable bt adapter. + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + CAResult_t ret = CAInitGattServerMutexVaraibles(); + + if (CA_STATUS_OK != ret ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAInitGattServerMutexVaraibles failed!"); + CATerminateGattServerMutexVaraibles(); + return CA_SERVER_NOT_STARTED; + } + + + u_mutex_lock(gBleServerThreadPoolMutex); + if (NULL == gBleServerThreadPool) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gBleServerThreadPool is NULL"); + u_mutex_unlock(gBleServerThreadPoolMutex); + return CA_STATUS_FAILED; + } + + ret = u_thread_pool_add_task(gBleServerThreadPool, (void *) CAStartBleGattServerThread, + (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; + } + + 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); + + //CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress); + u_mutex_unlock(gBleServerThreadPoolMutex); + return CA_STATUS_FAILED; + } + u_mutex_unlock(gBleServerThreadPoolMutex); + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void *CAStartBleGattServerThread(void *data) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + u_mutex_lock(gBleServerStateMutex); + if (CA_TRUE == gIsBleGattServerStarted) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Gatt Server is already running"); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + CAResult_t ret = CAInitBleGattService(); + + if (CA_STATUS_OK != ret ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_init_service failed"); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + sleep(5); // Sleep is must. otherwise its crashing + + char *serviceUUID = "000018f3-0000-1000-8000-00805f9b34fb"; + + ret = CAAddNewBleServiceInGattServer(serviceUUID); + + if (CA_STATUS_OK != ret ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewBleServiceInGattServer failed"); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + char *charReadUUID = "00002af5-0000-1000-8000-00805f9b34fb"; + + char charReadValue[4] = {33, 44, 55, 66}; + + ret = CAAddNewCharacteristicsToGattServer(gGattSvcPath, charReadUUID, charReadValue, 512 , + 0); // For Read Characteristics. + + if (CA_STATUS_OK != ret ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewCharacteristicsToGattServer failed"); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + char *charWriteUUID = "00002af6-0000-1000-8000-00805f9b34fb"; + + char charWriteValue[4] = {33, 44, 55, 66}; + + + ret = CAAddNewCharacteristicsToGattServer(gGattSvcPath, charWriteUUID, charWriteValue, 512 , + 1); // For Write Characteristics. + if (CA_STATUS_OK != ret ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAddNewCharacteristicsToGattServer failed"); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + ret = CARegisterBleServicewithGattServer(gGattSvcPath); + + if (CA_STATUS_OK != ret ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CARegisterBleServicewithGattServer failed"); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + bt_adapter_le_create_advertiser(&hAdvertiser); + + if (NULL == hAdvertiser) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "hAdvertiser is NULL"); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + int32_t retVal = bt_adapter_le_start_advertising(hAdvertiser, NULL, NULL, NULL); + + if (BT_ERROR_NONE != retVal) + { + OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "bt_adapter_le_start_advertising failed with ret [%d] ", + retVal); + u_mutex_unlock(gBleServerStateMutex); + CATerminateBleGattServer(); + return NULL; + } + + gIsBleGattServerStarted = CA_TRUE; + + u_mutex_unlock(gBleServerStateMutex); + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, + "LE Server initialization complete. Enabling gServerUp state to TRUE "); + gServerUp = CA_TRUE; + + GMainContext *thread_context = NULL; + + thread_context = g_main_context_new(); + + g_event_loop = g_main_loop_new(thread_context, FALSE); + + g_main_context_push_thread_default(thread_context); + + g_main_loop_run(g_event_loop); + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + + return NULL; + +} + +CAResult_t CAStopBleGattServer() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + u_mutex_lock(gBleServerStateMutex); + + if (CA_FALSE == gIsBleGattServerStarted) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Gatt Server is not running to stop"); + + u_mutex_unlock(gBleServerStateMutex); + return CA_STATUS_OK; + } + u_mutex_unlock(gBleServerStateMutex); + + CATerminateBleGattServer(); + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + + return CA_STATUS_OK; +} + +void CATerminateBleGattServer() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + int32_t ret = 0; + + u_mutex_lock(gBleServerStateMutex); + // Required for waking up the thread which is running in gmain loop + GMainContext *context_event_loop = g_main_loop_get_context(g_event_loop); + + if (context_event_loop) + { + OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "g_event_loop context %x", context_event_loop); + g_main_context_wakeup(context_event_loop); + } + else + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "g_event_loop context is NULL"); + } + + // Kill g main loops and kill threads + g_main_loop_quit(g_event_loop); + + if (NULL != hAdvertiser ) + { + ret = bt_adapter_le_stop_advertising(hAdvertiser); + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_adapter_le_stop_advertising failed with ret [%d]", ret); + } + + ret = bt_adapter_le_destroy_advertiser(hAdvertiser); + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_adapter_le_destroy_advertiser failed with ret [%d]", ret); + } + hAdvertiser = NULL; + } + + ret = CARemoveAllBleServicesFromGattServer(); + if (ret != 0) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "removeAllBleServicesFromGattServer failed"); + } + + ret = CADeInitBleGattService(); + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret); + } + + // free service Path(unique identifier for ble service) + u_mutex_lock(gBleServiceMutex); + OICFree(gGattSvcPath); + gGattSvcPath = NULL; + u_mutex_unlock(gBleServiceMutex); + + // freeing characteristics + u_mutex_lock(gBleCharacteristicMutex); + OICFree(gGattReadCharPath); + gGattReadCharPath = NULL; + OICFree(gGattWriteCharPath); + gGattWriteCharPath = NULL; + u_mutex_unlock(gBleCharacteristicMutex); + + gIsBleGattServerStarted = CA_FALSE; + gServerUp = CA_FALSE; + 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"); +} + +CAResult_t CAInitGattServerMutexVaraibles() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + u_mutex_init(); + if (NULL == gBleServerStateMutex) + { + gBleServerStateMutex = u_mutex_new(); + if (NULL == gBleServerStateMutex) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleServiceMutex) + { + gBleServiceMutex = u_mutex_new(); + if (NULL == gBleServiceMutex) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleCharacteristicMutex) + { + gBleCharacteristicMutex = u_mutex_new(); + if (NULL == gBleCharacteristicMutex) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed"); + return CA_STATUS_FAILED; + } + } + + if (NULL == gBleReqRespCbMutex) + { + gBleReqRespCbMutex = u_mutex_new(); + if (NULL == gBleReqRespCbMutex) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_mutex_new failed"); + 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; + } + } + + return CA_STATUS_OK; +} +void CATerminateGattServerMutexVaraibles() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + u_mutex_free(gBleServerStateMutex); + gBleServerStateMutex = NULL; + + u_mutex_free(gBleServerReceiveDataMutex); + gBleServerReceiveDataMutex = NULL; + u_mutex_free(gBleServerSendDataMutex); + gBleServerSendDataMutex = NULL; + + gBleServerStateMutex = NULL; + u_mutex_free(gBleServiceMutex); + gBleServiceMutex = NULL; + u_mutex_free(gBleCharacteristicMutex); + gBleCharacteristicMutex = NULL; + u_mutex_free(gBleReqRespCbMutex); + gBleReqRespCbMutex = NULL; + + u_mutex_free(gBleServerSendCondWait); + gBleServerSendCondWait = NULL; + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); +} +CAResult_t CAInitBleGattService() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + int32_t ret = _bt_gatt_init_service(); + + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret); + return CA_STATUS_FAILED; + } + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + return CA_STATUS_OK; +} + + +CAResult_t CADeInitBleGattService() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + int32_t ret = _bt_gatt_deinit_service(); + + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "_bt_gatt_deinit_service failed with ret [%d]", ret); + return CA_STATUS_FAILED; + } + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CASetBleServerThreadPoolHandle(u_thread_pool_t handle) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + u_mutex_lock(gBleServerThreadPoolMutex); + gBleServerThreadPool = handle; + u_mutex_unlock(gBleServerThreadPoolMutex); + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); +} + + +CAResult_t CALEReadDataFromLEServer() +{ +#if 0 + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN "); + + CAAdapterMessage_t *receiverData = NULL; + + CAResult_t result = CAAdapterDequeueMessage(gCABleServerReceiverQueue, &receiverData); + + if (CA_STATUS_OK != result) + { + u_mutex_lock(gBleReqRespCbMutex); + if (NULL == gReqRespCallback) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!"); + u_mutex_unlock(gBleReqRespCbMutex); + return; + } + + gReqRespCallback(receiverData->remoteEndpoint, receiverData->data, receiverData->dataLen); + + u_mutex_unlock(gBleReqRespCbMutex); + + CAAdapterFreeMessage(receiverData); + } +#endif + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT "); +} + +CAResult_t CAAddNewBleServiceInGattServer(const char *serviceUUID) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + VERIFY_NON_NULL(serviceUUID, NULL, "Param serviceUUID is NULL"); + + OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "service uuid %s", serviceUUID); + + char *svcPath = NULL; + + int32_t ret = bt_gatt_add_service(serviceUUID, &svcPath); + + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_add_service failed with ret [%d]", ret); + return CA_STATUS_FAILED; + } + + if (NULL != svcPath) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "AddNewBleServiceInGattServer ServicePath obtained is %s", + svcPath); + + u_mutex_lock(gBleServiceMutex); + + if (NULL != gGattSvcPath) + { + OICFree(gGattSvcPath); + gGattSvcPath = NULL; + } + gGattSvcPath = svcPath; + + u_mutex_unlock(gBleServiceMutex); + } + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CARemoveBleServiceFromGattServer(const char *svcPath) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + VERIFY_NON_NULL(svcPath, NULL, "Param svcPath is NULL"); + + int32_t ret = bt_gatt_remove_service(svcPath); + + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_remove_service failed [%d]", ret); + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CARemoveAllBleServicesFromGattServer() +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + int32_t ret = bt_gatt_delete_services(); + + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_delete_services failed with ret [%d]", ret); + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + + return CA_STATUS_OK; +} + +void CABleGattRemoteCharacteristicWriteCb(char *charPath, + unsigned char *charValue, + int32_t charValueLen, void *userData) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + if (NULL == charPath || NULL == charValue) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Param callback values are NULL"); + return; + } + + OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "charPath = [%s] charValue = [%s] len [%d]", charPath, + charValue, charValueLen); + CARemoteEndpoint_t *remoteEndPoint = (CARemoteEndpoint_t *) OICMalloc(sizeof(CARemoteEndpoint_t)); + if (NULL == remoteEndPoint) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc Failure!"); + return; + } + memset(remoteEndPoint, 0x0, sizeof(CARemoteEndpoint_t)); + ///TODO: Currently Empty endpoint is being sent. + ///TODO:Later proper remote address has to be added when tizen team changed their code +#if 0 + VERIFY_NON_NULL(gCABleServerReceiverQueue, TZ_BLE_SERVER_TAG, "BleServerReceiverQueue is NULL"); + + CAResult_t retVal = CAAdapterEnqueueMessage(gCABleServerReceiverQueue, remoteEndPoint, charValue, + charValueLen); + if (CA_STATUS_OK != retVal ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAdapterEnqueueMessage failed!"); + return; + } +#endif + + char *data = (char *)OICMalloc(sizeof(char) * charValueLen + 1); + if (NULL == data) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc failed!"); + OICFree(remoteEndPoint); + return; + } + + memset(data, 0x0, charValueLen + 1); + + strncpy(data, charValue, charValueLen); + + u_mutex_lock(gBleReqRespCbMutex); + if (NULL == gReqRespCallback) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!"); + OICFree(charValue); + OICFree(remoteEndPoint); + u_mutex_unlock(gBleReqRespCbMutex); + return; + } + + gReqRespCallback(remoteEndPoint, data, charValueLen); + u_mutex_unlock(gBleReqRespCbMutex); + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); +} + +CAResult_t CABleServerSenderQueueEnqueueMessage(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 ) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAdapterEnqueueMessage failed!"); + u_mutex_unlock(gBleServerSendDataMutex); + return CA_STATUS_FAILED; + } + 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 "); + + return CA_STATUS_OK; +} + +CAResult_t CARegisterBleServicewithGattServer(const char *svcPath) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + VERIFY_NON_NULL(svcPath, NULL, "Param svcPath is NULL"); + + OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "svcPath:%s", svcPath); + + int32_t ret = bt_gatt_register_service(svcPath, CABleGattRemoteCharacteristicWriteCb, NULL); + + if (ret != 0) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_register_service failed with ret [%d]", ret); + return CA_STATUS_FAILED; + } + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUUID, char *charValue, + int32_t charValueLen, int32_t read) +{ + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + const char *charFlags[4] = {"read", "write", "notify", "indicate"}; + + char *charPath = NULL; + + int32_t flagLen = 4; + + int32_t ret = bt_gatt_add_characteristic(charUUID, charValue, charValueLen, charFlags, flagLen, + svcPath, &charPath); + + if (ret != 0 || charPath == NULL) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_add_characteristic failed with ret [%d]", ret); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "bt_gatt_add_characteristic charPath obtained: %s", charPath); + + u_mutex_lock(gBleCharacteristicMutex); + + if (read == 0) + { + if (NULL != gGattReadCharPath) + { + OICFree(gGattReadCharPath); + gGattReadCharPath = NULL; + } + gGattReadCharPath = charPath; + + } + else + { + if (NULL != gGattWriteCharPath) + { + OICFree(gGattWriteCharPath); + gGattWriteCharPath = NULL; + } + gGattWriteCharPath = charPath; + } + + u_mutex_unlock(gBleCharacteristicMutex); + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); + + return CA_STATUS_OK; +} + +CAResult_t CARemoveCharacteristicsFromGattServer(const char *charPath) +{ + ///TODO: There is no api provided in bluetooth.h for removing characteristics. + return CA_STATUS_OK; +} + +CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, int32_t charValueLen) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + VERIFY_NON_NULL(charValue, NULL, "Param charValue is NULL"); + + u_mutex_lock(gBleCharacteristicMutex); + + if (NULL == gGattWriteCharPath) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gGattWriteCharPath is NULL"); + u_mutex_unlock(gBleCharacteristicMutex); + return CA_STATUS_FAILED; + } + + char *data = (char *) OICMalloc(sizeof(char) * (charValueLen + 1)); + + if (NULL == data) + { + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "malloc failed!"); + u_mutex_unlock(gBleCharacteristicMutex); + return CA_STATUS_FAILED; + } + memset(data, 0x0, (charValueLen + 1)); + + strncpy(data, charValue, charValueLen); + + int32_t ret = bt_gatt_update_characteristic(gGattWriteCharPath, data, charValueLen); + + OICFree(data); + data = NULL; + + if (0 != ret) + { + OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_update_characteristic failed with return [%d]", ret); + u_mutex_unlock(gBleCharacteristicMutex); + return CA_STATUS_FAILED; + } + + u_mutex_unlock(gBleCharacteristicMutex); + + OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "OUT"); + + return CA_STATUS_OK; +} + +void CASetBLEReqRespServerCallback(CANetworkPacketReceivedCallback callback) +{ + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN"); + + u_mutex_lock(gBleReqRespCbMutex); + + gReqRespCallback = callback; + + u_mutex_unlock(gBleReqRespCbMutex); + + OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT"); +} + diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h new file mode 100644 index 0000000..0f632be --- /dev/null +++ b/resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.h @@ -0,0 +1,306 @@ +/****************************************************************** +* +* 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 __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(); + +/** +* @fn CAStartBleGattServerThread +* @brief This is thread which will be used for creating ble service and advertise ble service. +* 1. Create New OIC Service 2. Add two read & write characteristics to service. +* 3. Register Service 4. Advertise service. +* +* @param[in] data - Currently it will be NULL. +* +* @return NULL on sucess or failure. +* +*/ +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. +* +* @return void +* +*/ +void CATerminateBleGattServer(); + +/** +* @fn CAInitBleGattService +* @brief Used to initialize gatt service using _bt_gatt_init_service api. +* +* @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 CAInitBleGattService(); + +/** +* @fn CADeInitBleGattService +* @brief Used to de-initialize gatt service using _bt_gatt_deinit_service api. +* +* @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 CADeInitBleGattService(); + +/** +* @fn CAInitGattServerMutexVaraibles +* @brief Used to initialize all required mutex varaibles for GATT server implementation. +* +* @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 CAInitGattServerMutexVaraibles(); + + +/** +* @fn CATerminateGattServerMutexVaraibles +* @brief Used to terminate all required mutex varaibles for GATT server implementation. +* +* @return void +* +*/ +void CATerminateGattServerMutexVaraibles(); + +/** +* @fn CASetBleServerThreadPoolHandle +* @brief Used to Set the gThreadPool handle which is required for spawning new thread. +* +* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task. +* +* @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 CASetBleServerThreadPoolHandle(u_thread_pool_t handle); + +/** +* @fn CAAddNewBleServiceInGattServer +* @brief Used to add new OIC service in GATT server using bt_gatt_add_service api and +* internally store service path(outparam) in global variable +* +* @param[in] serviceUUID - unique identifier for BLE OIC 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 CAAddNewBleServiceInGattServer(const char *serviceUUID); + +/** +* @fn CARemoveBleServiceFromGattServer +* @brief Used to remove already registered service from Gatt Server using bt_gatt_remove_service api. +* +* @param[in] svcPath - unique identifier for BLE OIC service which is outparam of bt_gatt_add_service api. +* +* @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 CARemoveBleServiceFromGattServer(const char *svcPath); + +/** +* @fn CARemoveAllBleServicesFromGattServer +* @brief Used to remove all the registered service from Gatt Server using bt_gatt_delete_services api. +* +* +* @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 CARemoveAllBleServicesFromGattServer(); + +/** +* @fn CARegisterBleServicewithGattServer +* @brief Used to register the service in Gatt Server using bt_gatt_register_service api. +* +* @param[in] svcPath - unique identifier for BLE OIC service which is outparam of bt_gatt_add_service api. +* +* @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 CARegisterBleServicewithGattServer(const char *svcPath); + +/** +* @fn CAAddNewCharacteristicsToGattServer +* @brief Used to add new characteristics(Read/Write) to the service in Gatt Server using bt_gatt_add_characteristic api. +* +* @param[in] svcPath service path to which this characteristic belongs to. +* @param[in] charUUID - Gatt characteristic uuid. +* @param[in] charValue -Gatt characteristic value. +* @param[in] charValueLen - Caracteristic value length. +* @param[in] read - boolean varaible for checking whether read characteristics or write characteristics. +* +* @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 CAAddNewCharacteristicsToGattServer(const char *svcPath, char *charUUID, char *charValue, + int32_t charValueLen, int32_t read); + +/** +* @fn CARemoveCharacteristicsFromGattServer +* @brief Used to remove characteristics(Read/Write) from the service in Gatt Server. +* +* @param[in] charPath characteristic path registered on the interface and unique identifier for added characteristics. +* +* @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 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. +* +* @param[in] charPath - characteristic path registered on the interface and unique identifier for added characteristics. +* @param[in] charValue - data which is send by client. +* @param[in] charValueLen - length of the data. +* @param[in] userData - user data +* +* @return void +* +*/ +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. +* +* @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 CALEReadDataFromLEServer(); + +/** +* @fn CABleServerSenderQueueEnqueueMessage +* @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 +* @param[in] dataLen Length of 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 CABleServerSenderQueueEnqueueMessage(CARemoteEndpoint_t *remoteEndpoint, + void *data, uint32_t dataLen); + +/** +* @fn CABleServerSenderQueueProcessor +* @brief This is the thread which will be used for processing receiver queue. +* +* @return NULL on success or failure. +* +*/ +void *CABleServerSenderQueueProcessor(); + +#endif //#ifndef __TZ_BLE_SERVER_H_ diff --git a/resource/csdk/connectivity/src/caconnectivitymanager.c b/resource/csdk/connectivity/src/caconnectivitymanager.c index 29da713..4e8c2cc 100644 --- a/resource/csdk/connectivity/src/caconnectivitymanager.c +++ b/resource/csdk/connectivity/src/caconnectivitymanager.c @@ -25,22 +25,17 @@ #include "cainterface.h" #include "caremotehandler.h" #include "camessagehandler.h" +#include "caprotocolmessage.h" #include "canetworkconfigurator.h" #include "cainterfacecontroller.h" #include "logger.h" #define TAG PCF("CA") -static void CAMessageHandler(int32_t id, CADetachErrorCode code) -{ -} - CAResult_t CAInitialize() { OIC_LOG_V(DEBUG, TAG, "CAInitialize"); - CASetMessageHandlerCallback(CAMessageHandler); - CAResult_t res = CAInitializeMessageHandler(); if (res != CA_STATUS_OK) @@ -116,73 +111,51 @@ void CADestroyToken(CAToken_t token) CADestroyTokenInternal(token); } -CAResult_t CAGetNetworkInformation(CALocalConnectivityt_t **info, uint32_t* size) +CAResult_t CAGetNetworkInformation(CALocalConnectivity_t **info, uint32_t* size) { OIC_LOG_V(DEBUG, TAG, "CAGetNetworkInformation"); - return CA_NOT_SUPPORTED; + return CAGetNetworkInformationInternal(info, size); } CAResult_t CAFindResource(const CAURI_t resourceUri) { OIC_LOG_V(DEBUG, TAG, "CAFindResource"); - int32_t actionId = -1; - - actionId = CADetachMessageResourceUri(resourceUri); + return CADetachMessageResourceUri(resourceUri, NULL, 0); - if (actionId == -1) - return CA_SEND_FAILED; - - OIC_LOG_V(DEBUG, TAG, "action id : %d", actionId); - - return CA_STATUS_OK; } CAResult_t CASendRequest(const CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo) { OIC_LOG_V(DEBUG, TAG, "CASendGetRequest"); - int32_t actionId = -1; - - actionId = CADetachRequestMessage(object, requestInfo); - - if (actionId == -1) - return CA_SEND_FAILED; - - OIC_LOG_V(DEBUG, TAG, "action id : %d", actionId); - - return CA_STATUS_OK; + return CADetachRequestMessage(object, requestInfo); } CAResult_t CASendNotification(const CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo) { OIC_LOG_V(DEBUG, TAG, "CASendNotification"); - return CA_NOT_SUPPORTED; + return CADetachResponseMessage(object, responseInfo); + } CAResult_t CASendResponse(const CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo) { OIC_LOG_V(DEBUG, TAG, "CASendResponse"); - int32_t actionId = -1; - - actionId = CADetachResponseMessage(object, responseInfo); + return CADetachResponseMessage(object, responseInfo); - if (actionId == -1) - return CA_SEND_FAILED; - - OIC_LOG_V(DEBUG, TAG, "action id : %d", actionId); - - return CA_STATUS_OK; } -CAResult_t CAAdvertiseResource(const CAURI_t uri, CAHeaderOption_t* options, uint8_t numOptions) +CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAHeaderOption_t* options, + uint8_t numOptions) { OIC_LOG_V(DEBUG, TAG, "CAAdvertiseResource"); - return CA_NOT_SUPPORTED; + return CADetachMessageResourceUri(resourceUri, options, numOptions); + } CAResult_t CASelectNetwork(const uint32_t interestedNetwork) diff --git a/resource/csdk/connectivity/src/cainterfacecontroller.c b/resource/csdk/connectivity/src/cainterfacecontroller.c index 981eef9..867bca1 100644 --- a/resource/csdk/connectivity/src/cainterfacecontroller.c +++ b/resource/csdk/connectivity/src/cainterfacecontroller.c @@ -24,20 +24,30 @@ #include #include "cainterfacecontroller.h" +#include "cawifiadapter.h" +#include "caethernetadapter.h" #include "caedradapter.h" #include "caleadapter.h" -#include "cawifiethernetadapter.h" +#include "cawifiadapter.h" +#include "caethernetadapter.h" #include "canetworkconfigurator.h" +#include "caremotehandler.h" +#include "oic_malloc.h" #include "logger.h" +#include "uthreadpool.h" #define TAG PCF("CA") +#define CA_MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "memory error"); goto memory_error_exit;} } + #define CA_CONNECTIVITY_TYPE_NUM 4 static CAConnectivityHandler_t gAdapterHandler[CA_CONNECTIVITY_TYPE_NUM]; static CANetworkPacketReceivedCallback gNetworkPacketReceivedCallback = NULL; +static CANetworkChangeCallback gNetworkChangeCallback = NULL; + static int8_t CAGetAdapterIndex(CAConnectivityType_t cType) { switch (cType) @@ -56,6 +66,7 @@ static int8_t CAGetAdapterIndex(CAConnectivityType_t cType) static void CARegisterCallback(CAConnectivityHandler_t handler, CAConnectivityType_t cType) { + OIC_LOG(DEBUG, TAG, "CARegisterCallback - Entry"); int8_t index = -1; index = CAGetAdapterIndex(cType); @@ -82,12 +93,18 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t* endpoint, void* data, u } } -static void CANetworkChangedCallback(CALocalConnectivityt_t* info, CANetworkStatus_t status) +static void CANetworkChangedCallback(CALocalConnectivity_t* info, CANetworkStatus_t status) { OIC_LOG(DEBUG, TAG, "Network Changed callback"); + + // Call the callback. + if (gNetworkChangeCallback != NULL) + { + gNetworkChangeCallback(info, status); + } } -void CAInitializeAdapters() +void CAInitializeAdapters(u_thread_pool_t handle) { OIC_LOG(DEBUG, TAG, "initialize adapters.."); @@ -95,19 +112,19 @@ void CAInitializeAdapters() // Initialize adapters and register callback. #ifdef ETHERNET_ADAPTER - CAInitializeEthernet(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback); + CAInitializeEthernet(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle); #endif /* ETHERNET_ADAPTER */ #ifdef WIFI_ADAPTER - CAInitializeWifi(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback); + CAInitializeWifi(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle); #endif /* WIFI_ADAPTER */ #ifdef EDR_ADAPTER - CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback); + CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle); #endif /* EDR_ADAPTER */ #ifdef LE_ADAPTER - CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback); + CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle); #endif /* LE_ADAPTER */ } @@ -119,6 +136,13 @@ void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback) gNetworkPacketReceivedCallback = callback; } +void CASetNetworkChangeCallback(CANetworkChangeCallback callback) +{ + OIC_LOG(DEBUG, TAG, "Set network change callback"); + + gNetworkChangeCallback = callback; +} + void CAStartAdapter(CAConnectivityType_t cType) { OIC_LOG_V(DEBUG, TAG, "Start the adapter of CAConnectivityType[%d]", cType); @@ -159,6 +183,90 @@ void CAStopAdapter(CAConnectivityType_t cType) } } +CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t* size) +{ + CAResult_t res = CA_STATUS_FAILED; + int8_t index = 0; + int8_t i = 0; + + CALocalConnectivity_t* resInfo = NULL; + uint32_t resSize = 0; + + CALocalConnectivity_t* tempInfo[CA_CONNECTIVITY_TYPE_NUM]; + uint32_t tempSize[CA_CONNECTIVITY_TYPE_NUM]; + + memset(tempInfo, 0, sizeof(CALocalConnectivity_t*) * CA_CONNECTIVITY_TYPE_NUM); + memset(tempSize, 0, sizeof(int8_t) * CA_CONNECTIVITY_TYPE_NUM); + + // #1. get information each adapter + for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++) + { + if (gAdapterHandler[index].GetnetInfo != NULL) + { + 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); + } + } + + resSize = 0; + for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++) + { + // check information + if (tempInfo[index] == NULL || tempSize[index] <= 0) + { + continue; + } + + // #2. total size + resSize += tempSize[index]; + } + + OIC_LOG_V(DEBUG, TAG, "network info total size is %d!", resSize); + + if (resSize <= 0) + { + return res; + } + + // #3. add data into result + // memory allocation + resInfo = (CALocalConnectivity_t*) OICMalloc(sizeof(CALocalConnectivity_t) * resSize); + CA_MEMORY_ALLOC_CHECK(resInfo); + memset(resInfo, 0, sizeof(CALocalConnectivity_t) * resSize); + + i = 0; + for (index = 0; index < CA_CONNECTIVITY_TYPE_NUM; index++) + { + // check information + if (tempInfo[index] == NULL || tempSize[index] <= 0) + { + continue; + } + + memcpy(resInfo + i, tempInfo[index], sizeof(CALocalConnectivity_t) * tempSize[index]); + + i += tempSize[index]; + + // free adapter data + OICFree(tempInfo[index]); + } + + // #5. save data + *info = resInfo; + *size = resSize; + + OIC_LOG_V(DEBUG, TAG, "each network info save success!"); + + return res; + + // memory error label. + memory_error_exit: + + return CA_MEMORY_ALLOC_FAILED; +} + CAResult_t CASendUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t length) { OIC_LOG(DEBUG, TAG, "Send unicast data to enabled interface.."); diff --git a/resource/csdk/connectivity/src/camessagehandler.c b/resource/csdk/connectivity/src/camessagehandler.c index 9552827..f27d95f 100644 --- a/resource/csdk/connectivity/src/camessagehandler.c +++ b/resource/csdk/connectivity/src/camessagehandler.c @@ -27,141 +27,59 @@ #include "camessagehandler.h" #include "caremotehandler.h" #include "cainterfacecontroller.h" +#include "caprotocolmessage.h" #include "uqueue.h" #include "logger.h" #include "config.h" /* for coap protocol */ #include "coap.h" #include "uthreadpool.h" /* for thread pool */ +#include "caqueueingthread.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"); goto memory_error_exit;} } -#define MAX_ACTION_NUM 300 #define MAX_THREAD_POOL_SIZE 10 -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif +typedef enum +{ + SEND_TYPE_MULTICAST = 0, SEND_TYPE_UNICAST +} CASendDataType_t; typedef struct { - int32_t actionId; + CASendDataType_t type; CARemoteEndpoint_t* remoteEndpoint; CARequestInfo_t* requestInfo; CAResponseInfo_t* responseInfo; + CAHeaderOption_t* options; + uint8_t numOptions; } CAData_t; -typedef void (*CAThreadTask)(CAData_t* data); - -typedef struct -{ - u_mutex threadMutex; - u_cond threadCond; - CAThreadTask threadTask; - int32_t isStop; - u_queue_t* dataQueue; -} CAThread_t; - // thread pool handle static u_thread_pool_t gThreadPoolHandle = NULL; // message handler main thread -static CAThread_t gSendThread; - -// message handler callback -static int32_t gCurrentActionId = 0; -static CAMessageHandlerCallback gHandlerCallback = NULL; +static CAQueueingThread_t gSendThread; +static CAQueueingThread_t gReceiveThread; // handler field static CARequestCallback gRequestHandler = NULL; static CAResponseCallback gResponseHandler = NULL; -static u_queue_t* gMessageQueue = NULL; -static u_mutex gMessageQueueMutex = NULL; - -static void CAAddReceiveData(CAData_t* data) +static void CAReceiveThreadProcess(void* threadData) { - OIC_LOG_V(DEBUG, TAG, "CAAddReceiveData"); - - // create thread data - u_queue_message_t* message = (u_queue_message_t*) OICMalloc(sizeof(u_queue_message_t)); - - if (message == NULL) - { - OIC_LOG_V(DEBUG, TAG, "memory error!!"); - return; - } - memset(message, 0, sizeof(u_queue_message_t)); - - message->msg = data; - message->size = sizeof(CAData_t); - - // mutex lock - u_mutex_lock(gMessageQueueMutex); - - // add thread data into list - u_queue_add_element(gMessageQueue, message); - - // mutex unlock - u_mutex_unlock(gMessageQueueMutex); + // TODO + // currently not support. + // CAHandleRequestResponseCallbacks codes will move to this function. } -static void CAAddSendData(CAData_t* data) +static void CASendThreadProcess(void* threadData) { - OIC_LOG_V(DEBUG, TAG, "CAAddSendData!!"); + CAData_t* data = (CAData_t*) threadData; - // create thread data - u_queue_message_t* message = (u_queue_message_t*) OICMalloc(sizeof(u_queue_message_t)); - - if (message == NULL) - { - OIC_LOG_V(DEBUG, TAG, "memory error!!"); - return; - } - memset(message, 0, sizeof(u_queue_message_t)); - - message->msg = data; - message->size = sizeof(CAData_t); - - // mutex lock - u_mutex_lock(gSendThread.threadMutex); - - // add thread data into list - u_queue_add_element(gSendThread.dataQueue, message); - - // notity the thread - u_cond_signal(gSendThread.threadCond); - - // mutex unlock - u_mutex_unlock(gSendThread.threadMutex); -} - -static void CAStopSendThread() -{ - OIC_LOG_V(DEBUG, TAG, "CAStopSendThread request!!"); - - // mutex lock - u_mutex_lock(gSendThread.threadMutex); - - // set stop flag - gSendThread.isStop = TRUE; - - // notity the thread - u_cond_signal(gSendThread.threadCond); - - // mutex unlock - u_mutex_unlock(gSendThread.threadMutex); -} - -static void CASendThreadProcess(CAData_t* data) -{ if (data == NULL) { OIC_LOG(DEBUG, TAG, "thread data error!!"); @@ -174,39 +92,32 @@ static void CASendThreadProcess(CAData_t* data) return; } - OIC_LOG_V(DEBUG, TAG, "thread action id : %d", data->actionId); + CAResult_t res = CA_STATUS_FAILED; - CADetachErrorCode code = FAIL; - int32_t res = 0; + CASendDataType_t type = data->type; - if (data->requestInfo != NULL) + if (type == SEND_TYPE_UNICAST) { - OIC_LOG(DEBUG, TAG, "requestInfo is available"); - coap_pdu_t* pdu = NULL; - pdu = CAGeneratePdu(data->remoteEndpoint->resourceUri, data->requestInfo->method, - data->requestInfo->info); - // interface controller function call. - if (NULL != pdu) + if (data->requestInfo != NULL) { - OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data); - - OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code); + OIC_LOG_V(DEBUG, TAG, "requestInfo is available.."); - OIC_LOG_V(DEBUG, TAG, "PDU Maker - buffer data : %s", pdu->hdr); - - res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length); + pdu = (coap_pdu_t*) CAGeneratePdu(data->remoteEndpoint->resourceUri, + data->requestInfo->method, data->requestInfo->info); } - } - else if (data->responseInfo != NULL) - { - OIC_LOG_V(DEBUG, TAG, "responseInfo is available.."); - - coap_pdu_t* pdu = NULL; + else if (data->responseInfo != NULL) + { + OIC_LOG_V(DEBUG, TAG, "responseInfo is available.."); - pdu = CAGeneratePdu(data->remoteEndpoint->resourceUri, data->responseInfo->result, - data->responseInfo->info); + pdu = (coap_pdu_t*) CAGeneratePdu(data->remoteEndpoint->resourceUri, + data->responseInfo->result, data->responseInfo->info); + } + else + { + OIC_LOG(DEBUG, TAG, "request info, response info is empty"); + } // interface controller function call. if (NULL != pdu) @@ -215,19 +126,24 @@ static void CASendThreadProcess(CAData_t* data) OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code); - OIC_LOG_V(DEBUG, TAG, "PDU Maker - buffer data : %x", pdu->hdr); + OIC_LOG_V(DEBUG, TAG, "PDU Maker - buffer data : %s", pdu->hdr); res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length); } + } - else + else if (type == SEND_TYPE_MULTICAST) { OIC_LOG(DEBUG, TAG, "both requestInfo & responseInfo is not available"); coap_pdu_t* pdu = NULL; CAInfo_t info; memset(&info, 0, sizeof(CAInfo_t)); - pdu = CAGeneratePdu(data->remoteEndpoint->resourceUri, CA_GET, info); + + info.options = data->options; + info.numOptions = data->numOptions; + + pdu = (coap_pdu_t*) CAGeneratePdu(data->remoteEndpoint->resourceUri, CA_GET, info); if (NULL != pdu) { @@ -239,80 +155,16 @@ static void CASendThreadProcess(CAData_t* data) OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", pdu->hdr->id); - OIC_LOG_V(DEBUG, TAG, "PDU Maker - buffer data : %x", pdu->hdr); + OIC_LOG_V(DEBUG, TAG, "PDU Maker - buffer data : %s", pdu->hdr); res = CASendMulticastData(pdu->hdr, pdu->length); } - - } - - if (res) - { - code = SUCCESS; - } - - if (gHandlerCallback != NULL) - { - gHandlerCallback(data->actionId, code); - } -} - -static void* CAThreadBaseRoutine(void* treadData) -{ - OIC_LOG_V(DEBUG, TAG, "message handler main thread start.."); - - CAThread_t* thread = (CAThread_t*) treadData; - - if (thread == NULL) - { - OIC_LOG_V(DEBUG, TAG, "thread data passing error!!"); - - return NULL; } - - while (!thread->isStop) + else { - // mutex lock - u_mutex_lock(thread->threadMutex); - - // if queue is empty, thread will wait - if (u_queue_get_size(thread->dataQueue) <= 0) - { - OIC_LOG_V(DEBUG, TAG, "wait.."); - // wait - u_cond_wait(thread->threadCond, thread->threadMutex); - - OIC_LOG_V(DEBUG, TAG, "wake up.."); - } - - // mutex unlock - u_mutex_unlock(thread->threadMutex); - - // check stop flag - if (thread->isStop) - continue; - - // get data - u_queue_message_t* message = u_queue_get_element(thread->dataQueue); - - CAData_t* data = (CAData_t*) message->msg; - - // process data - thread->threadTask(data); + OIC_LOG(DEBUG, TAG, "unknown type!"); } - OIC_LOG_V(DEBUG, TAG, "message handler main thread end.."); - - return NULL; -} - -static int32_t CAIncreaseActionId() -{ - ++gCurrentActionId; - - gCurrentActionId = (gCurrentActionId > MAX_ACTION_NUM) ? 0 : gCurrentActionId; - - return gCurrentActionId; } static void CAReceivedPacketCallback(CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen) @@ -327,27 +179,36 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t* endpoint, void* data, u coap_pdu_t* pdu; uint32_t code = CA_NOT_FOUND; - pdu = CAParsePDU(data, &code); + pdu = (coap_pdu_t*) CAParsePDU((const char*) data, &code); + OICFree(data); + + char uri[CA_MAX_URI_LENGTH] = + { 0, }; if (code == CA_GET || code == CA_POST || code == CA_PUT || code == CA_DELETE) { - CARequestInfo_t ReqInfo; - memset(&ReqInfo, 0, sizeof(CARequestInfo_t)); - CAGetRequestInfoFromPdu(pdu, &ReqInfo); + CARequestInfo_t* ReqInfo; + ReqInfo = (CARequestInfo_t*) OICMalloc(sizeof(CARequestInfo_t)); + memset(ReqInfo, 0, sizeof(CARequestInfo_t)); + CAGetRequestInfoFromPdu(pdu, ReqInfo, uri); - if (NULL != ReqInfo.info.options && NULL != endpoint) + if (NULL != ReqInfo->info.options && NULL != endpoint) { - OIC_LOG_V(DEBUG, TAG, "Request PDU - optionID: %d", ReqInfo.info.options->optionID); + uint32_t i; + for (i = 0; i < ReqInfo->info.numOptions; i++) + { + OIC_LOG_V(DEBUG, TAG, "Request- optionID: %d", ReqInfo->info.options[i].optionID); - OIC_LOG_V(DEBUG, TAG, "Request PDU - optionlist: %s", ReqInfo.info.options->optionData); + OIC_LOG_V(DEBUG, TAG, "Request- list: %s", ReqInfo->info.options[i].optionData); + } - OIC_LOG_V(DEBUG, TAG, "Request PDU - payload: %s", ReqInfo.info.payload); + OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload); - OIC_LOG_V(DEBUG, TAG, "Request PDU - code: %d", ReqInfo.method); + OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method); - endpoint->resourceUri = (char*) OICMalloc(strlen(ReqInfo.info.options->optionData) + 1); - memcpy(endpoint->resourceUri, ReqInfo.info.options->optionData, - strlen(ReqInfo.info.options->optionData)); + endpoint->resourceUri = (char*) OICMalloc(strlen(uri) + 1); + memset(endpoint->resourceUri, 0, strlen(uri) + 1); + memcpy(endpoint->resourceUri, uri, strlen(uri)); OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri); } @@ -355,32 +216,37 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t* endpoint, void* data, u CAData_t* cadata = NULL; cadata = (CAData_t*) OICMalloc(sizeof(CAData_t)); memset(cadata, 0, sizeof(CAData_t)); - cadata->actionId = 1; + + cadata->type = SEND_TYPE_UNICAST; cadata->remoteEndpoint = endpoint; - cadata->requestInfo = &ReqInfo; + cadata->requestInfo = ReqInfo; cadata->responseInfo = NULL; - CAAddReceiveData(cadata); - + CAQueueingThreadAddData(&gReceiveThread, cadata, sizeof(CAData_t)); } else { - CAResponseInfo_t ResInfo; - memset(&ResInfo, 0, sizeof(CARequestInfo_t)); - CAGetResponseInfoFromPdu(pdu, &ResInfo); + CAResponseInfo_t* ResInfo; + ResInfo = (CAResponseInfo_t*) OICMalloc(sizeof(CAResponseInfo_t)); + memset(ResInfo, 0, sizeof(CAResponseInfo_t)); + CAGetResponseInfoFromPdu(pdu, ResInfo, uri); - if (NULL != ResInfo.info.options && NULL != endpoint) + if (NULL != ResInfo->info.options && NULL != endpoint) { - OIC_LOG_V(DEBUG, TAG, "Response PDU - optionID: %d", ResInfo.info.options->optionID); + uint32_t i; + for (i = 0; i < ResInfo->info.numOptions; i++) + { + OIC_LOG_V(DEBUG, TAG, "Response- optionID: %d", ResInfo->info.options[i].optionID); - OIC_LOG_V(DEBUG, TAG, "Response PDU - optionlist: %s", ResInfo.info.options->optionData); + OIC_LOG_V(DEBUG, TAG, "Response- list: %s", ResInfo->info.options[i].optionData); + } - OIC_LOG_V(DEBUG, TAG, "Response PDU - payload: %s", ResInfo.info.payload); + OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload); - OIC_LOG_V(DEBUG, TAG, "Response PDU - code: %d", ResInfo.result); + OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result); - endpoint->resourceUri = (char*) OICMalloc(strlen(ResInfo.info.options->optionData) + 1); - memcpy(endpoint->resourceUri, ResInfo.info.options->optionData, - strlen(ResInfo.info.options->optionData)); + endpoint->resourceUri = (char*) OICMalloc(strlen(uri) + 1); + memset(endpoint->resourceUri, 0, strlen(uri) + 1); + memcpy(endpoint->resourceUri, uri, strlen(uri)); OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri); } @@ -388,14 +254,21 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t* endpoint, void* data, u CAData_t* cadata = NULL; cadata = (CAData_t*) OICMalloc(sizeof(CAData_t)); memset(cadata, 0, sizeof(CAData_t)); - cadata->actionId = 1; + + cadata->type = SEND_TYPE_UNICAST; cadata->remoteEndpoint = endpoint; cadata->requestInfo = NULL; - cadata->responseInfo = &ResInfo; - CAAddReceiveData(cadata); + cadata->responseInfo = ResInfo; + + CAQueueingThreadAddData(&gReceiveThread, cadata, sizeof(CAData_t)); } } +static void CANetworkChangedCallback(CALocalConnectivity_t* info, CANetworkStatus_t status) +{ + OIC_LOG(DEBUG, TAG, "networkChangeCallback in message handler!!"); +} + void CAHandleRequestResponseCallbacks() { OIC_LOG_V(DEBUG, TAG, "CAHandleRequestResponseCallbacks"); @@ -404,11 +277,11 @@ void CAHandleRequestResponseCallbacks() // #1 parse the data // #2 get endpoint - u_mutex_lock(gMessageQueueMutex); + u_mutex_lock(gReceiveThread.threadMutex); - u_queue_message_t* item = u_queue_get_element(gMessageQueue); + u_queue_message_t* item = u_queue_get_element(gReceiveThread.dataQueue); - u_mutex_unlock(gMessageQueueMutex); + u_mutex_unlock(gReceiveThread.threadMutex); if (item == NULL) return; @@ -421,7 +294,6 @@ void CAHandleRequestResponseCallbacks() // get endpoint CAData_t* td = (CAData_t*) msg; - CARemoteEndpoint_t* rep = td->remoteEndpoint; if (rep == NULL) @@ -431,35 +303,66 @@ void CAHandleRequestResponseCallbacks() { if (gRequestHandler) { - gRequestHandler(rep, NULL); + gRequestHandler(rep, td->requestInfo); + } + + if(NULL != td->requestInfo->info.options) + { + OICFree(td->requestInfo->info.options); + } + + if(NULL != td->requestInfo->info.payload) + { + OICFree(td->requestInfo->info.payload); } + + if(NULL != td->requestInfo->info.token) + { + OICFree(td->requestInfo->info.token); + } + OICFree(td->requestInfo); } if (td->responseInfo != NULL) { if (gResponseHandler) { - gResponseHandler(rep, NULL); + gResponseHandler(rep, td->responseInfo); } + + if(NULL != td->responseInfo->info.options) + { + OICFree(td->responseInfo->info.options); + } + + if(NULL != td->responseInfo->info.payload) + { + OICFree(td->responseInfo->info.payload); + } + + if(NULL != td->responseInfo->info.token) + { + OICFree(td->responseInfo->info.token); + } + OICFree(td->responseInfo); } - u_queue_remove_element(gMessageQueue); + if(NULL != rep->resourceUri) + { + OICFree(rep->resourceUri); + } + OICFree(rep); } -int32_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"); if (object == NULL || request == NULL) { - return -1; + return CA_STATUS_FAILED; } - int32_t id = 0; - - // create action id - id = CAIncreaseActionId(); - CAData_t* data = (CAData_t*) OICMalloc(sizeof(CAData_t)); MEMORY_ALLOCK_CHECK(data); @@ -475,15 +378,15 @@ int32_t CADetachRequestMessage(const CARemoteEndpoint_t* object, const CARequest MEMORY_ALLOCK_CHECK(requestInfo); // save data - data->actionId = id; + data->type = SEND_TYPE_UNICAST; data->remoteEndpoint = remoteEndpoint; data->requestInfo = requestInfo; data->responseInfo = NULL; // add thread - CAAddSendData(data); + CAQueueingThreadAddData(&gSendThread, data, sizeof(CAData_t)); - return id; + return CA_STATUS_OK; // memory error label. memory_error_exit: @@ -497,23 +400,19 @@ int32_t CADetachRequestMessage(const CARemoteEndpoint_t* object, const CARequest OICFree(data); } - return -1; + return CA_MEMORY_ALLOC_FAILED; } -int32_t CADetachResponseMessage(const CARemoteEndpoint_t* object, const CAResponseInfo_t* response) +CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t* object, + const CAResponseInfo_t* response) { OIC_LOG_V(DEBUG, TAG, "CADetachResponseMessage"); if (object == NULL || response == NULL) { - return -1; + return CA_STATUS_FAILED; } - int32_t id = 0; - - // create action id - id = CAIncreaseActionId(); - CAData_t* data = (CAData_t*) OICMalloc(sizeof(CAData_t)); MEMORY_ALLOCK_CHECK(data); @@ -529,15 +428,15 @@ int32_t CADetachResponseMessage(const CARemoteEndpoint_t* object, const CARespon MEMORY_ALLOCK_CHECK(responseInfo); // save data - data->actionId = id; + data->type = SEND_TYPE_UNICAST; data->remoteEndpoint = remoteEndpoint; data->requestInfo = NULL; data->responseInfo = responseInfo; // add thread - CAAddSendData(data); + CAQueueingThreadAddData(&gSendThread, data, sizeof(CAData_t)); - return id; + return CA_STATUS_OK; // memory error label. memory_error_exit: @@ -551,21 +450,17 @@ int32_t CADetachResponseMessage(const CARemoteEndpoint_t* object, const CARespon OICFree(data); } - return -1; + return CA_MEMORY_ALLOC_FAILED; } -int32_t CADetachMessageResourceUri(const CAURI_t resourceUri) +CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAHeaderOption_t* options, + uint8_t numOptions) { if (resourceUri == NULL) { - return -1; + return CA_STATUS_FAILED; } - int32_t id = 0; - - // create action id - id = CAIncreaseActionId(); - CAData_t* data = (CAData_t*) OICMalloc(sizeof(CAData_t)); MEMORY_ALLOCK_CHECK(data); @@ -578,15 +473,32 @@ int32_t CADetachMessageResourceUri(const CAURI_t resourceUri) CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE); // save data - data->actionId = id; + data->type = SEND_TYPE_MULTICAST; data->remoteEndpoint = remoteEndpoint; data->requestInfo = NULL; data->responseInfo = NULL; + data->options = NULL; + data->numOptions = 0; + + if (options != NULL && numOptions > 0) + { + // copy data + CAHeaderOption_t* temp = (CAHeaderOption_t*) OICMalloc( + sizeof(CAHeaderOption_t) * numOptions); + + MEMORY_ALLOCK_CHECK(temp); + + memset(temp, 0, sizeof(CAHeaderOption_t) * numOptions); + memcpy(temp, options, sizeof(CAHeaderOption_t) * numOptions); + + data->options = temp; + data->numOptions = numOptions; + } // add thread - CAAddSendData(data); + CAQueueingThreadAddData(&gSendThread, data, sizeof(CAData_t)); - return id; + return CA_STATUS_OK; // memory error label. memory_error_exit: @@ -598,14 +510,7 @@ int32_t CADetachMessageResourceUri(const CAURI_t resourceUri) OICFree(data); } - return -1; -} - -void CASetMessageHandlerCallback(CAMessageHandlerCallback callback) -{ - OIC_LOG_V(DEBUG, TAG, "set message handler callback."); - - gHandlerCallback = callback; + return CA_MEMORY_ALLOC_FAILED; } void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler) @@ -618,8 +523,11 @@ void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallb CAResult_t CAInitializeMessageHandler() { + OIC_LOG(DEBUG, TAG, "CAInitializeMessageHandler - Entry"); CASetPacketReceivedCallback(CAReceivedPacketCallback); + CASetNetworkChangeCallback(CANetworkChangedCallback); + // create thread pool CAResult_t res; res = u_thread_pool_init(MAX_THREAD_POOL_SIZE, &gThreadPoolHandle); @@ -631,33 +539,33 @@ CAResult_t CAInitializeMessageHandler() } // send thread initialize - memset(&gSendThread, 0, sizeof(CAThread_t)); - - // mutex init - u_mutex_init(); - - // set send thread data - gSendThread.dataQueue = u_queue_create(); - gSendThread.threadMutex = u_mutex_new(); - gSendThread.threadCond = u_cond_new(); - gSendThread.isStop = FALSE; - gSendThread.threadTask = CASendThreadProcess; + CAQueueingThreadInitialize(&gSendThread, gThreadPoolHandle, CASendThreadProcess); // start send thread - res = u_thread_pool_add_task(gThreadPoolHandle, CAThreadBaseRoutine, &gSendThread); + res = CAQueueingThreadStart(&gSendThread); if (res != CA_STATUS_OK) { - OIC_LOG_V(DEBUG, TAG, "thread pool add task error."); + OIC_LOG_V(DEBUG, TAG, "thread start error(send thread)."); return res; } - // set receive queue - gMessageQueue = u_queue_create(); - gMessageQueueMutex = u_mutex_new(); + // receive thread initialize + CAQueueingThreadInitialize(&gReceiveThread, gThreadPoolHandle, CAReceiveThreadProcess); + + // start receive thread + // TODO + // currently not support. +// res = CAThreadStart(gReceiveThread); +// +// if (res != CA_STATUS_OK) +// { +// OIC_LOG_V(DEBUG, TAG, "thread start error(receive thread)."); +// return res; +// } // initialize interface adapters by controller - CAInitializeAdapters(); + CAInitializeAdapters(gThreadPoolHandle); return CA_STATUS_OK; } @@ -668,19 +576,18 @@ void CATerminateMessageHandler() CATerminateAdapters(); // stop thread - CAStopSendThread(); + // delete thread data + CAQueueingThreadStop(&gSendThread); + CAQueueingThreadDestroy(&gSendThread); + // stop thread // delete thread data - u_mutex_free(gSendThread.threadMutex); - u_cond_free(gSendThread.threadCond); - u_queue_delete(gSendThread.dataQueue); + CAQueueingThreadStop(&gReceiveThread); + CAQueueingThreadDestroy(&gReceiveThread); // destroy thread pool u_thread_pool_free(gThreadPoolHandle); OIC_LOG_V(DEBUG, TAG, "message handler terminate completed!"); - - u_queue_delete(gMessageQueue); - u_mutex_free(gMessageQueueMutex); } diff --git a/resource/csdk/connectivity/src/canetworkconfigurator.c b/resource/csdk/connectivity/src/canetworkconfigurator.c index 0efe118..d374ebc 100644 --- a/resource/csdk/connectivity/src/canetworkconfigurator.c +++ b/resource/csdk/connectivity/src/canetworkconfigurator.c @@ -77,7 +77,7 @@ CAResult_t CAAddNetworkType(uint32_t ConnectivityType) case CA_LE: -#ifdef LE_ADAPTER +#ifndef LE_ADAPTER OIC_LOG_V(DEBUG, TAG, "Add network type(LE) - Not Supported"); return CA_NOT_SUPPORTED; #endif /* LE_ADAPTER */ @@ -162,12 +162,20 @@ CAResult_t CARemoveNetworkType(uint32_t ConnectivityType) u_arraylist_t* CAGetSelectedNetworkList() { + OIC_LOG(DEBUG, TAG, "IN"); if (gSelectedNetworkList == NULL) { OIC_LOG_V(DEBUG, TAG, "Selected network not found"); return NULL; } - + OIC_LOG(DEBUG, TAG, "OUT"); return gSelectedNetworkList; } + +CAResult_t CAGetNetworkInformationInternal(CALocalConnectivity_t **info, uint32_t* size) +{ + OIC_LOG_V(DEBUG, TAG, "get network information."); + + return CAGetNetworkInfo(info, size); +} diff --git a/resource/csdk/connectivity/src/caprotocolmessage.c b/resource/csdk/connectivity/src/caprotocolmessage.c index fb5a3d5..deb988f 100644 --- a/resource/csdk/connectivity/src/caprotocolmessage.c +++ b/resource/csdk/connectivity/src/caprotocolmessage.c @@ -28,31 +28,31 @@ #define TAG PCF("CA") -#define CA_MAX_TOKEN_LEN 8 +#define CA_MAX_TOKEN_LEN (8) #define CA_FLAGS_BLOCK 0x01 -#define CA_URI_MAX_SIZE 256 -#define CA_BUFSIZE 40 +#define CA_BUFSIZE 128 +#define CA_COAP_MESSAGE_CON 0 -uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t* outReqInfo) +uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t* outReqInfo, char* outUri) { OIC_LOG(DEBUG, TAG, "get request info from PDU"); if (NULL == pdu) return 0; uint32_t code = CA_NOT_FOUND; - CAGetRequestPDUInfo(pdu, &code, &(outReqInfo->info)); + CAGetRequestPDUInfo(pdu, &code, &(outReqInfo->info), outUri); outReqInfo->method = code; return 1; } -uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t* outResInfo) +uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t* outResInfo, char* outUri) { OIC_LOG(DEBUG, TAG, "get response info from PDU"); if (NULL == pdu) return 0; uint32_t code = CA_NOT_FOUND; - CAGetRequestPDUInfo(pdu, &code, &(outResInfo->info)); + CAGetRequestPDUInfo(pdu, &code, &(outResInfo->info), outUri); outResInfo->result = code; return 1; @@ -72,12 +72,17 @@ coap_pdu_t* CAGeneratePdu(const char* uri, const uint32_t code, const CAInfo_t i return NULL; length = strlen(uri); + if (CA_MAX_URI_LENGTH < length) + { + OIC_LOG(DEBUG, TAG, "check URI length.."); + return NULL; + } + coapUri = (char*) OICMalloc(length + coapHeaderLength + 1); memset(coapUri, 0, length + coapHeaderLength + 1); if (NULL != coapUri) { - memcpy(coapUri, "coap://[::]/", coapHeaderLength); memcpy(coapUri + coapHeaderLength, uri, length); @@ -85,20 +90,17 @@ coap_pdu_t* CAGeneratePdu(const char* uri, const uint32_t code, const CAInfo_t i CAParseURI(coapUri, &optlist); // parsing options in HeadOption - if (NULL != &info) - { - CAParseHeadOption(code, info, &optlist); - } + CAParseHeadOption(code, info, &optlist); OICFree(coapUri); } - if (NULL != info.payload) + if (NULL != info.payload) // payload is include in request / response { if (!(pdu = CACreatePDUforRequestWithPayload((code_t) code, optlist, info.payload))) return NULL; } - else + else // payload is not include in request / response { if (!(pdu = CACreatePDUforRequest((code_t) code, optlist))) return NULL; @@ -129,42 +131,46 @@ coap_pdu_t* CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *opt str the_token = { 0, _token_data }; + uint32_t CAFlags = 0; + coap_block_t CABlock = + { .num = 0, .m = 0, .szx = 6 }; + if (!(pdu = coap_new_pdu())) return NULL; /* initialize message id */ unsigned short message_id; - prng((unsigned char *)&message_id, sizeof(unsigned short)); + prng((unsigned char * )&message_id, sizeof(unsigned short)); - pdu->hdr->type = msgtype; + pdu->hdr->type = CA_COAP_MESSAGE_CON; pdu->hdr->id = htons(++message_id); pdu->hdr->code = code; pdu->hdr->token_length = the_token.length; if (!coap_add_token(pdu, the_token.length, the_token.s)) { - OIC_LOG(DEBUG, TAG,"cannot add token to request"); + OIC_LOG(DEBUG, TAG, "cannot add token to request"); } for (opt = options; opt; opt = opt->next) { - coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *)opt->data), - COAP_OPTION_LENGTH(*(coap_option *)opt->data), - COAP_OPTION_DATA(*(coap_option *)opt->data)); + coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data), + COAP_OPTION_LENGTH(*(coap_option * )opt->data), + COAP_OPTION_DATA(*(coap_option * )opt->data)); } if (NULL != payload) { uint32_t len = strlen(payload); - if ((flags & CA_FLAGS_BLOCK) == 0) + if ((CAFlags & CA_FLAGS_BLOCK) == 0) { OIC_LOG_V(DEBUG, TAG, "coap_add_data, payload: %s", payload); - coap_add_data(pdu, len, payload); + coap_add_data(pdu, len, (const unsigned char *) payload); } else { OIC_LOG_V(DEBUG, TAG, "coap_add_block, payload: %s", payload); - coap_add_block(pdu, len, payload, block.num, block.szx); + coap_add_block(pdu, len, (const unsigned char *) payload, CABlock.num, CABlock.szx); } } return pdu; @@ -185,9 +191,9 @@ coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options) /* initialize message id */ unsigned short message_id; - prng((unsigned char *)&message_id, sizeof(unsigned short)); + prng((unsigned char * )&message_id, sizeof(unsigned short)); - pdu->hdr->type = msgtype; + pdu->hdr->type = CA_COAP_MESSAGE_CON; pdu->hdr->id = htons(++message_id); pdu->hdr->code = code; @@ -199,9 +205,9 @@ coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options) for (opt = options; opt; opt = opt->next) { - coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *)opt->data), - COAP_OPTION_LENGTH(*(coap_option *)opt->data), - COAP_OPTION_DATA(*(coap_option *)opt->data)); + coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data), + COAP_OPTION_LENGTH(*(coap_option * )opt->data), + COAP_OPTION_DATA(*(coap_option * )opt->data)); } return pdu; @@ -269,9 +275,21 @@ void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **o uint32_t i; for (i = 0; i < info.numOptions; i++) { - coap_insert(optlist, - CACreateNewOptionNode(info.options->optionID, info.options->optionLength, - info.options->optionData), CAOrderOpts); + uint32_t id = info.options[i].optionID; + if (COAP_OPTION_URI_PATH == id || COAP_OPTION_URI_QUERY == id) + { + OIC_LOG_V(DEBUG, TAG, "it is not Header Option : %d", id); + } + else + { + OIC_LOG_V(DEBUG, TAG, "Head Option ID: %d", info.options[i].optionID); + OIC_LOG_V(DEBUG, TAG, "Head Option data: %s", info.options[i].optionData); + OIC_LOG_V(DEBUG, TAG, "Head Option length: %d", info.options[i].optionLength); + + coap_insert(optlist, + CACreateNewOptionNode(info.options[i].optionID, info.options[i].optionLength, + info.options[i].optionData), CAOrderOpts); + } } } @@ -295,7 +313,7 @@ coap_list_t* CACreateNewOptionNode(const uint16_t key, const uint32_t length, co return node; error: perror("new_option_node: malloc"); - coap_free( option); + coap_free(option); return NULL; } @@ -304,100 +322,180 @@ int32_t CAOrderOpts(void *a, void *b) if (!a || !b) return a < b ? -1 : 1; - if (COAP_OPTION_KEY(*(coap_option *)a) < COAP_OPTION_KEY(*(coap_option *)b)) + if (COAP_OPTION_KEY(*(coap_option *)a) < COAP_OPTION_KEY(*(coap_option * )b)) return -1; - return COAP_OPTION_KEY(*(coap_option *)a) == COAP_OPTION_KEY(*(coap_option *)b); + return COAP_OPTION_KEY(*(coap_option *)a) == COAP_OPTION_KEY(*(coap_option * )b); +} + +uint32_t getOptionCount(coap_opt_iterator_t opt_iter) +{ + uint32_t count = 0; + coap_opt_t *option; + + while ((option = coap_option_next(&opt_iter))) + { + count++; + } + + return count; } -void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t* outCode, CAInfo_t* outInfo) +void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t* outCode, CAInfo_t* outInfo, char* outUri) { unsigned char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */ uint32_t encode = 0; coap_opt_iterator_t opt_iter; coap_opt_t *option; - char optionResult[CA_URI_MAX_SIZE] = + char optionResult[CA_MAX_URI_LENGTH] = { 0, }; - uint32_t count = 0; + uint32_t count = 0, idx = 0; + uint32_t optionLength = 0; uint32_t isfirstsetflag = 0; - /* show options, if any */ coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL); memset(optionResult, 0, sizeof(optionResult)); + + count = getOptionCount(opt_iter); + + // set code + (*outCode) = (uint32_t) pdu->hdr->code; + + // init HeaderOption list + memset(outInfo, 0, sizeof(CAInfo_t)); + outInfo->numOptions = count; + outInfo->options = (CAHeaderOption_t*) OICMalloc(sizeof(CAHeaderOption_t) * count); + memset(outInfo->options, 0, sizeof(CAHeaderOption_t) * count); + while ((option = coap_option_next(&opt_iter))) { if (print_readable(COAP_OPT_VALUE(option), COAP_OPT_LENGTH(option), buf, sizeof(buf), encode)) { - if (opt_iter.type == COAP_OPTION_URI_PATH || opt_iter.type == COAP_OPTION_URI_QUERY) + if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type) { if (0 == isfirstsetflag) { isfirstsetflag = 1; - memcpy(optionResult + count, buf, strlen(buf)); - count += strlen(buf); + memcpy(optionResult + optionLength, buf, strlen((const char *) buf)); + optionLength += strlen((const char *) buf); } else { - if (opt_iter.type == COAP_OPTION_URI_PATH) + if (COAP_OPTION_URI_PATH == opt_iter.type) { - memcpy(optionResult + count, "/", 1); - count++; + memcpy(optionResult + optionLength, "/", 1); + optionLength++; } - else if (opt_iter.type == COAP_OPTION_URI_QUERY) + else if (COAP_OPTION_URI_QUERY == opt_iter.type) { - memcpy(optionResult + count, "?", 1); - count++; + memcpy(optionResult + optionLength, "?", 1); + optionLength++; } - memcpy(optionResult + count, buf, strlen(buf)); - count += strlen(buf); + memcpy(optionResult + optionLength, buf, strlen((const char *) buf)); + optionLength += strlen((const char *) buf); + } + } + + if (idx < count) + { + uint32_t length = (uint32_t) strlen((const char *) buf); + + 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; + memcpy(outInfo->options[idx].optionData, buf, length); + idx++; } } } } - OIC_LOG(DEBUG, TAG, "set CAInfo_t after parsing"); - - // set pdu info - (*outCode) = (uint32_t) pdu->hdr->code; - memset(outInfo, 0, sizeof(CAInfo_t)); - - outInfo->options = (CAHeaderOption_t*) OICMalloc(sizeof(CAHeaderOption_t)); - memset(outInfo->options, 0, sizeof(CAHeaderOption_t)); - - outInfo->options->optionID = opt_iter.type; - outInfo->options->optionLength = count; - memcpy(outInfo->options->optionData, optionResult, CA_MAX_HEADER_OPTION_DATA_LENGTH); - + // set token data if (pdu->hdr->token_length > 0) { outInfo->token = (char*) OICMalloc(pdu->hdr->token_length); memcpy(outInfo->token, pdu->hdr->token, pdu->hdr->token_length); } + // set payload data if (NULL != pdu->data) { - outInfo->payload = (char*) OICMalloc(strlen(pdu->data) + 1); - memcpy(outInfo->payload, pdu->data, strlen(pdu->data) + 1); + outInfo->payload = (char*) OICMalloc(strlen((const char *) pdu->data) + 1); + memcpy(outInfo->payload, pdu->data, strlen((const char *) pdu->data) + 1); } + + // set uri info + memcpy(outUri, optionResult, strlen(optionResult)); } CAResult_t CAGenerateTokenInternal(CAToken_t* token) { - OIC_LOG(DEBUG, TAG, "generate the token"); + if (token == NULL) + { + return CA_STATUS_FAILED; + } + + // memory allocation + char* temp = (char*) OICMalloc(sizeof(char) * (CA_MAX_TOKEN_LEN + 1)); + + if (temp == NULL) + { + return CA_MEMORY_ALLOC_FAILED; + } + memset(temp, 0, sizeof(char) * (CA_MAX_TOKEN_LEN + 1)); + + // set random byte + uint32_t index; + for (index = 0; index < CA_MAX_TOKEN_LEN; index++) + { + temp[index] = rand() & 0xFF; + } + + // save token + *token = temp; + + OIC_LOG_V(DEBUG, TAG, "generate the token(%s)!!", *token); return CA_STATUS_OK; } void CADestroyTokenInternal(CAToken_t token) { - OIC_LOG(DEBUG, TAG, "destroy the token!!"); - if (token != NULL) { + OIC_LOG_V(DEBUG, TAG, "destroy the token(%s)!!", token); + OICFree(token); } } + +void CADeinitialize(CAInfo_t* info) +{ + OIC_LOG(DEBUG, TAG, "CADeinitialize!!"); + + if (NULL != info) + { + if (NULL != info->options) + { + OIC_LOG(DEBUG, TAG, "free options in CAInfo"); + OICFree(info->options); + } + + if (NULL != info->token) + { + OIC_LOG(DEBUG, TAG, "free token in CAInfo"); + OICFree(info->token); + } + + if (NULL != info->payload) + { + OIC_LOG(DEBUG, TAG, "free payload in CAInfo"); + OICFree(info->payload); + } + } +} diff --git a/resource/csdk/connectivity/src/caqueueingthread.c b/resource/csdk/connectivity/src/caqueueingthread.c new file mode 100644 index 0000000..0bd08eb --- /dev/null +++ b/resource/csdk/connectivity/src/caqueueingthread.c @@ -0,0 +1,223 @@ +/****************************************************************** + * + * 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 "caqueueingthread.h" +#include "oic_malloc.h" +#include "logger.h" + +#define TAG PCF("CA") + +static void CAQueueingThreadBaseRoutine(void* treadValue) +{ + OIC_LOG_V(DEBUG, TAG, "message handler main thread start.."); + + CAQueueingThread_t* thread = (CAQueueingThread_t*) treadValue; + + if (thread == NULL) + { + OIC_LOG_V(DEBUG, TAG, "thread data passing error!!"); + + return; + } + + while (!thread->isStop) + { + // mutex lock + u_mutex_lock(thread->threadMutex); + + // if queue is empty, thread will wait + if (u_queue_get_size(thread->dataQueue) <= 0) + { + OIC_LOG_V(DEBUG, TAG, "wait.."); + // wait + u_cond_wait(thread->threadCond, thread->threadMutex); + + OIC_LOG_V(DEBUG, TAG, "wake up.."); + } + + // mutex unlock + u_mutex_unlock(thread->threadMutex); + + // check stop flag + if (thread->isStop) + continue; + + // get data + u_queue_message_t* message = u_queue_get_element(thread->dataQueue); + + void* data = message->msg; + + // process data + thread->threadTask(data); + + // free + } + + OIC_LOG_V(DEBUG, TAG, "message handler main thread end.."); +} + +CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t* thread, u_thread_pool_t handle, + CAThreadTask task) +{ + if (thread == 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(thread, 0, sizeof(CAQueueingThread_t)); + + // mutex init + u_mutex_init(); + + // set send thread data + thread->threadPool = handle; + thread->dataQueue = u_queue_create(); + thread->threadMutex = u_mutex_new(); + thread->threadCond = u_cond_new(); + thread->isStop = CA_FALSE; + thread->threadTask = task; + + return CA_STATUS_OK; +} + +CAResult_t CAQueueingThreadStart(CAQueueingThread_t* thread) +{ + if (thread == NULL) + { + OIC_LOG_V(DEBUG, TAG, "thread instance is empty.."); + return CA_STATUS_FAILED; + } + + if (thread->threadPool == NULL) + { + OIC_LOG_V(DEBUG, TAG, "thread pool handle is empty.."); + return CA_STATUS_FAILED; + } + + 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)."); + return res; + } + + return res; +} + +CAResult_t CAQueueingThreadAddData(CAQueueingThread_t* thread, void* data, uint32_t size) +{ + if (thread == NULL) + { + OIC_LOG_V(DEBUG, TAG, "thread instance is empty.."); + return CA_STATUS_FAILED; + } + + if (data == NULL || size == 0) + { + OIC_LOG_V(DEBUG, TAG, "data is empty.."); + + return CA_STATUS_FAILED; + } + + // create thread data + u_queue_message_t* message = (u_queue_message_t*) OICMalloc(sizeof(u_queue_message_t)); + + if (message == NULL) + { + OIC_LOG_V(DEBUG, TAG, "memory error!!"); + return CA_MEMORY_ALLOC_FAILED; + } + memset(message, 0, sizeof(u_queue_message_t)); + + message->msg = data; + message->size = sizeof(size); + + // mutex lock + u_mutex_lock(thread->threadMutex); + + // add thread data into list + u_queue_add_element(thread->dataQueue, message); + + // notity the thread + u_cond_signal(thread->threadCond); + + // mutex unlock + u_mutex_unlock(thread->threadMutex); + + return CA_STATUS_OK; +} + +CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t* thread) +{ + if (thread == NULL) + { + OIC_LOG_V(DEBUG, TAG, "thread instance is empty.."); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, TAG, "thread destroy.."); + + u_mutex_free(thread->threadMutex); + u_cond_free(thread->threadCond); + u_queue_delete(thread->dataQueue); + + return CA_STATUS_OK; +} + +CAResult_t CAQueueingThreadStop(CAQueueingThread_t* thread) +{ + if (thread == NULL) + { + OIC_LOG_V(DEBUG, TAG, "thread instance is empty.."); + return CA_STATUS_FAILED; + } + + OIC_LOG_V(DEBUG, TAG, "thread stop request!!"); + + // mutex lock + u_mutex_lock(thread->threadMutex); + + // set stop flag + thread->isStop = CA_TRUE; + + // notity the thread + u_cond_signal(thread->threadCond); + + // mutex unlock + u_mutex_unlock(thread->threadMutex); + + return CA_STATUS_OK; +} + diff --git a/resource/csdk/connectivity/src/caremotehandler.c b/resource/csdk/connectivity/src/caremotehandler.c index f193168..a79d43e 100644 --- a/resource/csdk/connectivity/src/caremotehandler.c +++ b/resource/csdk/connectivity/src/caremotehandler.c @@ -84,7 +84,6 @@ static int32_t getCAAddress(const char* pAddress, CAAddress_t* outAddress) int32_t isIp = 0; int32_t ipLen = 0; - int32_t port = 0; int i = 0; for (i = 0; i < len; i++) @@ -109,7 +108,7 @@ static int32_t getCAAddress(const char* pAddress, CAAddress_t* outAddress) if (ipLen > 0) outAddress->IP.port = atoi(pAddress + ipLen + 1); - OIC_LOG_V(DEBUG, TAG, "ip: %s,port: %d", outAddress->IP.ipAddress, outAddress->IP.port); + OIC_LOG_V(DEBUG, TAG, "ip: %s, port: %d", outAddress->IP.ipAddress, outAddress->IP.port); } else { diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetadapter.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetadapter.c index e73c2fd..7e90a34 100644 --- a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetadapter.c +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetadapter.c @@ -23,18 +23,51 @@ #include #include "caethernetadapter.h" +//#include "config.h" +//#include "coap.h" +#include "caethernetcore.h" #include "logger.h" +#include "oic_malloc.h" #define TAG PCF("CA") +// received packet callback static CANetworkPacketReceivedCallback gEthernetReceivedCallback = NULL; +static u_thread_pool_t gThreadPoolHandle = NULL; + +static void CAEthernetPacketReceiveCallback(const char* address, const char* data) +{ + OIC_LOG_V(DEBUG, TAG, "CAethernetPacketReceiveCallback, from: %s, data: %s", address, data); + + // call the callback + if (gEthernetReceivedCallback != NULL) + { + CARemoteEndpoint_t* endpoint = NULL; + endpoint = (CARemoteEndpoint_t*) OICMalloc(sizeof(CARemoteEndpoint_t)); + + // set address + memset((void*) endpoint->addressInfo.IP.ipAddress, 0, CA_IPADDR_SIZE); + if (CA_IPADDR_SIZE > strlen(address)) + { + strcpy((char*) endpoint->addressInfo.IP.ipAddress, address); + } + free(address); + + // set connectivity type + endpoint->connectivityType = CA_ETHERNET; + + gEthernetReceivedCallback(endpoint, (void *) data, strlen(data)); + } +} CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback) + CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle) { - OIC_LOG_V(DEBUG, TAG, "CAInitializeEthernet"); + OIC_LOG(DEBUG, TAG, "IntializeEthernet"); gEthernetReceivedCallback = reqRespCallback; + gThreadPoolHandle = handle; // register handlers CAConnectivityHandler_t handler; @@ -45,7 +78,7 @@ CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback, handler.startDiscoverServer = CAStartEthernetDiscoveryServer; handler.sendData = CASendEthernetUnicastData; handler.sendDataToAll = CASendEthernetMulticastData; - handler.startNotifyServer = CAStartEthernetNotifyServer; + handler.startNotifyServer = CAStartEthernetNotifyRecvServers; handler.sendNotification = CASendEthernetNotification; handler.GetnetInfo = CAGetEthernetInterfaceInformation; handler.readData = CAReadEthernetData; @@ -54,47 +87,89 @@ CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback, registerCallback(handler, CA_ETHERNET); + CAEthernetSetCallback(CAEthernetPacketReceiveCallback); + return CA_STATUS_OK; } +void CATerminateEthernet() +{ + OIC_LOG(DEBUG, TAG, "TerminateEthernet"); + + CAEthernetTerminate(); +} + CAResult_t CAStartEthernet() { - OIC_LOG_V(DEBUG, TAG, "CAStartEthernet"); + OIC_LOG(DEBUG, TAG, "CAStartEthernet"); + //CAEthernetInitialize(); + CAEthernetInitialize(gThreadPoolHandle); + + OIC_LOG(DEBUG, TAG, "CAEthernetStartUnicastServer"); + int32_t res = CAEthernetStartUnicastServer(); + + if (res < 0) + return CA_STATUS_FAILED; + + return CA_STATUS_OK; +} + +CAResult_t CAStopEthernet() +{ + OIC_LOG(DEBUG, TAG, "CAStopEthernet"); + + // ToDo: return CA_STATUS_OK; } CAResult_t CAStartEthernetListeningServer() { - OIC_LOG_V(DEBUG, TAG, "CAStartEthernetListeningServer"); + OIC_LOG(DEBUG, TAG, "StartEthernetListeningServer"); + + int32_t res = CAEthernetStartMulticastServer(); + + if (res < 0) + return CA_STATUS_FAILED; return CA_STATUS_OK; } CAResult_t CAStartEthernetDiscoveryServer() { - OIC_LOG_V(DEBUG, TAG, "CAStartEthernetDiscoveryServer"); + OIC_LOG(DEBUG, TAG, "StartEthernetDiscoveryServer"); + + int32_t res = CAEthernetStartMulticastServer(); + + if (res < 0) + return CA_STATUS_FAILED; return CA_STATUS_OK; } uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen) { - OIC_LOG_V(DEBUG, TAG, "CASendEthernetUnicastData"); + OIC_LOG(DEBUG, TAG, "SendEthernetUnicastData"); + + CAEthernetSendUnicastMessage(endpoint->addressInfo.IP.ipAddress, data, dataLen); return 0; } uint32_t CASendEthernetMulticastData(void* data, uint32_t dataLen) { - OIC_LOG_V(DEBUG, TAG, "CASendEthernetMulticastData"); + OIC_LOG(DEBUG, TAG, "CASendEthernetMulticastData"); + + CAEthernetSendMulticastMessage("0.0.0.0", (char*) data); return 0; } -CAResult_t CAStartEthernetNotifyServer() +CAResult_t CAStartEthernetNotifyRecvServers() { - OIC_LOG_V(DEBUG, TAG, "CAStartEthernetNotifyServer"); + OIC_LOG(DEBUG, TAG, "StartEthernetNotifyRecvServers"); + + // ToDo: return CA_STATUS_OK; } @@ -102,33 +177,28 @@ CAResult_t CAStartEthernetNotifyServer() uint32_t CASendEthernetNotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen) { - OIC_LOG_V(DEBUG, TAG, "CASendEthernetNotification"); + OIC_LOG(DEBUG, TAG, "SendEthernetNotification"); + + // ToDo: return 0; } -CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size) +CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size) { - OIC_LOG_V(DEBUG, TAG, "CAGetEthernetInterfaceInformation"); + OIC_LOG(DEBUG, TAG, "GetEthernetInterfaceInformation"); + + // ToDo: return CA_STATUS_OK; } CAResult_t CAReadEthernetData() { - OIC_LOG_V(DEBUG, TAG, "Read Ethernet Data"); + OIC_LOG(DEBUG, TAG, "Read Ethernet Data"); - return CA_STATUS_OK; -} - -CAResult_t CAStopEthernet() -{ - OIC_LOG_V(DEBUG, TAG, "CAStopEthernet"); + // ToDo: return CA_STATUS_OK; } -void CATerminateEthernet() -{ - OIC_LOG_V(DEBUG, TAG, "CATerminateEthernet"); -} diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetcore.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetcore.c new file mode 100644 index 0000000..394674f --- /dev/null +++ b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetcore.c @@ -0,0 +1,622 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "caethernetcore.h" +#include "logger.h" +#include "uthreadpool.h" /* for thread pool */ +#include "umutex.h" +#include "caqueueingthread.h" +#include "oic_malloc.h" + +#define TAG PCF("CA") + +#define CA_MAX_BUFFER_SIZE 512 // Max length of buffer +#define CA_UNICAST_PORT 5383 // The port on which to listen for incoming data +#define CA_MULTICAST_ADDR "224.0.1.187" +#define CA_MULTICAST_PORT 5683 +typedef enum +{ + CA_UNICAST = 1, CA_MULTICAST +} CATransmissionType_t; + +typedef struct +{ + CATransmissionType_t transmissionType; // 0: none, 1: unicast, 2: multicast + char* address; + int port; + void* data; +} CAThreadData_t; + +typedef struct +{ + u_mutex threadMutex; + u_cond threadCond; + CABool_t isStop; + int32_t status; // 0: stopped, 1: running +} CATask_t; + +int32_t unicast_receive_socket; +struct sockaddr_in multicast_send_interface_addr; +int32_t multicast_receive_socket; +struct sockaddr_in multicast_receive_interface_addr; + +static CAPacketReceiveCallback gPacketReceiveCallback = NULL; + +static u_thread_pool_t gThreadPoolHandle = NULL; + +// message handler main thread +static CAQueueingThread_t gSendThread; +static CAQueueingThread_t gReceiveThread; + +CATask_t unicastListenTask; +CATask_t multicastListenTask; + +static void CAEthernetSendProcess(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CAEthernetSendThreadProcess"); + + CAThreadData_t* data = (CAThreadData_t*) threadData; + if (data == NULL) + { + OIC_LOG(DEBUG, TAG, "thread data is error!"); + return; + } + + if (data->transmissionType == CA_UNICAST) + { + // unicast + CAEthernetSendUnicastMessageImpl(data->address, (char*) (data->data)); + } + else if (data->transmissionType == CA_MULTICAST) + { + // multicast + CAEthernetSendMulticastMessageImpl((char*) (data->data)); + } +} + +static void CAEthernetReceiveProcess(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CAEthernetReceiveProcess"); + + CAThreadData_t* data = (CAThreadData_t*) threadData; + if (data == NULL) + { + OIC_LOG(DEBUG, TAG, "thread data is error!"); + return; + } + + if (gPacketReceiveCallback != NULL) + { + gPacketReceiveCallback(data->address, (char*) (data->data)); + } +} + +static void CAUnicastListenThread(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CAUnicastListenThread"); + + char buf[CA_MAX_BUFFER_SIZE]; + int32_t recv_len; + + struct sockaddr_in si_other; + int32_t slen = sizeof(si_other); + + while (!unicastListenTask.isStop) + { + OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, Waiting for data..."); + fflush(stdout); + + memset(buf, 0, sizeof(char) * CA_MAX_BUFFER_SIZE); + + // try to receive some data, this is a blocking call + if ((recv_len = recvfrom(unicast_receive_socket, buf, CA_MAX_BUFFER_SIZE, 0, + (struct sockaddr *) &si_other, (socklen_t *) &slen)) == -1) + { + OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, recv_len() error"); + continue; + } + + // print details of the client/peer and the data received + OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Received packet from %s:%d", + inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port)); + OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Data: %s", buf); + + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = 1; // unicast + + char* _address = inet_ntoa(si_other.sin_addr); + int len = strlen(_address); + td->address = (char*) OICMalloc(sizeof(char) * (len + 1)); + memset(td->address, 0, len + 1); + memcpy(td->address, _address, len); + td->port = ntohs(si_other.sin_port); + + td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE); + memset(td->data, 0, CA_MAX_BUFFER_SIZE); + memcpy(td->data, buf, sizeof(buf)); + + CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t)); + } + + OIC_LOG(DEBUG, TAG, "end of CAUnicastListenThread"); +} + +static void CAMulticastListenThread(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CAMulticastListenThread"); + + char msgbuf[CA_MAX_BUFFER_SIZE]; + + struct sockaddr_in client; + int32_t addrlen = sizeof(client); + + OIC_LOG(DEBUG, TAG, "CAMulticastListenThread, waiting for input..."); + + while (!multicastListenTask.isStop) + { + int32_t recv_bytes = recvfrom(multicast_receive_socket, msgbuf, CA_MAX_BUFFER_SIZE, 0, + (struct sockaddr *) &client, (socklen_t *) &addrlen); + if (recv_bytes < 0) + { + if (errno != EAGAIN) + { + OIC_LOG(DEBUG, TAG, "CAMulticastListenThread, error recvfrom"); + + return; + } + + continue; + } + + msgbuf[recv_bytes] = 0; + + OIC_LOG_V(DEBUG, TAG, "Received msg: %s, size: %d", msgbuf, recv_bytes); + + char* sender = inet_ntoa(client.sin_addr); + char local[INET_ADDRSTRLEN]; + CAEthernetGetLocalAddress(local); + if (strcmp(sender, local) == 0) + { + OIC_LOG_V(DEBUG, TAG, "skip the local request (via multicast)"); + continue; + } + else + { + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = 2; // multicast + + char* _address = inet_ntoa(client.sin_addr); + int len = strlen(_address); + td->address = (char*) OICMalloc(sizeof(char) * (len + 1)); + memset(td->address, 0, len + 1); + memcpy(td->address, _address, len); + td->port = ntohs(client.sin_port); + + td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE); + memset(td->data, 0, CA_MAX_BUFFER_SIZE); + memcpy(td->data, msgbuf, sizeof(msgbuf)); + + CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t)); + } + + } + + OIC_LOG(DEBUG, TAG, "end of CAMulticastListenThread"); +} + +void CAEthernetInitialize(u_thread_pool_t handle) +{ + OIC_LOG(DEBUG, TAG, "CAEthernetInitialize"); + + gThreadPoolHandle = handle; + + // unicast/multicast send queue + CAQueueingThreadInitialize(&gSendThread, gThreadPoolHandle, CAEthernetSendProcess); + + // start send thread + CAResult_t res = CAQueueingThreadStart(&gSendThread); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "thread start is error (send thread)"); + // return res; + return; + } + + // unicast/multicast receive queue + CAQueueingThreadInitialize(&gReceiveThread, gThreadPoolHandle, CAEthernetReceiveProcess); + + // start send thread + res = CAQueueingThreadStart(&gReceiveThread); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "thread start is error (receive thread)"); + // return res; + return; + } + + unicastListenTask.threadMutex = u_mutex_new(); + unicastListenTask.threadCond = u_cond_new(); + unicastListenTask.isStop = CA_FALSE; + unicastListenTask.status = 0; // stopped + + multicastListenTask.threadMutex = u_mutex_new(); + multicastListenTask.threadCond = u_cond_new(); + multicastListenTask.isStop = CA_FALSE; + multicastListenTask.status = 0; // stopped + + // [UDP Server] + struct sockaddr_in si_me; + + // create a UDP socket + if ((unicast_receive_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + { + OIC_LOG_V(DEBUG, TAG, "CAEthernetInit, creating socket failed"); + + return; + } + + OIC_LOG_V(DEBUG, TAG, "CAEthernetInit, socket created"); + + // [multicast sender] + uint32_t multiTTL = 1; + + // zero out the structure + memset((char *) &si_me, 0, sizeof(si_me)); + + si_me.sin_family = AF_INET; + si_me.sin_port = htons(CA_UNICAST_PORT); + si_me.sin_addr.s_addr = htonl(INADDR_ANY); + + int32_t ret_val = setsockopt(unicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL, + sizeof(multiTTL)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to set REUSEADDR"); + } + + // bind socket to port + if (bind(unicast_receive_socket, (struct sockaddr*) &si_me, sizeof(si_me)) == -1) + { + OIC_LOG(DEBUG, TAG, "CAEthernetInit, binding socket failed"); + close(unicast_receive_socket); + return; + } + + OIC_LOG(DEBUG, TAG, "CAEthernetInit, socket binded"); + + memset(&multicast_send_interface_addr, 0, sizeof(multicast_send_interface_addr)); + multicast_send_interface_addr.sin_family = AF_INET; + multicast_send_interface_addr.sin_addr.s_addr = inet_addr(CA_MULTICAST_ADDR); + multicast_send_interface_addr.sin_port = htons(CA_MULTICAST_PORT); + + // [multicast receiver] + // 1. Create a typical UDP socket and set Non-blocking for reading + multicast_receive_socket = socket(AF_INET, SOCK_DGRAM, 0); + if (multicast_receive_socket < 0) + { + OIC_LOG(DEBUG, TAG, "CAEthernetInit, Socket error"); + close(unicast_receive_socket); + return; + } + + // 2. Allow multiple sockets to use the same port number + ret_val = setsockopt(multicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL, + sizeof(multiTTL)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to set REUSEADDR"); + } + + // 3. Set up the interface + memset(&multicast_receive_interface_addr, 0, sizeof(multicast_receive_interface_addr)); + multicast_receive_interface_addr.sin_family = AF_INET; + multicast_receive_interface_addr.sin_addr.s_addr = htonl(INADDR_ANY); + multicast_receive_interface_addr.sin_port = htons(CA_MULTICAST_PORT); + + // 4. Bind to the interface + ret_val = bind(multicast_receive_socket, (struct sockaddr *) &multicast_receive_interface_addr, + sizeof(multicast_receive_interface_addr)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to bind socket"); + + return; + } + + // 5. Join the multicast group + struct ip_mreq mreq; + memset(&mreq, 0, sizeof(mreq)); + mreq.imr_multiaddr.s_addr = inet_addr(CA_MULTICAST_ADDR); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + ret_val = setsockopt(multicast_receive_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, + sizeof(mreq)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to join multicast group"); + + return; + } +} + +void CAEthernetTerminate() +{ + OIC_LOG(DEBUG, TAG, "CAEthernetTerminate"); + + close(unicast_receive_socket); + close(multicast_receive_socket); + + shutdown(unicast_receive_socket, 2); + shutdown(multicast_receive_socket, 2); + + CAEthernetStopUnicastServer(0); + + CAEthernetStopMulticastServer(0); + + // stop thread + CAQueueingThreadStop(&gSendThread); + // delete thread data + CAQueueingThreadDestroy(&gSendThread); + + // stop thread + CAQueueingThreadStop(&gReceiveThread); + // delete thread data + CAQueueingThreadDestroy(&gReceiveThread); + + u_mutex_free(unicastListenTask.threadMutex); + u_cond_free(unicastListenTask.threadCond); + + u_mutex_free(multicastListenTask.threadMutex); + u_cond_free(multicastListenTask.threadCond); + +} + +int32_t CAEthernetSendUnicastMessage(const char* address, const char* data, int lengh) +{ + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + if (td == NULL) + { + OICFree(data); + return 0; + } + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = CA_UNICAST; // unicast type + int len = strlen(address); + td->address = (char*) OICMalloc(sizeof(char) * (len + 1)); + if (td->address != NULL) + { + memset(td->address, 0, len + 1); + memcpy(td->address, address, len); + } + else + { + OIC_LOG_V(DEBUG, TAG, "Memory Full"); + OICFree(td); + OICFree(data); + return 0; + } + td->data = data; + + CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t)); + + return 0; +} + +int32_t CAEthernetSendMulticastMessage(const char* m_address, const char* data) +{ + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + if (td == NULL) + { + OIC_LOG_V(DEBUG, TAG, "Memory Full"); + OICFree(data); + return 0; + } + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = CA_MULTICAST; // unicast + td->address = NULL; + td->data = data; + + CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t)); + + return 0; +} + +int32_t CAEthernetStartUnicastServer() +{ + OIC_LOG_V(DEBUG, TAG, "CAEthernetStartUnicastServer(%s, %d)", "0.0.0.0", CA_UNICAST_PORT); + + // check the server status + if (unicastListenTask.status == 1) + { + OIC_LOG(DEBUG, TAG, "CAEthernetStartUnicastServer, already running"); + + return 0; + } + + // unicast listen thread + CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAUnicastListenThread, NULL); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (unicast listen thread)"); + return res; + } + + unicastListenTask.status = 1; // running + + return 0; +} + +int32_t CAEthernetStartMulticastServer() +{ + OIC_LOG_V(DEBUG, TAG, "CAEthernetStartMulticastServer(%s, %d)", "0.0.0.0", CA_MULTICAST_PORT); + + // check the server status + if (multicastListenTask.status == 1) + { + OIC_LOG(DEBUG, TAG, "CAEthernetStartMulticastServer, already running"); + + return 0; + } + + // multicast listen thread + CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAMulticastListenThread, NULL); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (multicast listen thread)"); + return res; + } + + multicastListenTask.status = 1; + + return 0; +} + +int32_t CAEthernetStopUnicastServer() +{ + OIC_LOG(DEBUG, TAG, "CAEthernetStopUnicastServer"); + + // mutex lock + u_mutex_lock(unicastListenTask.threadMutex); + + // set stop flag + unicastListenTask.isStop = CA_TRUE; + + // notity the thread + u_cond_signal(unicastListenTask.threadCond); + + // mutex unlock + u_mutex_unlock(unicastListenTask.threadMutex); + + unicastListenTask.status = 0; // stopped + + return 0; +} + +int32_t CAEthernetStopMulticastServer() +{ + OIC_LOG(DEBUG, TAG, "CAEthernetStopMulticastServer"); + + // mutex lock + u_mutex_lock(multicastListenTask.threadMutex); + + // set stop flag + multicastListenTask.isStop = CA_TRUE; + + // notity the thread + u_cond_signal(multicastListenTask.threadCond); + + // mutex unlock + u_mutex_unlock(multicastListenTask.threadMutex); + + multicastListenTask.status = 0; // stopped + + return 0; +} + +void CAEthernetSetCallback(CAPacketReceiveCallback callback) +{ + gPacketReceiveCallback = callback; +} + +void CAEthernetGetLocalAddress(char* addressBuffer) +{ + //char addressBuffer[INET_ADDRSTRLEN]; + memset(addressBuffer, 0, INET_ADDRSTRLEN); + + struct ifaddrs* ifAddrStruct = NULL; + struct ifaddrs* ifa = NULL; + void* tmpAddrPtr = NULL; + + getifaddrs(&ifAddrStruct); + + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) + { + if (!ifa->ifa_addr) + { + continue; + } + + if (ifa->ifa_addr->sa_family == AF_INET) + { // check it is IP4 + // is a valid IP4 Address + tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr; + + memset(addressBuffer, 0, INET_ADDRSTRLEN); + inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); + + if (strcmp(addressBuffer, "127.0.0.1") == 0) + continue; + } + } + + if (ifAddrStruct != NULL) + freeifaddrs(ifAddrStruct); +} + +int32_t CAEthernetSendUnicastMessageImpl(const char* address, const char* data) +{ + OIC_LOG_V(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, address: %s, data: %s", address, data); + + // [UDP Client] + + struct sockaddr_in si_other; + int32_t slen = sizeof(si_other); + + memset((char *) &si_other, 0, sizeof(si_other)); + + si_other.sin_family = AF_INET; + si_other.sin_port = htons(CA_UNICAST_PORT); + if (inet_aton(address, &si_other.sin_addr) == 0) + { + OIC_LOG(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, inet_aton, error..."); + return 0; + } + + OIC_LOG_V(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, sendto, to: %s, data: %s", address, + data); + if (sendto(unicast_receive_socket, data, strlen(data), 0, (struct sockaddr *) &si_other, slen) + == -1) + { + OIC_LOG(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, sendto, error..."); + + return 0; + } + + return 0; +} + +int32_t CAEthernetSendMulticastMessageImpl(const char* msg) +{ + OIC_LOG_V(DEBUG, TAG, "CAEthernetSendMulticastMessageImpl, sendto, data: %s", msg); + + int32_t result = sendto(unicast_receive_socket, msg, strlen(msg), 0, + (struct sockaddr *) &multicast_send_interface_addr, + sizeof(multicast_send_interface_addr)); + if (result < 0) + { + OIC_LOG(DEBUG, TAG, "CAEthernetSendMulticastMessageImpl, sending message error..."); + + return -1; + } + + return 0; +} diff --git a/resource/csdk/connectivity/src/wifi_adapter/cawifiethernetadapter.c b/resource/csdk/connectivity/src/wifi_adapter/cawifiethernetadapter.c deleted file mode 100644 index a6033cc..0000000 --- a/resource/csdk/connectivity/src/wifi_adapter/cawifiethernetadapter.c +++ /dev/null @@ -1,371 +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 "cawifiethernetadapter.h" - -#include -#include -#include -#include -#include "caadapterutils.h" -#include "umutex.h" - -#ifdef __TIZEN__ -#include "cawifiserver.h" -#include "cawificlient.h" -#include "cawifimonitor.h" -#elif defined(OIC_ARDUINODUE) -#include -#include -#include "cawifiadapter.h" -#endif //#ifdef __TIZEN__ -/** - * @def WIFI_ETHERNET_ADAPTER_TAG - * @brief Logging tag for module name - */ -#define WIFI_ETHERNET_ADAPTER_TAG "WIFI_ETHERNET_ADAPTER" - -/** - * @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" - -/** - * @var gNetworkCallback - * @brief Network callback - */ -static CANetworkChangeCallback gNetworkCallback = NULL; - -/** - * @var gIsMulticastServerStarted - * @brief Flag to check if multicast server is started - */ -static int gIsMulticastServerStarted = 0; -static u_mutex gMutexIsMulticastServerStarted = NULL; - -void CAInitializeMutex() -{ - u_mutex_init(); - gMutexIsMulticastServerStarted = u_mutex_new(); -} - -int CAWIFIRegisterNetworkNotifications(CANetworkChangeCallback netCallback) -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - gNetworkCallback = netCallback; //TODO: Remove and set using API define in arduino specific file -#ifdef __TIZEN__ - if (netCallback != NULL) - { - CAInitializeWIFIAdapter(); - CASetWIFINetworkChangeCallback(netCallback); - } - else - { - CADeinitializeWIFIAdapter(); - } -#endif - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback) -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - CAResult_t ret = CA_STATUS_OK; - - VERIFY_NON_NULL(registerCallback, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument"); - VERIFY_NON_NULL(reqRespCallback, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument"); - VERIFY_NON_NULL(netCallback, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument"); - - CAConnectivityHandler_t wifiHandler; - wifiHandler.startAdapter = CAStartWIFI; - wifiHandler.startListenServer = CAStartWIFIListeningServer; - wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer; - wifiHandler.sendData = CASendWIFIUnicastData; - wifiHandler.sendDataToAll = CASendWIFIMulticastData; - wifiHandler.startNotifyServer = CAStartWIFINotifyRecvServers; - wifiHandler.sendNotification = CASendWIFINotification; - wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation; - wifiHandler.readData = CAReadWIFIData; - wifiHandler.stopAdapter = CAStopWIFI; - wifiHandler.terminate = CATerminateWifi; - registerCallback(wifiHandler, CA_WIFI); - - CASetWIFINetworkPacketCallback(reqRespCallback); - CAWIFIRegisterNetworkNotifications(netCallback); - CAInitializeMutex(); - CAInitializeServerMutex(); - //ret = CAStartWIFIUnicastServer(); - - OCLog(INFO, WIFI_ETHERNET_ADAPTER_TAG, "IntializeWifi Success"); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return ret; -} - -CAResult_t CAStartWIFI() -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - int16_t unicastPort = CA_PORT; - CAResult_t ret = CA_STATUS_OK; - -#ifdef __TIZEN__ - CASetIsStartServerInvoked(); - int retVal = CAIsWIFIConnected(); - if(retVal == 0) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "WIFI is not Connected"); - return ret; - } -#endif - /*Address is hardcoded as we are using Single Interface*/ - ret = CAStartUnicastServer("0.0.0.0", &unicastPort); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return ret; -} - -CAResult_t CAStartWIFIListeningServer() -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - CAResult_t ret = CA_STATUS_OK; - int16_t multicastPort = CA_MCAST_PORT; - - if (gIsMulticastServerStarted == 1) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Server is already Started"); - return CA_STATUS_OK; - } -#ifdef __TIZEN__ - int retVal = CAIsWIFIConnected(); - if(retVal == 0) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "WIFI is not Connected"); - return CA_STATUS_FAILED; - } -#endif - ret = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort); - if (ret == CA_STATUS_OK) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Multicast Server is Started Successfully"); - u_mutex_lock(gMutexIsMulticastServerStarted); - gIsMulticastServerStarted = 1; - u_mutex_unlock(gMutexIsMulticastServerStarted); - } - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return ret; -} - -CAResult_t CAStartWIFIDiscoveryServer() -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - CAResult_t ret = CA_STATUS_OK; - int16_t multicastPort = CA_MCAST_PORT; - - if (gIsMulticastServerStarted == 1) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Server is already Started"); - return CA_STATUS_OK; - } -#ifdef __TIZEN__ - /*int retVal = CAIsWIFIConnected(); - if(retVal == 0) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "WIFI is not Connected"); - return CA_STATUS_FAILED; - }*/ //VV -#endif - ret = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort); - if (ret == CA_STATUS_OK) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Multicast Server is Started Successfully"); - u_mutex_lock(gMutexIsMulticastServerStarted); - gIsMulticastServerStarted = 1; - u_mutex_unlock(gMutexIsMulticastServerStarted); - } - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return ret; -} - -uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data, - uint32_t dataLen) -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - uint32_t dataSize = 0; - - VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument", dataSize); - VERIFY_NON_NULL_RET(data, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument", dataSize); - - if (dataLen <= 0) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Data Length is 0"); - return dataSize; - - } - - dataSize = CAWIFISendData(remoteEndpoint->addressInfo.IP.ipAddress, - remoteEndpoint->addressInfo.IP.port, data, dataLen, 0); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return dataSize; -} - -uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength) -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - uint32_t dataSize = 0; - - VERIFY_NON_NULL_RET(data, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument", dataSize); - - if (dataLength <= 0) - { - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Data Length is 0"); - return 0; - - } - dataSize = CAWIFISendData(CA_MULTICAST_IP, CA_MCAST_PORT, data, dataLength, 1); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return dataSize; -} - -CAResult_t CAStartWIFINotifyRecvServers() -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -uint32_t CASendWIFINotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen) -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivityt_t **info, uint32_t* size) -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - - VERIFY_NON_NULL(info, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument"); - //VERIFY_NON_NULL(size, WIFI_ETHERNET_ADAPTER_TAG, "Invalid argument"); - char localIpAddress[CA_IPADDR_SIZE]; - int32_t localIpAddressLen = sizeof(localIpAddress); -#ifdef __TIZEN__ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Getting WIFI address"); - CAGetInterfaceAddress(localIpAddress, localIpAddressLen); - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Got WIFI address"); -#else - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Getting shield address"); - arduinoGetInterfaceAddress(localIpAddress, localIpAddressLen); - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "Got shield address"); -#endif //#if __ARDUINO__ - /** - * Create local endpoint using util function - */ - (*info) = CreateLocalEndpoint(CA_WIFI, localIpAddress, "WiFi"); - if (NULL == (*info)) - { - OCLog(ERROR, WIFI_ETHERNET_ADAPTER_TAG, "Error while Createing Memory"); - return CA_STATUS_FAILED; - } - - (*size) = 1; - - OCLog(INFO, WIFI_ETHERNET_ADAPTER_TAG, "GetWIFIInterfaceInformation success"); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -CAResult_t CAReadWIFIData() -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); -#ifdef __ARDUINO__ - arduoinoCheckServerData(); -#endif //#ifdef __ARDUINO__ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return CA_STATUS_OK; -} - -CAResult_t CAStopWIFI() -{ - CAResult_t result = CA_STATUS_FAILED; - result = CAStopUnicastServer(); - if (result != CA_STATUS_OK) - { - OCLog(ERROR, WIFI_ETHERNET_ADAPTER_TAG, "Error while stopping UnicastServer"); - return CA_STATUS_FAILED; - } -#ifdef __TIZEN__ - CAUnsetIsStartServerInvoked(); -#endif - result = CAStopMulticastServer(); - if (result != CA_STATUS_OK) - { - OCLog(ERROR, WIFI_ETHERNET_ADAPTER_TAG, "Error while stopping MulticastServer"); - return CA_STATUS_FAILED; - } - else - { - u_mutex_lock(gMutexIsMulticastServerStarted); - gIsMulticastServerStarted = 0; - u_mutex_unlock(gMutexIsMulticastServerStarted); - } - return CA_STATUS_OK; -} - -void CATerminateWifi() -{ - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "IN"); - CAResult_t result = CA_STATUS_FAILED; - - CASetWIFINetworkPacketCallback(NULL); - result = CAWIFIRegisterNetworkNotifications(NULL); - if (result != CA_STATUS_OK) - { - OCLog(ERROR, WIFI_ETHERNET_ADAPTER_TAG, - "Error while wifiRegisterNetworkNotifications(NULL)"); - } - - OCLog(INFO, WIFI_ETHERNET_ADAPTER_TAG, "TerminateWifi Success"); - - OCLog(DEBUG, WIFI_ETHERNET_ADAPTER_TAG, "OUT"); - return; -} diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiadapter.c index 298f50f..7ddf382 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiadapter.c +++ b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiadapter.c @@ -23,20 +23,19 @@ #include #include "cawifiadapter.h" - #include "config.h" #include "coap.h" - #include "cawificore.h" - #include "logger.h" +#include "oic_malloc.h" #define TAG PCF("CA") // received packet callback static CANetworkPacketReceivedCallback gWifiReceivedCallback = NULL; +static u_thread_pool_t gThreadPoolHandle = NULL; -static void CAWiFiPacketReceiveCallback(const char* address, const char* data) +static void CAWiFiPacketReceiveCallback(char* address, const char* data) { OIC_LOG_V(DEBUG, TAG, "CAWiFiPacketReceiveCallback, from: %s, data: %s", address, data); @@ -49,22 +48,26 @@ static void CAWiFiPacketReceiveCallback(const char* address, const char* data) // set address memset((void*) endpoint->addressInfo.IP.ipAddress, 0, CA_IPADDR_SIZE); - if (CA_IPADDR_SIZE > strlen(address)) + if (CA_IPADDR_SIZE > strlen(address)) { strcpy((char*) endpoint->addressInfo.IP.ipAddress, address); + } + OICFree(address); // set connectivity type endpoint->connectivityType = CA_WIFI; - gWifiReceivedCallback(endpoint, data, strlen(data)); + gWifiReceivedCallback(endpoint, (void *) data, strlen(data)); } } CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, - CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback) + CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle) { OIC_LOG(DEBUG, TAG, "IntializeWifi"); gWifiReceivedCallback = reqRespCallback; + gThreadPoolHandle = handle; // register handlers CAConnectivityHandler_t handler; @@ -86,7 +89,7 @@ CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, CAWiFiSetCallback(CAWiFiPacketReceiveCallback); - return 0; + return CA_STATUS_OK; } void CATerminateWIfI() @@ -99,12 +102,16 @@ void CATerminateWIfI() CAResult_t CAStartWIFI() { OIC_LOG(DEBUG, TAG, "CAStartWIFI"); - CAWiFiInitialize(); + //CAWiFiInitialize(); + CAWiFiInitialize(gThreadPoolHandle); OIC_LOG(DEBUG, TAG, "CAWiFiStartUnicastServer"); - CAWiFiStartUnicastServer("0.0.0.0", atoi("5283")); + int32_t res = CAWiFiStartUnicastServer("0.0.0.0", atoi("5283")); - return 0; + if (res < 0) + return CA_STATUS_FAILED; + + return CA_STATUS_OK; } CAResult_t CAStopWIFI() @@ -113,25 +120,31 @@ CAResult_t CAStopWIFI() // ToDo: - return 0; + return CA_STATUS_OK; } CAResult_t CAStartWIFIListeningServer() { OIC_LOG(DEBUG, TAG, "StartWIFIListeningServer"); - CAWiFiStartMulticastServer("0.0.0.0", atoi("5283")); + int32_t res = CAWiFiStartMulticastServer("0.0.0.0", atoi("5283")); - return 0; + if (res < 0) + return CA_STATUS_FAILED; + + return CA_STATUS_OK; } CAResult_t CAStartWIFIDiscoveryServer() { OIC_LOG(DEBUG, TAG, "StartWIFIDiscoveryServer"); - CAWiFiStartMulticastServer("0.0.0.0", atoi("5283")); + int32_t res = CAWiFiStartMulticastServer("0.0.0.0", atoi("5283")); - return 0; + if (res < 0) + return CA_STATUS_FAILED; + + return CA_STATUS_OK; } uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen) @@ -158,7 +171,7 @@ CAResult_t CAStartWIFINotifyRecvServers() // ToDo: - return 0; + return CA_STATUS_OK; } uint32_t CASendWIFINotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen) @@ -170,13 +183,13 @@ uint32_t CASendWIFINotification(const CARemoteEndpoint_t* endpoint, void* data, return 0; } -CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivityt_t** info, uint32_t* size) +CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size) { OIC_LOG(DEBUG, TAG, "GetWIFIInterfaceInformation"); // ToDo: - return 0; + return CA_STATUS_OK; } CAResult_t CAReadWIFIData() @@ -185,6 +198,6 @@ CAResult_t CAReadWIFIData() // ToDo: - return 0; + return CA_STATUS_OK; } diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawificore.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawificore.c index f3d4f5f..81137c3 100644 --- a/resource/csdk/connectivity/src/wifi_adapter/linux/cawificore.c +++ b/resource/csdk/connectivity/src/wifi_adapter/linux/cawificore.c @@ -1,500 +1,617 @@ -#include -#include -#include -#include -#include -#include -#include "cawificore.h" -#include -#include -#include -#include -#include -#include -#include "logger.h" - -#define TAG PCF("CA") - -#define CA_MAX_BUFFER_SIZE 512 // Max length of buffer -#define CA_UNICAST_PORT 5283 // The port on which to listen for incoming data -int32_t unicast_socket; -pthread_t pthread_unicast_server; -pthread_t pthread_unicast_client; -pthread_mutex_t mutex_unicast; -pthread_cond_t sync_cond_unicast; -int32_t unicast_send_thread_flag = 0; // 0: run, 1: stop - -char* target = NULL; -void* list = NULL; - -#define CA_MULTICAST_ADDR "224.0.1.187" -#define CA_MULTICAST_PORT 5683 - -int32_t multicast_send_socket; -struct sockaddr_in multicast_send_interface_addr; - -pthread_t pthread_multicast_server; -pthread_t pthread_multicast_client; - -int32_t multicast_receive_socket; -struct sockaddr_in multicast_receive_interface_addr; - -void* data_list = NULL; - -pthread_mutex_t mutex_multicast; -pthread_cond_t sync_cond_multicast; -int32_t multicast_send_thread_flag = 0; // 0: run, 1: stop - -CAPacketReceiveCallback gPacketReceiveCallback = NULL; - -void CAWiFiInitialize() -{ - OIC_LOG(DEBUG, TAG, "CAWiFiInitialize"); - - pthread_mutex_init(&mutex_unicast, NULL); - - pthread_mutex_init(&mutex_multicast, NULL); - - // [UDP Server] - struct sockaddr_in si_me; - - // create a UDP socket - if ((unicast_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - { - OIC_LOG_V(DEBUG, TAG, "CAWiFiInit, creating socket failed"); - - return; - } - - OIC_LOG_V(DEBUG, TAG, "CAWiFiInit, socket created"); - - // zero out the structure - memset((char *) &si_me, 0, sizeof(si_me)); - - si_me.sin_family = AF_INET; - si_me.sin_port = htons(CA_UNICAST_PORT); - si_me.sin_addr.s_addr = htonl(INADDR_ANY); - - // bind socket to port - if (bind(unicast_socket, (struct sockaddr*) &si_me, sizeof(si_me)) == -1) - { - OIC_LOG(DEBUG, TAG, "CAWiFiInit, binding socket failed"); - - return; - } - - OIC_LOG(DEBUG, TAG, "CAWiFiInit, socket binded"); - - // [multicast sender] - uint32_t multiTTL = 1; - - // 1. Set up a typical UDP socket - multicast_send_socket = socket(AF_INET, SOCK_DGRAM, 0); - if (multicast_send_socket < 0) - { - OIC_LOG(DEBUG, TAG, "CAWiFiInit, Socket error"); - - return; - } - - memset(&multicast_send_interface_addr, 0, sizeof(multicast_send_interface_addr)); - multicast_send_interface_addr.sin_family = AF_INET; - multicast_send_interface_addr.sin_addr.s_addr = inet_addr(CA_MULTICAST_ADDR); - multicast_send_interface_addr.sin_port = htons(CA_MULTICAST_PORT); - - // [multicast receiver] - // 1. Create a typical UDP socket and set Non-blocking for reading - multicast_receive_socket = socket(AF_INET, SOCK_DGRAM, 0); - if (multicast_receive_socket < 0) - { - OIC_LOG(DEBUG, TAG, "CAWiFiInit, Socket error"); - - return; - } - - // 2. Allow multiple sockets to use the same port number - int32_t ret_val = setsockopt(multicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL, - sizeof(multiTTL)); - if (ret_val < 0) - { - OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to set REUSEADDR"); - } - - // 3. Set up the interface - memset(&multicast_receive_interface_addr, 0, sizeof(multicast_receive_interface_addr)); - multicast_receive_interface_addr.sin_family = AF_INET; - multicast_receive_interface_addr.sin_addr.s_addr = htonl(INADDR_ANY); - multicast_receive_interface_addr.sin_port = htons(CA_MULTICAST_PORT); - - // 4. Bind to the interface - ret_val = bind(multicast_receive_socket, (struct sockaddr *) &multicast_receive_interface_addr, - sizeof(multicast_receive_interface_addr)); - if (ret_val < 0) - { - OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to bind socket"); - - return; - } - - // 5. Join the multicast group - struct ip_mreq mreq; - memset(&mreq, 0, sizeof(mreq)); - mreq.imr_multiaddr.s_addr = inet_addr(CA_MULTICAST_ADDR); - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - ret_val = setsockopt(multicast_receive_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, - sizeof(mreq)); - if (ret_val < 0) - { - OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to join multicast group"); - - return; - } -} - -void CAWiFiTerminate() -{ - OIC_LOG(DEBUG, TAG, "CAWiFiTerminate"); - - pthread_mutex_destroy(&mutex_unicast); - - pthread_mutex_destroy(&mutex_multicast); - - close(unicast_socket); - - close(multicast_send_socket); - - close(multicast_receive_socket); -} - -int32_t CAWiFiSendUnicastMessage(const char* address, const char* data, int lengh) -{ - CASendUnicastMessage(address, data); - - return 0; -} - -int32_t CAWiFiSendMulticastMessage(const char* m_address, const char* data) -{ - CASendMulticastMessage(data); - - return 0; -} - -int32_t CAWiFiStartUnicastServer(const char* address, int port) -{ - OIC_LOG_V(DEBUG, TAG, "CAWiFiStartUnicastServer(%s, %d)", address, port); - - int32_t result = pthread_create(&pthread_unicast_server, NULL, (void *) &CAUnicastReceiveThread, - (void *) NULL); - if (result < 0) - { - OIC_LOG(DEBUG, TAG, "CAWiFiStartUnicastServer, creating unicast_receive_thread failed"); - - return -1; - } - - result = pthread_create(&pthread_unicast_client, NULL, (void *) &CAUnicastSendThread, - (void *) NULL); - if (result < 0) - { - OIC_LOG(DEBUG, TAG, "CAWiFiStartUnicastServer, creating unicast_send_thread failed"); - - return -1; - } - - OIC_LOG(DEBUG, TAG, "CAWiFiStartUnicastServer, receive & send thread created"); - - return 0; -} - -int32_t CAWiFiStartMulticastServer(const char* m_address, int port) -{ - OIC_LOG_V(DEBUG, TAG, "CAWiFiStartMulticastServer(%s, %d)", m_address, port); - - int32_t result = pthread_create(&pthread_multicast_server, NULL, - (void *) &CAMulticastReceiveThread, (void *) NULL); - if (result < 0) - { - - return -1; - } - - result = pthread_create(&pthread_multicast_client, NULL, (void *) &CAMulticastSendThread, - (void *) NULL); - if (result < 0) - { - OIC_LOG(DEBUG, TAG, "creating receive_thread failed"); - - return -1; - } - - return 0; -} - -int32_t CAWiFiStopUnicastServer(int32_t server_id) -{ - - CAStopUnicastSendThread(); - - return 0; -} - -int32_t CAWiFiStopMulticastServer(int32_t server_id) -{ - - CAStopMulticastSendThread(); - - return 0; -} - -void CAWiFiSetCallback(CAPacketReceiveCallback callback) -{ - gPacketReceiveCallback = callback; -} - -void* CAUnicastReceiveThread(void* data) -{ - OIC_LOG(DEBUG, TAG, "CAUnicastReceiveThread"); - - char buf[CA_MAX_BUFFER_SIZE]; - int32_t recv_len; - - struct sockaddr_in si_other; - int32_t slen = sizeof(si_other); - - // keep listening for data - while (1) - { - OIC_LOG(DEBUG, TAG, "CAUnicastReceiveThread, Waiting for data..."); - fflush(stdout); - - memset(buf, 0, sizeof(char) * CA_MAX_BUFFER_SIZE); - - // try to receive some data, this is a blocking call - if ((recv_len = recvfrom(unicast_socket, buf, CA_MAX_BUFFER_SIZE, 0, - (struct sockaddr *) &si_other, &slen)) == -1) - { - OIC_LOG(DEBUG, TAG, "CAUnicastReceiveThread, recv_len() error"); - continue; - } - - // print details of the client/peer and the data received - OIC_LOG_V(DEBUG, TAG, "CAUnicastReceiveThread, Received packet from %s:%d", - inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port)); - OIC_LOG_V(DEBUG, TAG, "CAUnicastReceiveThread, Data: %s", buf); - - if (gPacketReceiveCallback != NULL) - { - gPacketReceiveCallback(inet_ntoa(si_other.sin_addr), buf); - } - } - - return (void*) 0; -} - -void* CAUnicastSendThread(void* data) -{ - OIC_LOG(DEBUG, TAG, "CAUnicastSendThread"); - - while (!unicast_send_thread_flag) - { - pthread_mutex_lock(&mutex_unicast); - - pthread_cond_wait(&sync_cond_unicast, &mutex_unicast); - - pthread_mutex_unlock(&mutex_unicast); - - if (unicast_send_thread_flag) - return (void*) 0; - - CASendUnicastMessageImpl(target, list, strlen(list)); - } - - return (void*) 0; -} - -void CASendUnicastMessage(char* address, void* data) -{ - target = address; - list = data; - unicast_send_thread_flag = 0; - - pthread_cond_signal(&sync_cond_unicast); -} - -int32_t CASendUnicastMessageImpl(const char* address, const char* data, int32_t lengh) -{ - OIC_LOG_V(DEBUG, TAG, "CASendUnicastMessageImpl, address: %s, data: %s", address, data); - - // [UDP Client] - struct sockaddr_in si_other; - int32_t slen = sizeof(si_other); - - memset((char *) &si_other, 0, sizeof(si_other)); - - si_other.sin_family = AF_INET; - si_other.sin_port = htons(CA_UNICAST_PORT); - if (inet_aton(address, &si_other.sin_addr) == 0) - { - OIC_LOG(DEBUG, TAG, "CASendUnicastMessageImpl, inet_aton, error..."); - return 0; - } - - OIC_LOG_V(DEBUG, TAG, "CASendUnicastMessageImpl, sendto, to: %s, data: %s", address, data); - if (sendto(unicast_socket, data, strlen(data), 0, (struct sockaddr *) &si_other, slen) == -1) - { - OIC_LOG(DEBUG, TAG, "CASendUnicastMessageImpl, sendto, error..."); - - return 0; - } - - return 0; -} - -void CAStopUnicastSendThread() -{ - unicast_send_thread_flag = 1; - - pthread_cond_signal(&sync_cond_unicast); -} - -void* CAMulticastReceiveThread(void* data) -{ - OIC_LOG(DEBUG, TAG, "CAMulticastReceiveThread"); - - // 6. Read from the socket and print out a message when one is received - char msgbuf[CA_MAX_BUFFER_SIZE]; - - struct sockaddr_in client; - int32_t addrlen = sizeof(client); - - OIC_LOG(DEBUG, TAG, "CAMulticastReceiveThread, waiting for input..."); - - while (1) - { - int32_t recv_bytes = recvfrom(multicast_receive_socket, msgbuf, CA_MAX_BUFFER_SIZE, 0, - (struct sockaddr *) &client, (socklen_t *) &addrlen); - if (recv_bytes < 0) - { - if (errno != EAGAIN) - { - OIC_LOG(DEBUG, TAG, "CAMulticastReceiveThread, error recvfrom"); - - return (void*) 0; - } - - continue; - } - - msgbuf[recv_bytes] = 0; - - OIC_LOG_V(DEBUG, TAG, "Received msg: %s, size: %d", msgbuf, recv_bytes); - - char* sender = inet_ntoa(client.sin_addr); - char local[INET_ADDRSTRLEN]; - CAGetLocalAddress(local); - if (strcmp(sender, local) == 0) - { - OIC_LOG_V(DEBUG, TAG, "skip the local request (via multicast)"); - } - else - { - if (gPacketReceiveCallback != NULL) - { - gPacketReceiveCallback(inet_ntoa(client.sin_addr), msgbuf); - } - } - - } - - return (void*) 0; -} - -void* CAMulticastSendThread(void* data) -{ - OIC_LOG(DEBUG, TAG, "CAMulticastSendThread"); - - while (!multicast_send_thread_flag) - { - pthread_mutex_lock(&mutex_multicast); - - pthread_cond_wait(&sync_cond_multicast, &mutex_multicast); - - pthread_mutex_unlock(&mutex_multicast); - - if (multicast_send_thread_flag) - return (void*) 0; - - CASendMulticastMessageImpl(data_list); - } - - return (void*) 0; -} - -void CASendMulticastMessage(void* data) -{ - data_list = data; - multicast_send_thread_flag = 0; - - pthread_cond_signal(&sync_cond_multicast); -} - -int32_t CASendMulticastMessageImpl(const char* msg) -{ - OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, sendto, data: %s", msg); - - int32_t result = sendto(multicast_send_socket, msg, strlen(msg), 0, - (struct sockaddr *) &multicast_send_interface_addr, - sizeof(multicast_send_interface_addr)); - if (result < 0) - { - OIC_LOG(DEBUG, TAG, "CASendMulticastMessageImpl, sending message error..."); - - return -1; - } - - return 0; -} - -void CAStopMulticastSendThread() -{ - multicast_send_thread_flag = 1; - - pthread_cond_signal(&sync_cond_multicast); -} - -void CAGetLocalAddress(char* addressBuffer) -{ - //char addressBuffer[INET_ADDRSTRLEN]; - memset(addressBuffer, 0, INET_ADDRSTRLEN); - - struct ifaddrs* ifAddrStruct = NULL; - struct ifaddrs* ifa = NULL; - void* tmpAddrPtr = NULL; - - getifaddrs(&ifAddrStruct); - - for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) - { - if (!ifa->ifa_addr) - { - continue; - } - - if (ifa->ifa_addr->sa_family == AF_INET) - { // check it is IP4 - // is a valid IP4 Address - tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr; - - memset(addressBuffer, 0, INET_ADDRSTRLEN); - inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); - - if (strcmp(addressBuffer, "127.0.0.1") == 0) - continue; - } - } - - if (ifAddrStruct != NULL) - freeifaddrs(ifAddrStruct); -} - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cawificore.h" +#include "logger.h" +#include "uthreadpool.h" /* for thread pool */ +#include "umutex.h" +#include "caqueueingthread.h" +#include "oic_malloc.h" + +#define TAG PCF("CA") + +#define CA_MAX_BUFFER_SIZE 512 // Max length of buffer #define CA_UNICAST_PORT 5383 // The port on which to listen for incoming data #define CA_MULTICAST_ADDR "224.0.1.187" +#define CA_MULTICAST_PORT 5683 + +typedef enum +{ + CA_UNICAST = 1, CA_MULTICAST +} CATransmissionType_t; + +typedef struct +{ + CATransmissionType_t transmissionType; // 0: none, 1: unicast, 2: multicast + char* address; + int port; + void* data; +} CAThreadData_t; + +typedef struct +{ + u_mutex threadMutex; + u_cond threadCond; + int32_t isStop; + int32_t status; // 0: stopped, 1: running +} CATask_t; + +int32_t unicast_receive_socket; +struct sockaddr_in multicast_send_interface_addr; +int32_t multicast_receive_socket; +struct sockaddr_in multicast_receive_interface_addr; + +static CAPacketReceiveCallback gPacketReceiveCallback = NULL; + +static u_thread_pool_t gThreadPoolHandle = NULL; + +// message handler main thread +static CAQueueingThread_t gSendThread; +static CAQueueingThread_t gReceiveThread; + +CATask_t unicastListenTask; +CATask_t multicastListenTask; + +static void CASendProcess(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CASendThreadProcess"); + + CAThreadData_t* data = (CAThreadData_t*) threadData; + if (data == NULL) + { + OIC_LOG(DEBUG, TAG, "thread data is error!"); + return; + } + + if (data->transmissionType == CA_UNICAST) + { + // unicast + CASendUnicastMessageImpl(data->address, (char*) (data->data)); + } + else if (data->transmissionType == CA_MULTICAST) + { + // multicast + CASendMulticastMessageImpl((char*) (data->data)); + } +} + +static void CAReceiveProcess(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CAReceiveProcess"); + + CAThreadData_t* data = (CAThreadData_t*) threadData; + if (data == NULL) + { + OIC_LOG(DEBUG, TAG, "thread data is error!"); + return; + } + + if (gPacketReceiveCallback != NULL) + { + gPacketReceiveCallback(data->address, (char*) (data->data)); + } +} + +static void CAUnicastListenThread(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CAUnicastListenThread"); + + char buf[CA_MAX_BUFFER_SIZE]; + int32_t recv_len; + + struct sockaddr_in si_other; + int32_t slen = sizeof(si_other); + + while (!unicastListenTask.isStop) + { + OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, Waiting for data..."); + fflush(stdout); + + memset(buf, 0, sizeof(char) * CA_MAX_BUFFER_SIZE); + + // try to receive some data, this is a blocking call + if ((recv_len = recvfrom(unicast_receive_socket, buf, CA_MAX_BUFFER_SIZE, 0, + (struct sockaddr *) &si_other, (socklen_t *) &slen)) == -1) + { + OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, recv_len() error"); + continue; + } + + // print details of the client/peer and the data received + OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Received packet from %s:%d", + inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port)); + OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Data: %s", buf); + + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = 1; // unicast + + char* _address = inet_ntoa(si_other.sin_addr); + int len = strlen(_address); + td->address = (char*) OICMalloc(sizeof(char) * (len + 1)); + memset(td->address, 0, len + 1); + memcpy(td->address, _address, len); + td->port = ntohs(si_other.sin_port); + + td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE); + memset(td->data, 0, CA_MAX_BUFFER_SIZE); + memcpy(td->data, buf, sizeof(buf)); + + CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t)); + } + + OIC_LOG(DEBUG, TAG, "end of CAUnicastListenThread"); +} + +static void CAMulticastListenThread(void* threadData) +{ + OIC_LOG(DEBUG, TAG, "CAMulticastListenThread"); + + char msgbuf[CA_MAX_BUFFER_SIZE]; + + struct sockaddr_in client; + int32_t addrlen = sizeof(client); + + OIC_LOG(DEBUG, TAG, "CAMulticastListenThread, waiting for input..."); + + while (!multicastListenTask.isStop) + { + int32_t recv_bytes = recvfrom(multicast_receive_socket, msgbuf, CA_MAX_BUFFER_SIZE, 0, + (struct sockaddr *) &client, (socklen_t *) &addrlen); + if (recv_bytes < 0) + { + if (errno != EAGAIN) + { + OIC_LOG(DEBUG, TAG, "CAMulticastListenThread, error recvfrom"); + + return; + } + + continue; + } + + msgbuf[recv_bytes] = 0; + + OIC_LOG_V(DEBUG, TAG, "Received msg: %s, size: %d", msgbuf, recv_bytes); + + char* sender = inet_ntoa(client.sin_addr); + char local[INET_ADDRSTRLEN]; + CAGetLocalAddress(local); + if (strcmp(sender, local) == 0) + { + OIC_LOG_V(DEBUG, TAG, "skip the local request (via multicast)"); + } + else + { + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = 2; // multicast + + char* _address = inet_ntoa(client.sin_addr); + int len = strlen(_address); + td->address = (char*) OICMalloc(sizeof(char) * (len + 1)); + memset(td->address, 0, len + 1); + memcpy(td->address, _address, len); + td->port = ntohs(client.sin_port); + + td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE); + memset(td->data, 0, CA_MAX_BUFFER_SIZE); + memcpy(td->data, msgbuf, sizeof(msgbuf)); + + CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t)); + } + + } + + OIC_LOG(DEBUG, TAG, "end of CAMulticastListenThread"); +} + +void CAWiFiInitialize(u_thread_pool_t handle) +{ + OIC_LOG(DEBUG, TAG, "CAWiFiInitialize"); + + gThreadPoolHandle = handle; + + // unicast/multicast send queue + CAQueueingThreadInitialize(&gSendThread, gThreadPoolHandle, CASendProcess); + + // start send thread + CAResult_t res = CAQueueingThreadStart(&gSendThread); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "thread start is error (send thread)"); + // return res; + return; + } + + // unicast/multicast receive queue + CAQueueingThreadInitialize(&gReceiveThread, gThreadPoolHandle, CAReceiveProcess); + + // start send thread + res = CAQueueingThreadStart(&gReceiveThread); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "thread start is error (receive thread)"); + // return res; + return; + } + + unicastListenTask.threadMutex = u_mutex_new(); + unicastListenTask.threadCond = u_cond_new(); + unicastListenTask.isStop = FALSE; + unicastListenTask.status = 0; // stopped + + multicastListenTask.threadMutex = u_mutex_new(); + multicastListenTask.threadCond = u_cond_new(); + multicastListenTask.isStop = FALSE; + multicastListenTask.status = 0; // stopped + + // [UDP Server] + struct sockaddr_in si_me; + + // create a UDP socket + if ((unicast_receive_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + { + OIC_LOG_V(DEBUG, TAG, "CAWiFiInit, creating socket failed"); + + return; + } + + OIC_LOG_V(DEBUG, TAG, "CAWiFiInit, socket created"); + + // [multicast sender] + uint32_t multiTTL = 1; + + // zero out the structure + memset((char *) &si_me, 0, sizeof(si_me)); + + si_me.sin_family = AF_INET; + si_me.sin_port = htons(CA_UNICAST_PORT); + si_me.sin_addr.s_addr = htonl(INADDR_ANY); + + int32_t ret_val = setsockopt(unicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL, + sizeof(multiTTL)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to set REUSEADDR"); + } + + // bind socket to port + if (bind(unicast_receive_socket, (struct sockaddr*) &si_me, sizeof(si_me)) == -1) + { + OIC_LOG(DEBUG, TAG, "CAWiFiInit, binding socket failed"); + + return; + } + + OIC_LOG(DEBUG, TAG, "CAWiFiInit, socket binded"); + + memset(&multicast_send_interface_addr, 0, sizeof(multicast_send_interface_addr)); + multicast_send_interface_addr.sin_family = AF_INET; + multicast_send_interface_addr.sin_addr.s_addr = inet_addr(CA_MULTICAST_ADDR); + multicast_send_interface_addr.sin_port = htons(CA_MULTICAST_PORT); + + // [multicast receiver] + // 1. Create a typical UDP socket and set Non-blocking for reading + multicast_receive_socket = socket(AF_INET, SOCK_DGRAM, 0); + if (multicast_receive_socket < 0) + { + OIC_LOG(DEBUG, TAG, "CAWiFiInit, Socket error"); + + return; + } + + // 2. Allow multiple sockets to use the same port number + ret_val = setsockopt(multicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL, + sizeof(multiTTL)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to set REUSEADDR"); + } + + // 3. Set up the interface + memset(&multicast_receive_interface_addr, 0, sizeof(multicast_receive_interface_addr)); + multicast_receive_interface_addr.sin_family = AF_INET; + multicast_receive_interface_addr.sin_addr.s_addr = htonl(INADDR_ANY); + multicast_receive_interface_addr.sin_port = htons(CA_MULTICAST_PORT); + + // 4. Bind to the interface + ret_val = bind(multicast_receive_socket, (struct sockaddr *) &multicast_receive_interface_addr, + sizeof(multicast_receive_interface_addr)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to bind socket"); + + return; + } + + // 5. Join the multicast group + struct ip_mreq mreq; + memset(&mreq, 0, sizeof(mreq)); + mreq.imr_multiaddr.s_addr = inet_addr(CA_MULTICAST_ADDR); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + ret_val = setsockopt(multicast_receive_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, + sizeof(mreq)); + if (ret_val < 0) + { + OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to join multicast group"); + + return; + } +} + +void CAWiFiTerminate() +{ + OIC_LOG(DEBUG, TAG, "CAWiFiTerminate"); + + close(unicast_receive_socket); + close(multicast_receive_socket); + + shutdown(unicast_receive_socket, 2); + shutdown(multicast_receive_socket, 2); + + CAWiFiStopUnicastServer(0); + + CAWiFiStopMulticastServer(0); + + // stop thread + CAQueueingThreadStop(&gSendThread); + // delete thread data + CAQueueingThreadDestroy(&gSendThread); + + // stop thread + CAQueueingThreadStop(&gReceiveThread); + // delete thread data + CAQueueingThreadDestroy(&gReceiveThread); + + u_mutex_free(unicastListenTask.threadMutex); + u_cond_free(unicastListenTask.threadCond); + + u_mutex_free(multicastListenTask.threadMutex); + u_cond_free(multicastListenTask.threadCond); + +} + +int32_t CAWiFiSendUnicastMessage(const char* address, const char* data, int lengh) +{ + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + if (td == NULL) + { + return 0; + } + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = CA_UNICAST; // unicast type + int len = strlen(address); + td->address = (char*) OICMalloc(sizeof(char) * (len + 1)); + if (td->address != NULL) + { + memset(td->address, 0, len + 1); + memcpy(td->address, address, len); + } + else + { + OIC_LOG_V(DEBUG, TAG, "Memory Full"); + OICFree(td); + return 0; + } + + td->data = data; + + CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t)); + + return 0; +} + +int32_t CAWiFiSendMulticastMessage(const char* m_address, const char* data) +{ + // store the data at queue. + CAThreadData_t* td = NULL; + td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t)); + if (td == NULL) + { + OICFree(data); + return 0; + } + memset(td, 0, sizeof(CAThreadData_t)); + td->transmissionType = CA_MULTICAST; // multicast type + td->address = NULL; + td->data = data; + + CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t)); + + return 0; +} + +int32_t CAWiFiStartUnicastServer() +{ + OIC_LOG_V(DEBUG, TAG, "CAWiFiStartUnicastServer(%s, %d)", "0.0.0.0", CA_UNICAST_PORT); + + // check the server status + if (unicastListenTask.status == 1) + { + OIC_LOG(DEBUG, TAG, "CAWiFiStartUnicastServer, already running"); + + return 0; + } + + // unicast listen thread + CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAUnicastListenThread, NULL); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (unicast listen thread)"); + return res; + } + + unicastListenTask.status = 1; // running + + return 0; +} + +int32_t CAWiFiStartMulticastServer() +{ + OIC_LOG_V(DEBUG, TAG, "CAWiFiStartMulticastServer(%s, %d)", "0.0.0.0", CA_MULTICAST_PORT); + + // check the server status + if (multicastListenTask.status == 1) + { + OIC_LOG(DEBUG, TAG, "CAWiFiStartMulticastServer, already running"); + + return 0; + } + + // multicast listen thread + CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAMulticastListenThread, NULL); + if (res != CA_STATUS_OK) + { + OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (multicast listen thread)"); + return res; + } + + multicastListenTask.status = 1; + + return 0; +} + +int32_t CAWiFiStopUnicastServer() +{ + OIC_LOG(DEBUG, TAG, "CAWiFiStopUnicastServer"); + + // mutex lock + u_mutex_lock(unicastListenTask.threadMutex); + + // set stop flag + unicastListenTask.isStop = TRUE; + + // notity the thread + u_cond_signal(unicastListenTask.threadCond); + + // mutex unlock + u_mutex_unlock(unicastListenTask.threadMutex); + + unicastListenTask.status = 0; // stopped + + return 0; +} + +int32_t CAWiFiStopMulticastServer() +{ + OIC_LOG(DEBUG, TAG, "CAWiFiStopMulticastServer"); + + // mutex lock + u_mutex_lock(multicastListenTask.threadMutex); + + // set stop flag + multicastListenTask.isStop = TRUE; + + // notity the thread + u_cond_signal(multicastListenTask.threadCond); + + // mutex unlock + u_mutex_unlock(multicastListenTask.threadMutex); + + multicastListenTask.status = 0; // stopped + + return 0; +} + +void CAWiFiSetCallback(CAPacketReceiveCallback callback) +{ + gPacketReceiveCallback = callback; +} + +void CAGetLocalAddress(char* addressBuffer) +{ + //char addressBuffer[INET_ADDRSTRLEN]; + memset(addressBuffer, 0, INET_ADDRSTRLEN); + + struct ifaddrs* ifAddrStruct = NULL; + struct ifaddrs* ifa = NULL; + void* tmpAddrPtr = NULL; + + getifaddrs(&ifAddrStruct); + + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) + { + if (!ifa->ifa_addr) + { + continue; + } + + if (ifa->ifa_addr->sa_family == AF_INET) + { // check it is IP4 + // is a valid IP4 Address + tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr; + + memset(addressBuffer, 0, INET_ADDRSTRLEN); + inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); + + if (strcmp(addressBuffer, "127.0.0.1") == 0) + continue; + } + } + + if (ifAddrStruct != NULL) + freeifaddrs(ifAddrStruct); +} + +int32_t CASendUnicastMessageImpl(const char* address, const char* data) +{ + OIC_LOG_V(DEBUG, TAG, "CASendUnicastMessageImpl, address: %s, data: %s", address, data); + + // [UDP Client] + + struct sockaddr_in si_other; + int32_t slen = sizeof(si_other); + + memset((char *) &si_other, 0, sizeof(si_other)); + + si_other.sin_family = AF_INET; + si_other.sin_port = htons(CA_UNICAST_PORT); + if (inet_aton(address, &si_other.sin_addr) == 0) + { + OIC_LOG(DEBUG, TAG, "CASendUnicastMessageImpl, inet_aton, error..."); + return 0; + } + + OIC_LOG_V(DEBUG, TAG, "CASendUnicastMessageImpl, sendto, to: %s, data: %s", address, data); + if (sendto(unicast_receive_socket, data, strlen(data), 0, (struct sockaddr *) &si_other, slen) + == -1) + { + OIC_LOG(DEBUG, TAG, "CASendUnicastMessageImpl, sendto, error..."); + + return 0; + } + + return 0; +} + +int32_t CASendMulticastMessageImpl(const char* msg) +{ + OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, sendto, data: %s", msg); + + int32_t result = sendto(unicast_receive_socket, msg, strlen(msg), 0, + (struct sockaddr *) &multicast_send_interface_addr, + sizeof(multicast_send_interface_addr)); + if (result < 0) + { + OIC_LOG(DEBUG, TAG, "CASendMulticastMessageImpl, sending message error..."); + + return -1; + } + + return 0; +} diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/caethernetadapter.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/caethernetadapter.c new file mode 100644 index 0000000..31c0501 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/caethernetadapter.c @@ -0,0 +1,120 @@ +/****************************************************************** + * + * 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 +#include +#include "logger.h" + +/** + * @def WIFI_ETHERNET_ADAPTER_TAG + * @brief Logging tag for module name + */ +#define ETHERNET_ADAPTER_TAG "ETHERNET_ADAPTER" + +CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback, + CANetworkPacketReceivedCallback networkPacketCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle) +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +CAResult_t CAStartEthernet() +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +CAResult_t CAStartEthernetListeningServer() +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; + +} + +CAResult_t CAStartEthernetDiscoveryServer() +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data, + uint32_t dataLen) +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return 0; +} + +uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLength) +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return 0; +} + +CAResult_t CAStartEthernetNotifyServer() +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +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_NOT_SUPPORTED; +} + +CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size) +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +CAResult_t CAReadEthernetData() +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +CAResult_t CAStopEthernet() +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); + return CA_NOT_SUPPORTED; +} + +void CATerminateEthernet() +{ + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN"); + OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT"); +} diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiadapter.c new file mode 100644 index 0000000..2aaa639 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiadapter.c @@ -0,0 +1,494 @@ +/****************************************************************** + * + * 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 "umutex.h" +#include "logger.h" +#include "cawifiserver.h" +#include "cawificlient.h" +#include "cawifimonitor.h" +#include "camessagequeue.h" + +/** + * @def WIFI_ETHERNET_ADAPTER_TAG + * @brief Logging tag for module name + */ +#define WIFI_ADAPTER_TAG "WIFI_ADAPTER" + +/** + * @def CA_PORT + * @brief Port to listen for incoming data + */ +#define CA_PORT 5283 + +/** + * @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 + */ +static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL; + +/** + * @var gIsMulticastServerStarted + * @brief Flag to check if multicast server is started + */ +static int gIsMulticastServerStarted = 0; + +/** + * @var gMutexIsMulticastServerStarted + * @brief Mutex for gIsMulticastServerStarted + */ +static u_mutex gMutexIsMulticastServerStarted = NULL; + +/** + * @var gSendQueueHandle + * @brief Queue handle for Send Data + */ +static CAAdapterMessageQueue_t *gSendQueueHandle = NULL; + +/** + * @var gRecvQueueHandle + * @brief Queue handle for Receive Data + */ +static CAAdapterMessageQueue_t *gRecvQueueHandle = NULL; + +/** + * @var gSendDataCond + * @brief Condition for Send Data + */ +static u_cond gSendDataCond = NULL; + +void CAInitializeMutex() +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + u_mutex_init(); + if (NULL == gMutexIsMulticastServerStarted) + { + gMutexIsMulticastServerStarted = u_mutex_new(); + } + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); +} + +int CAWIFIRegisterNetworkNotifications(CANetworkChangeCallback netCallback) +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + + if (netCallback != NULL) + { + CAInitializeWIFIAdapter(); + CASetWIFINetworkChangeCallback(netCallback); + } + else + { + CADeinitializeWIFIAdapter(); + } + + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CAInitializeQueueHandles() +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gSendQueueHandle)) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Send queue Handle"); + return CA_STATUS_FAILED; + } + gSendDataCond = u_cond_new(); + CASetSendQueueHandle(gSendQueueHandle, CA_TRUE, gSendDataCond); + + if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gRecvQueueHandle)) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Receive queue Handle"); + return CA_STATUS_FAILED; + } + CASetRecvQueueHandle(gRecvQueueHandle); + return CA_STATUS_OK; + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); +} + +void CADeinitializeSendQueueHandle() +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + CASetSendQueueHandle(NULL, CA_FALSE, NULL); + CAAdapterTerminateMessageQueue(gSendQueueHandle); + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); +} + +void CADeinitializeRecvQueueHandle() +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + CAAdapterTerminateMessageQueue(gRecvQueueHandle); + CASetRecvQueueHandle(NULL); + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); +} + +#if 0 /* Skip Queue */ +void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback) +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + gNetworkPacketCallback = callback; + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); +} +#endif //#if 0 +CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback, + CANetworkPacketReceivedCallback networkPacketCallback, CANetworkChangeCallback netCallback, + u_thread_pool_t handle) +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG, + "Invalid argument : registerCallback is NULL"); + VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG, + "Invalid argument : networkPacketCallback is NULL"); + VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "Invalid argument : netCallback is NULL"); + + CAConnectivityHandler_t wifiHandler; + wifiHandler.startAdapter = CAStartWIFI; + wifiHandler.startListenServer = CAStartWIFIListeningServer; + wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer; + wifiHandler.sendData = CASendWIFIUnicastData; + wifiHandler.sendDataToAll = CASendWIFIMulticastData; + wifiHandler.startNotifyServer = CAStartWIFINotifyRecvServers; + wifiHandler.sendNotification = CASendWIFINotification; + wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation; + wifiHandler.readData = CAReadWIFIData; + wifiHandler.stopAdapter = CAStopWIFI; + wifiHandler.terminate = CATerminateWIfI; + registerCallback(wifiHandler, CA_WIFI); + + CASetWIFINetworkPacketCallback(networkPacketCallback); + CAWIFIRegisterNetworkNotifications(netCallback); + CAInitializeMutex(); + CAInitializeServerMutex(); + CASetThreadHandle(handle); + CASetMulticastData(CA_MULTICAST_IP, CA_MCAST_PORT); + + if (CA_STATUS_OK != CAInitializeQueueHandles()) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Queue Handle"); + return CA_STATUS_FAILED; + } + if (CA_STATUS_OK != CAStartSendDataThread(handle)) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start Send Data Thread"); + return CA_STATUS_FAILED; + } + + 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; + + CASetIsStartServerInvoked(); + CABool_t retVal = CAIsWIFIConnected(); + if (retVal == CA_FALSE) + { + OIC_LOG(INFO, WIFI_ADAPTER_TAG, "WIFI is not Connected"); + return ret; + } + + // 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 == 1) + { + OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, + "Failed to Start Listening Server, Already Started! Return code[%d]", + CA_SERVER_STARTED_ALREADY); + return CA_SERVER_STARTED_ALREADY; + } + + CABool_t retVal = CAIsWIFIConnected(); + if (retVal == CA_FALSE) + { + OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, + "Failed to Start Listening Server, WIFI is not Connected! Return code[%d]", + CA_ADAPTER_NOT_ENABLED); + return CA_ADAPTER_NOT_ENABLED; + } + + 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"); + u_mutex_lock(gMutexIsMulticastServerStarted); + gIsMulticastServerStarted = 1; + u_mutex_unlock(gMutexIsMulticastServerStarted); + } + + 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 == 1) + { + OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, + "Failed to Start Discovery Server, Already Started! Return code[%d]", + CA_SERVER_STARTED_ALREADY); + return CA_SERVER_STARTED_ALREADY; + } + + CABool_t retVal = CAIsWIFIConnected(); + if (retVal == CA_FALSE) + { + OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, + "Failed to Start Discovery Server, WIFI is not Connected! Return code[%d]", + CA_ADAPTER_NOT_ENABLED); + return CA_ADAPTER_NOT_ENABLED; + } + + 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"); + u_mutex_lock(gMutexIsMulticastServerStarted); + gIsMulticastServerStarted = 1; + u_mutex_unlock(gMutexIsMulticastServerStarted); + } + + 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, + "Invalid argument : remoteEndpoint is NULL", dataSize); + VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "Invalid argument : data is NULL", dataSize); + + if (dataLen <= 0) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Invalid argument : Data Length is 0"); + return dataSize; + + } + + if (NULL == gSendQueueHandle) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Queue Handle is not Initialized"); + return dataSize; + } + CAAdapterEnqueueMessage(gSendQueueHandle, remoteEndpoint, data, dataLen); + u_cond_signal(gSendDataCond); + + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); + return dataLen; +} + +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, "Invalid argument : data is NULL", dataSize); + + if (dataLength <= 0) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Invalid argument : Data Length is 0"); + return 0; + + } + + if (NULL == gSendQueueHandle) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Queue Handle is not Initialized"); + return dataSize; + } + CAAdapterEnqueueMessage(gSendQueueHandle, NULL, data, dataLength); + u_cond_signal(gSendDataCond); + + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); + return dataLength; +} + +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"); + + CABool_t retVal = CAIsWIFIConnected(); + if (retVal == CA_FALSE) + { + OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, + "Failed to get interface address, WIFI is not Connected! Return code[%d]", + CA_ADAPTER_NOT_ENABLED); + return CA_ADAPTER_NOT_ENABLED; + } + + VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "Invalid argument : info is NULL"); + char localIpAddress[CA_IPADDR_SIZE]; + int32_t localIpAddressLen = sizeof(localIpAddress); + + CAGetInterfaceAddress(localIpAddress, localIpAddressLen); + + // Create local endpoint using util function + (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, localIpAddress, "WiFi"); + if (NULL == (*info)) + { + OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint! Return code[%d]", + CA_MEMORY_ALLOC_FAILED); + return CA_MEMORY_ALLOC_FAILED; + } + + (*size) = 1; + + 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"); + if (NULL == gRecvQueueHandle) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "QueueHandle is NULL"); + return CA_STATUS_FAILED; + } + CAAdapterMessage_t *messageReceived; + if (CA_STATUS_OK != CAAdapterDequeueMessage(gRecvQueueHandle, &messageReceived)) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Dequeue Message failed"); + return CA_STATUS_FAILED; + } + + if (gNetworkPacketCallback && (NULL != messageReceived)) + { + gNetworkPacketCallback(messageReceived->remoteEndpoint, messageReceived->data, + messageReceived->dataLen); + } + + CAAdapterFreeMessage(messageReceived); + 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_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Unicast Server! Return code[%d]", + result); + return result; + } + CAUnsetIsStartServerInvoked(); + result = CAStopMulticastServer(); + if (result != CA_STATUS_OK) + { + OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Multicast Server! Return code[%d]", + result); + return result; + } + else + { + u_mutex_lock(gMutexIsMulticastServerStarted); + gIsMulticastServerStarted = 0; + u_mutex_unlock(gMutexIsMulticastServerStarted); + } + CADeinitializeRecvQueueHandle(); + CADeinitializeSendQueueHandle(); + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT"); + return CA_STATUS_OK; +} + +void CATerminateWIfI() +{ + OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN"); + CAResult_t result = CA_STATUS_FAILED; + + CASetWIFINetworkPacketCallback(NULL); + result = CAWIFIRegisterNetworkNotifications(NULL); + if (result != CA_STATUS_OK) + { + OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Unregister Network Notifications"); + } + 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/tizen/cawificlient.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c new file mode 100644 index 0000000..1417d79 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c @@ -0,0 +1,207 @@ +/****************************************************************** +* +* 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 "cawificlient.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "caadapterutils.h" + +/** + * @def WIFI_CLIENT_TAG + * @brief Logging tag for module name + */ +#define WIFI_CLIENT_TAG "WIFI_CLIENT" + +/** + * @var gClientSendQueueHandle + * @brief Queue Handle for send Data + */ +static CAAdapterMessageQueue_t *gClientSendQueueHandle = NULL; + +/** + * @var gSendDataFlag + * @brief Flag to check if Termination is Called + */ +static CABool_t gSendDataFlag = CA_FALSE; + +/** + * @var gClientSendDataCond + * @brief Condition for Send Data + */ +static u_cond gClientSendDataCond = NULL; + +/** + * @var gMulticastIP + * @brief Multicast IP address + */ +static char gMulticastIP[CA_IPADDR_SIZE]; + +/** + * @var gMulticastPort + * @brief Multicast Port + */ +static uint32_t gMulticastPort; + +/** + * @var gUnicastServerSocketDescClient + * @brief socket descriptor for unicast server + */ +static int gUnicastServerSocketDescClient = -1; + +void CASetUnicastSocketDescriptor(int unicastSocketDesc) +{ + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN"); + gUnicastServerSocketDescClient = unicastSocketDesc; + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT"); +} + +void CASetSendQueueHandle(CAAdapterMessageQueue_t *gSendQueueHandle, CABool_t flag, u_cond cond) +{ + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN"); + gClientSendQueueHandle = gSendQueueHandle; + gSendDataFlag = flag; + if (cond == NULL) + { + u_cond_signal(gClientSendDataCond); + } + gClientSendDataCond = cond; + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT"); +} + +void CASetMulticastData(char *mAddr, uint32_t mPort) +{ + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN"); + strncpy(gMulticastIP, mAddr, CA_IPADDR_SIZE - 1); + gMulticastPort = mPort; + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT"); +} + +CAResult_t CAStartSendDataThread(u_thread_pool_t threadHandle) +{ + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN"); + VERIFY_NON_NULL(threadHandle, WIFI_CLIENT_TAG, "Invalid argument : threadHandle is NULL"); + if (CA_STATUS_OK != u_thread_pool_add_task(threadHandle, (void *) CAStartThreadForSendData, + (void *) NULL)) + { + OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Failed to add task in thread pool"); + return CA_STATUS_FAILED; + } + return CA_STATUS_OK; + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT"); +} + +uint32_t CAWIFISendData(const char *remoteIpAddress, const uint32_t port, const char *data, + uint32_t dataLen, int16_t isMulticast) +{ + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN"); + + VERIFY_NON_NULL_RET(remoteIpAddress, WIFI_CLIENT_TAG, "Invalid argument : remoteIpAddress is NULL", + 0); + VERIFY_NON_NULL_RET(data, WIFI_CLIENT_TAG, "Invalid argument : data is NULL", 0); + + OIC_LOG_V(DEBUG, WIFI_CLIENT_TAG, "remoteIPAddress is %s", remoteIpAddress); + OIC_LOG_V(DEBUG, WIFI_CLIENT_TAG, "PortNumber is %d", port); + OIC_LOG_V(DEBUG, WIFI_CLIENT_TAG, "Data[%d] to send is %s", dataLen, data); + + uint32_t sendDataLength = 0; + + if (dataLen <= 0) + { + OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Invalid Arguemnet : Datalength is <= 0"); + return sendDataLength; + } + + if (-1 == gUnicastServerSocketDescClient) + { + OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running"); + return sendDataLength; + } + + struct sockaddr_in destAddr; + memset((char *)&destAddr, 0, sizeof(destAddr)); + destAddr.sin_family = AF_INET; + destAddr.sin_port = htons(port); + + // Conversion from ASCII format to Network format + if (inet_aton(remoteIpAddress, &destAddr.sin_addr) == 0) + { + OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Failed to convert from ASCII to Network Address"); + return sendDataLength; + } + + sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLen, 0, + (struct sockaddr *)&destAddr, sizeof(destAddr)); + if (sendDataLength == -1) + { + OIC_LOG_V(ERROR, WIFI_CLIENT_TAG, "Failed to Send Data, Error code: %s", strerror(errno)); + return 0; + } + + OIC_LOG_V(INFO, WIFI_CLIENT_TAG, "Sending data is successful, sent bytes[%d]", sendDataLength); + + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT"); + return sendDataLength; +} + +void *CAStartThreadForSendData() +{ + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN"); + if (NULL == gClientSendQueueHandle) + { + OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Queue Handle is NULL"); + return NULL; + } + + u_mutex sendDataMutex = u_mutex_new(); + CAAdapterMessage_t *message; + + while (gSendDataFlag) + { + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "Inside The while loop"); + u_mutex_lock(sendDataMutex); + u_cond_wait(gClientSendDataCond, sendDataMutex); + while (CA_STATUS_OK == CAAdapterDequeueMessage(gClientSendQueueHandle, &message)) + { + if (NULL != message->remoteEndpoint) + { + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "Send Unicast Data is called"); + CAWIFISendData(message->remoteEndpoint->addressInfo.IP.ipAddress, + message->remoteEndpoint->addressInfo.IP.port, message->data, message->dataLen, 0); + } + else + { + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "Send Multicast Data is called"); + CAWIFISendData(gMulticastIP, gMulticastPort, message->data, message->dataLen, 1); + } + CAAdapterFreeMessage(message); + } + u_mutex_unlock(sendDataMutex); + } + + OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT"); + return NULL; +} diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.h b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.h new file mode 100644 index 0000000..47d8e70 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.h @@ -0,0 +1,75 @@ +/****************************************************************** +* +* 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 cawificlient.h + * @brief This file contains the APIs for WiFi Client module + */ + +#ifndef _CA_WIFI_CLIENT_ +#define _CA_WIFI_CLIENT_ + +#include +#include "cacommon.h" +#include "logger.h" +#include "camessagequeue.h" +#include "uthreadpool.h" + +/** + * @brief API to Set the send queue handle + * @param gSendQueueHandle [IN] Queue Handle to Send Data + * @return - None + */ +void CASetSendQueueHandle(CAAdapterMessageQueue_t *gSendQueueHandle, CABool_t flag, u_cond cond); + +/** + * @brief API to Set the Multicast IP and Port Address + * @param mAddr [IN] Multicast IP + * @param mPort [IN] Multicast Port + * @return - None + */ +void CASetMulticastData(char *mAddr, uint32_t mPort); + +/** + * @brief API to Start the Thread for Send Unicast and Multicast Data + * @param threadHandle [IN] ThreadHandle to Add the task in Thread pool + * @return - None + */ +CAResult_t CAStartSendDataThread(u_thread_pool_t threadHandle); + +/** + * @brief To send Unicast or Multicast Data + * @param remoteIpAddress [IN] RemoteEndpoint IP Address + * @param port [IN] RemoteEndpoint Port Number + * @param data [IN] Data to be sent to the RemoteEndpoint + * @param dataLen [IN] Length of the data to be sent + * @param isMulticast [IN] Unicast/Multicast flag, 0 for Unicast and 1 for Multicast + * @return Return 0 on failure and length of data on success + */ +uint32_t CAWIFISendData(const char *remoteIpAddress, const uint32_t port, const char *data, + uint32_t dataLen, int16_t isMulticast); + +/** + * @brief API to Invoke SendData. + * @return - NULL + */ +void *CAStartThreadForSendData(); + +#endif // #ifndef _CA_WIFI_CLIENT_ \ No newline at end of file diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.c new file mode 100644 index 0000000..53271b3 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.c @@ -0,0 +1,231 @@ +/****************************************************************** +* +* 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 "cawifimonitor.h" +#include +#include +#include +#include +#include +#include +#include "logger.h" +#include "caadapterutils.h" +#include "cawifiadapter.h" +#include "cawifiserver.h" +#include "umutex.h" + +#define WIFI_MONITOR_TAG "WIFI_MONITOR" + +static int gIsStartServerCalled = 0; +static u_mutex gMutexIsStartServerCalled = NULL; +CANetworkChangeCallback gNetworkChangeCb = NULL; + +CAResult_t CAGetInterfaceAddress(char *address, int32_t addrLen) +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + VERIFY_NON_NULL(address, WIFI_MONITOR_TAG, "Invalid argument : address is NULL"); + if (addrLen < CA_IPADDR_SIZE) + { + OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "addrLen MUST be atleast %d", CA_IPADDR_SIZE); + return CA_STATUS_INVALID_PARAM; + } + + struct ifaddrs *interfaceAddr, *ifAddr; + int interfaceFamily, name; + + /* Getting All Interfaces*/ + if (getifaddrs(&interfaceAddr) == -1) + { + OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Failed to get interface list"); + return CA_STATUS_FAILED; + } + + for (ifAddr = interfaceAddr; ifAddr != NULL; ifAddr = ifAddr->ifa_next) + { + if (ifAddr->ifa_addr == NULL) + continue; + + /* Currently, check for wifi interface and get the IP Address */ + OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "interface name = %s", ifAddr->ifa_name); + if (0 == strncmp(ifAddr->ifa_name, "wlan0", strlen("wlan0"))) + { + interfaceFamily = ifAddr->ifa_addr->sa_family; + OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "interfaceFamily = %d", interfaceFamily); + + if (interfaceFamily == AF_INET || interfaceFamily == AF_INET6) + { + name = getnameinfo(ifAddr->ifa_addr, + (interfaceFamily == AF_INET) ? sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6), + address, CA_IPADDR_SIZE, + NULL, 0, NI_NUMERICHOST); + if (name != 0) + { + OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get IPAddress, Error code: %s", + strerror(errno)); + return CA_STATUS_FAILED; + } + OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "interface name = %s", address); + break; + } + } + } + freeifaddrs(interfaceAddr); + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CAInitializeWIFIAdapter() +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + wifi_initialize(); + gMutexIsStartServerCalled = u_mutex_new(); + wifi_error_e ret = WIFI_ERROR_INVALID_PARAMETER; + wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL); + ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL); + if (ret != WIFI_ERROR_NONE) + { + OIC_LOG(ERROR, WIFI_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed"); + return CA_STATUS_FAILED; + } + else + { + OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_set_connection_state_changed_cb sucess"); + } + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CADeinitializeWIFIAdapter() +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + wifi_error_e ret = WIFI_ERROR_INVALID_PARAMETER; + wifi_unset_device_state_changed_cb(); + ret = wifi_unset_connection_state_changed_cb(); + if (ret != WIFI_ERROR_NONE) + { + OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed"); + } + else + { + OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_device_state_changed_cb success"); + } + wifi_deinitialize(); + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); + return CA_STATUS_OK; +} + +CABool_t CAIsWIFIConnected() +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + wifi_connection_state_e connection_state; + int retVal = wifi_get_connection_state(&connection_state); + if (retVal != WIFI_ERROR_NONE) + { + OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Failed to get the Connection State"); + return CA_FALSE; + } + if (connection_state == WIFI_CONNECTION_STATE_DISCONNECTED) + { + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "WIFI is not Connected"); + return CA_FALSE; + } + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "WIFI is Connected"); + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); + return CA_TRUE; +} + +void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap, void *userData) +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + if (state == WIFI_CONNECTION_STATE_ASSOCIATION + || WIFI_CONNECTION_STATE_CONFIGURATION == state) + { + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Connection is in Association State"); + return; + } + CANetworkStatus_t nwConnectivityStatus = CA_INTERFACE_DOWN; + CALocalConnectivity_t *localEndpoint = NULL; + uint32_t size = 0; + /* If Wifi is connected, then get the latest IP from the WIFI Interface */ + if (WIFI_CONNECTION_STATE_CONNECTED == state) + { + if (gIsStartServerCalled) + { + CAStartWIFI(); + } + nwConnectivityStatus = CA_INTERFACE_UP; + CAGetWIFIInterfaceInformation(&localEndpoint, &size); + } + else + { + localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, "", NULL); + CAStopUnicastServer(); + } + + gNetworkChangeCb(localEndpoint, nwConnectivityStatus); + + CAAdapterFreeLocalEndpoint(localEndpoint); + + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); + return; +} + +void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData) +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + + if (WIFI_DEVICE_STATE_ACTIVATED == state) + { + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Activated State"); + } + else + { + CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL); + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Deactivated State"); + } + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); + return; +} + +void CASetIsStartServerInvoked() +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + u_mutex_lock(gMutexIsStartServerCalled); + gIsStartServerCalled = 1; + u_mutex_unlock(gMutexIsStartServerCalled); + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); +} + +void CAUnsetIsStartServerInvoked() +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + u_mutex_lock(gMutexIsStartServerCalled); + gIsStartServerCalled = 0; + u_mutex_unlock(gMutexIsStartServerCalled); + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); +} + +void CASetWIFINetworkChangeCallback(CANetworkChangeCallback netCallback) +{ + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN"); + gNetworkChangeCb = netCallback; + OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT"); +} \ No newline at end of file diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.h b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.h new file mode 100644 index 0000000..d5fc6bf --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.h @@ -0,0 +1,95 @@ +/****************************************************************** +* +* 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 cawifiutils.h + * @brief This file contains the APIs for WiFi Specific Calls + */ + +#ifndef _CA_WIFI_MONITOR_ +#define _CA_WIFI_MONITOR_ + +#include +#include +#include "caadapterinterface.h" +#include "cacommon.h" + +/** + * @brief To send Unicast or Multicast Data + * @param remoteIpAddress [OUT] IP Address of the device + * @param port [IN] Length of the IP address + * @return Return Error Code + */ +CAResult_t CAGetInterfaceAddress(char *address, int32_t addrLen); + +/** + * @brief To Initialize the WIFI Adapter + * @return Return Error Code + */ +CAResult_t CAInitializeWIFIAdapter(); + +/** + * @brief To Deinitialize WIFI Adapter + * @return Return Error Code + */ +CAResult_t CADeinitializeWIFIAdapter(); + +/** + * @brief To Check if WIFI is connected + * @return Return True or False + */ +CABool_t CAIsWIFIConnected(); + +/** + * @brief WIFI connection state Changed Callback + * @param state [IN] Connection state of the Device + * @param ap [IN] Access Point handler + * @param userData [IN] User Data Passed on Setting the Callback + * @return Return None + */ +void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap, void *userData); + +/** + * @brief WIFI Device state Changed Callback + * @param state [IN] Device state + * @param userData [IN] User Data Passed on Setting the Callback + * @return Return None + */ +void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData); + +/** + * @brief To set the IsStartServerCalled global variable + * @return Return None + */ +void CASetIsStartServerInvoked(); + +/** + * @brief To unset the IsStartServerCalled global variable + * @return Return None + */ +void CAUnsetIsStartServerInvoked(); + +/** + * @brief API to set Network Changed callback to upper layer. + * @param netCallback - upper layer callback function to notify the change in WIFI connection state. + * @return - Error Code + */ +void CASetWIFINetworkChangeCallback(CANetworkChangeCallback netCallback); +#endif \ No newline at end of file diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c new file mode 100644 index 0000000..fef7d24 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c @@ -0,0 +1,717 @@ +/****************************************************************** +* +* 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 "cawifiserver.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "caadapterutils.h" +#include "umutex.h" + +/** + * @def WIFI_SERVER_TAG + * @brief Logging tag for module name + */ +#define WIFI_SERVER_TAG "WIFI_SERVER" + +/** + * @def CA_BUFFER_LEN + * @brief Length of buffer for receiving data + */ +#define CA_BUFFER_LEN 512 // Max length of buffer + +/** + * @def CA_UDP_BIND_RETRY_COUNT + * @brief Retry count in case of socket bind failure. + */ +#define CA_UDP_BIND_RETRY_COUNT 10 + + +/** + * @var gUnicastServerSocketDescriptor + * @brief socket descriptor for unicast server + */ +static int gUnicastServerSocketDescriptor = -1; + +/** + * @var gMutexUnicastServerSocketDescriptor + * @brief Mutex for socket descriptor for unicast server + */ +static u_mutex gMutexUnicastServerSocketDescriptor = NULL; +/** + * @var gMulticastServerSocketDescriptor + * @brief socket descriptor for multicast server + */ +static int gMulticastServerSocketDescriptor = -1; + +/** + * @var gMutexMulticastServerSocketDescriptor + * @brief Mutex for socket descriptor for Multicast server + */ +static u_mutex gMutexMulticastServerSocketDescriptor = NULL; + +/** + * @var gThreadPool + * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter + */ +static u_thread_pool_t gThreadPool = NULL; + +/** + * @var gMReq + * @brief ip_mreq structure passed to join a multicast group + */ +static struct ip_mreq gMReq; + +/** + * @var gStopUnicast + * @brief Flag to control the Receive Unicast Data Thread + */ +static bool gStopUnicast = false; + +/** + * @var gMutexStopUnicast + * @brief Mutex for gStopUnicast + */ +static u_mutex gMutexStopUnicast = NULL; + +/** + * @var gStopMulticast + * @brief Flag to control the Receive Multicast Data Thread + */ +static bool gStopMulticast = false; + +/** + * @var gMutexStopMulticast + * @brief Mutex for gStopMulticast + */ +static u_mutex gMutexStopMulticast = NULL; + +/** + * @var gServerRecvQueueHandle + * @brief Queue Handle for Receive Data + */ +static CAAdapterMessageQueue_t *gServerRecvQueueHandle = NULL; + +/* Skip Queue */ +/** + * @var gNetworkPacketCallback + * @brief receiving request response callback + */ +static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL; + +void CAInitializeServerMutex() +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + gMutexUnicastServerSocketDescriptor = u_mutex_new(); + gMutexMulticastServerSocketDescriptor = u_mutex_new(); + gMutexStopUnicast = u_mutex_new(); + gMutexStopMulticast = u_mutex_new(); + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); +} + +void CASetRecvQueueHandle(CAAdapterMessageQueue_t *recvQueueHandle) +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + gServerRecvQueueHandle = recvQueueHandle; + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); +} + +void CASetThreadHandle(u_thread_pool_t handle) +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + gThreadPool = handle; + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); +} + +CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port) +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "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"); + + struct sockaddr_in sockAddr; + int16_t isBound = 0; + int16_t i = 0; + int16_t result = 0; + int16_t status = 0; + int setOptionOn = 1; + u_mutex_lock(gMutexStopUnicast); + gStopUnicast = false; + u_mutex_unlock(gMutexStopUnicast); + + u_mutex_lock(gMutexUnicastServerSocketDescriptor); + // Create a UDP socket + if ((gUnicastServerSocketDescriptor = 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(gMutexUnicastServerSocketDescriptor); + return CA_SOCKET_OPERATION_FAILED; + } + + // Make the socket non-blocking + if ((status = fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK)) < 0) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "fcntl to make the socket non-blocking failed, Error code: %s", + strerror(errno)); + close(gUnicastServerSocketDescriptor); + gUnicastServerSocketDescriptor = -1; + u_mutex_unlock(gMutexUnicastServerSocketDescriptor); + return CA_STATUS_FAILED; + } + + OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success"); + + if ((result = setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR, + (char *) &setOptionOn, + sizeof(setOptionOn))) < 0) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR! Error code: %s", + strerror(errno)); + close(gUnicastServerSocketDescriptor); + gUnicastServerSocketDescriptor = -1; + u_mutex_unlock(gMutexUnicastServerSocketDescriptor); + return CA_SOCKET_OPERATION_FAILED; + } + + // zero out the structure + memset((char *) &sockAddr, 0, sizeof(sockAddr)); + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(*port); + + // TODO: Assign the Particular Address on Multiple Interfaces + sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); + + // Trying for bind in a loop + for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++) + { + // bind socket to port + if (bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr, sizeof(sockAddr)) == -1) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ", strerror(errno)); + continue; + } + isBound = 1; + break; + } + + if (!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; + } + + OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success"); + + socklen_t len; // = sizeof(sin); + + if (getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len) == -1) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to getsockname, Error code: %s", strerror(errno)); + } + else + { + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "port number %d", ntohs(sockAddr.sin_port)); + *port = ntohs(sockAddr.sin_port); + } + + /** + * 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 *) CAReceiveThreadForUnicast, + (void *) NULL)) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!"); + + close(gUnicastServerSocketDescriptor); + gUnicastServerSocketDescriptor = -1; + u_mutex_unlock(gMutexUnicastServerSocketDescriptor); + return CA_STATUS_FAILED; + } + u_mutex_unlock(gMutexUnicastServerSocketDescriptor); + + // Set Unicast Socket Descriptor in cawificlient + CASetUnicastSocketDescriptor(gUnicastServerSocketDescriptor); + + OIC_LOG(INFO, WIFI_SERVER_TAG, "thread_pool_add_task done"); + OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Started Successfully"); + + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CAStartMulticastServer(const char *mcastAddress, const char *localAddress, + int16_t *port) +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + + if (gMulticastServerSocketDescriptor != -1) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is Started Already! Return Code[%d]", + CA_SERVER_STARTED_ALREADY); + return CA_SERVER_STARTED_ALREADY; + } + + VERIFY_NON_NULL(mcastAddress, WIFI_SERVER_TAG, "Invalid argument : mcastAddress is NULL"); + VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Invalid argument : localAddress is NULL"); + VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Invalid argument : port is NULL"); + + // Create a datagram socket on which to recv/send. + struct sockaddr_in sockAddr; + int16_t result = 0; + int16_t i = 0; + int16_t status = 0; + + int setOptionOn = 1; + u_mutex_lock(gMutexStopMulticast); + gStopMulticast = false; + u_mutex_unlock(gMutexStopMulticast); + + u_mutex_lock(gMutexMulticastServerSocketDescriptor); + + // 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; + } + + // Make the socket non-blocking + if ((status = fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK)) < 0) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "fcntl to make the socket non-blocking failed, 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"); + + if ((result = setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR, + (char *) &setOptionOn, + sizeof(setOptionOn))) < 0) + { + 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; + } + + // zero out the structure + memset((char *) &sockAddr, 0, sizeof(sockAddr)); + + sockAddr.sin_family = AF_INET; + sockAddr.sin_port = htons(*port); + // TODO: Assign the Particular Address on Multiple Interfaces + sockAddr.sin_addr.s_addr = htonl(INADDR_ANY); + + // Trying for bind in a loop + for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++) + { + // bind socket to multicast port + if (bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr, sizeof(sockAddr)) == -1) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again...", strerror(errno)); + continue; + } + result = 1; + break; + } + if (!result) + { + 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; + } + + OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success"); + + socklen_t len = sizeof(sockAddr); + + if (getsockname(gMulticastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len) == -1) + { + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "getsockname failed, Error code: %s", strerror(errno)); + } + else + { + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "port number %d\n", ntohs(sockAddr.sin_port)); + *port = ntohs(sockAddr.sin_port); + } + + // add membership to receiving socket (join group) + memset(&gMReq, 0, sizeof(struct ip_mreq)); + gMReq.imr_interface.s_addr = htonl(INADDR_ANY); + inet_aton(mcastAddress, &gMReq.imr_multiaddr); + + if ((result = setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (char *) &gMReq, + sizeof(struct ip_mreq))) < 0) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "setsockopt API for IP_ADD_MEMBERSHIP failed, Error code: %s\n", + strerror(errno)); + close(gMulticastServerSocketDescriptor); + gMulticastServerSocketDescriptor = -1; + u_mutex_unlock(gMutexMulticastServerSocketDescriptor); + return CA_SOCKET_OPERATION_FAILED; + } + + /** + * 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!"); + + close(gMulticastServerSocketDescriptor); + gMulticastServerSocketDescriptor = -1; + u_mutex_unlock(gMutexMulticastServerSocketDescriptor); + return CA_STATUS_FAILED; + } + + 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, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CAStopUnicastServer() +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + u_mutex_lock(gMutexUnicastServerSocketDescriptor); + + if (gUnicastServerSocketDescriptor == -1) + { + OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server is not yet Started"); + u_mutex_unlock(gMutexUnicastServerSocketDescriptor); + return CA_SERVER_NOT_STARTED; + } + u_mutex_lock(gMutexStopUnicast); + gStopUnicast = true; + + // close the socket + int16_t ret = close(gUnicastServerSocketDescriptor); + + if (ret == -1) + { + 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; + } + + u_mutex_unlock(gMutexStopUnicast); + gUnicastServerSocketDescriptor = -1; + // UnSet Unicast Socket Descriptor in cawificlient + CASetUnicastSocketDescriptor(gUnicastServerSocketDescriptor); + u_mutex_unlock(gMutexUnicastServerSocketDescriptor); + + OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Stopped Successfully"); + + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); + return CA_STATUS_OK; +} + +CAResult_t CAStopMulticastServer() +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + + u_mutex_lock(gMutexMulticastServerSocketDescriptor); + + if (gMulticastServerSocketDescriptor == -1) + { + OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server is not yet Started"); + u_mutex_unlock(gMutexMulticastServerSocketDescriptor); + return CA_SERVER_NOT_STARTED; + } + + u_mutex_lock(gMutexStopMulticast); + gStopMulticast = true; + + // leave the group after you are done + int16_t result = setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP, + (char *)&gMReq, + sizeof(struct ip_mreq)); + if (result < 0) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "cannot leave multicast group, Error code: %s\n", + strerror(errno)); + } + + // close the socket + result = close(gMulticastServerSocketDescriptor); + if (result == -1) + { + 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); + + 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; +} + +void *CAReceiveThreadForUnicast(void *data) +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + if (NULL == gServerRecvQueueHandle) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "QueueHandle is not Initialized"); + return NULL; + } + + char *buf = (char *) OICMalloc (CA_BUFFER_LEN); + if (NULL == buf) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed"); + return NULL; + } + uint32_t recvLen; + int32_t ret = 0; + struct sockaddr_in siOther; + socklen_t sLen = sizeof(siOther); + fd_set reads; + struct timeval timeout; + CARemoteEndpoint_t *endPointUnicast = (CARemoteEndpoint_t *) OICMalloc (sizeof(CARemoteEndpoint_t)); + if (NULL == endPointUnicast) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed"); + return NULL; + } + memset (endPointUnicast, 0, sizeof(CARemoteEndpoint_t)); + + + + // keep listening for data + while (!gStopUnicast) + { + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Waiting for data.."); + + memset(buf, 0, sizeof(char) * CA_BUFFER_LEN); + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + FD_ZERO(&reads); + // Use select for polling the socket fd + FD_SET(gUnicastServerSocketDescriptor, &reads); + + ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout); + if ( ret < 0) + { + OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select API failed"); + continue; + } + if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads)) + { + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "No data to read"); + continue; + } + + + // try to receive some data + if ((recvLen = recvfrom(gUnicastServerSocketDescriptor, buf, CA_BUFFER_LEN, 0, + (struct sockaddr *) &siOther, &sLen)) == -1) + { + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s\n", strerror(errno)); + continue; + } + else if (0 == recvLen) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast socket is shutdown, returning from thread\n"); + return (void *) NULL; + } + + // print details of the client/peer and the data received + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n", inet_ntoa(siOther.sin_addr), + ntohs(siOther.sin_port)); + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s, DataLength: %d\n", buf, sizeof(buf)); + + endPointUnicast->resourceUri = NULL; // will be filled by upper layer + strncpy((char *)endPointUnicast->addressInfo.IP.ipAddress, inet_ntoa(siOther.sin_addr), + CA_IPADDR_SIZE); + endPointUnicast->addressInfo.IP.port = ntohs(siOther.sin_port); + endPointUnicast->connectivityType = CA_WIFI; + + // Enqueue the Received Message in the Queue +#if 0 /* Skip Queue */ + CAAdapterEnqueueMessage(gServerRecvQueueHandle, &endPointUnicast, buf, recvLen); +#else + if (gNetworkPacketCallback) + { + gNetworkPacketCallback(endPointUnicast, buf, recvLen); + } +#endif //#if 0 + } + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "stopUnicastServer is called, Breaking from while loop\n"); + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); + return (void *) NULL; +} + +void *CAReceiveThreadForMulticast(void *data) +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + + if (NULL == gServerRecvQueueHandle) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "QueueHandle is not Initialized"); + return NULL; + } + + char *buf = (char *) OICMalloc (CA_BUFFER_LEN); + if (NULL == buf) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed"); + return NULL; + } + int recvLen; + struct sockaddr_in siOther; + int32_t ret = 0; + socklen_t sLen = sizeof(siOther); + fd_set reads; + struct timeval timeout; + CARemoteEndpoint_t *endPointMulticast = (CARemoteEndpoint_t *) OICMalloc (sizeof( + CARemoteEndpoint_t)); + if (NULL == endPointMulticast) + { + OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed"); + return NULL; + } + memset (endPointMulticast, 0, sizeof(CARemoteEndpoint_t)); + + + // keep listening for data + while (!gStopMulticast) + { + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Waiting for data...\n"); + + memset(buf, 0, sizeof(char) * CA_BUFFER_LEN); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + FD_ZERO(&reads); + // Use select for polling the socket fd + FD_SET(gMulticastServerSocketDescriptor, &reads); + + ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout); + if ( ret < 0) + { + OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select API failed"); + continue; + } + if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads)) + { + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "No data to read"); + continue; + } + + // try to receive some data + if ((recvLen = recvfrom(gMulticastServerSocketDescriptor, buf, CA_BUFFER_LEN, 0, + (struct sockaddr *) &siOther, &sLen)) == -1) + { + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s\n", strerror(errno)); + continue; + } + else if (0 == recvLen) + { + OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown, returning from thread\n"); + return (void *) NULL; + } + + // print details of the client/peer and the data received + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n", + inet_ntoa(siOther.sin_addr), ntohs(siOther.sin_port)); + OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n", buf, recvLen); + + endPointMulticast->resourceUri = NULL; // will be filled by upper layer + strncpy((char *)endPointMulticast->addressInfo.IP.ipAddress, inet_ntoa(siOther.sin_addr), + strlen(inet_ntoa(siOther.sin_addr))); + endPointMulticast->addressInfo.IP.port = ntohs(siOther.sin_port); + endPointMulticast->connectivityType = CA_WIFI; + +#if 0 /* Skip Queue */ + // Enqueue the Received Message in the Queue + CAAdapterEnqueueMessage(gServerRecvQueueHandle, &endPointMulticast, buf, recvLen); +#else + if (gNetworkPacketCallback) + { + gNetworkPacketCallback(endPointMulticast, buf, recvLen); + } +#endif //#if 0 + } + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "stopMulticastServer is called, Breaking from while loop\n"); + + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); + return (void *) NULL; +} + +/* Skip Queue */ +void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback) +{ + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN"); + gNetworkPacketCallback = callback; + OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT"); +} diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.h b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.h new file mode 100644 index 0000000..1a619e6 --- /dev/null +++ b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.h @@ -0,0 +1,104 @@ +/****************************************************************** +* +* 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 cawifiserver.h + * @brief This file contains the APIs for WiFi Server module + */ + +#ifndef _CA_WIFI_SERVER_H_ +#define _CA_WIFI_SERVER_H_ + +#include "caadapterinterface.h" +#include "logger.h" +#include "uthreadpool.h" +#include "camessagequeue.h" + +/** + * @brief API to Initialize Server Mutex + * @return - None + */ +void CAInitializeServerMutex(); + +/** + * @brief API to Set the Receive queue handle + * @param recvQueueHandle [IN] Queue Handle to Receive Data + * @return - None + */ +void CASetRecvQueueHandle(CAAdapterMessageQueue_t *recvQueueHandle); + +/** + * @brief API to Get thread pool handle initialized in interface sample. + * @return - None + */ +void CASetThreadHandle(u_thread_pool_t gThreadPool); + +/** + * @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); + +/** + * @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); + +/** + * @brief API to stop unicast server. + * @return - Error Code + */ +CAResult_t CAStopUnicastServer(); + +/** + * @brief API to stop multicast server. + * @return - Error Code + */ +CAResult_t CAStopMulticastServer(); + +/** + * @brief API to receive the data in unicast server socket thread. + * @param data - data received in server from lower layer. + * @return - NULL + */ +void *CAReceiveThreadForUnicast(void *data); + +/** + * @brief API to receive the data in multicast server socket thread. + * @param data - data received in server from lower layer. + * @return - NULL + */ +void *CAReceiveThreadForMulticast(void *data); +/* Skip Queue */ +/** + * @brief API to set request response callback to upper layer. + * @param RequestResponseCallback - upper layer callback function to pass the data received in the server. + * @return - Error Code + */ +void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback); + +#endif // #ifndef _CA_WIFI_SERVER_H_ diff --git a/resource/csdk/connectivity/unittests/linux/sample1_unittest.cc b/resource/csdk/connectivity/unittests/linux/sample1_unittest.cc index 6d8be53..c58492d 100644 --- a/resource/csdk/connectivity/unittests/linux/sample1_unittest.cc +++ b/resource/csdk/connectivity/unittests/linux/sample1_unittest.cc @@ -5,17 +5,17 @@ using namespace std; -void request_handler(CARemoteEndpoint* object, CARequestInfo* requestInfo); -void response_handler(CARemoteEndpoint* object, CAResponseInfo* responseInfo); +void request_handler(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo); +void response_handler(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo); -void request_handler(CARemoteEndpoint* object, CARequestInfo* requestInfo) +void request_handler(CARemoteEndpoint_t* object, CARequestInfo_t* requestInfo) { cout << "request_handler, uri : " << (object != NULL) ? object->resourceUri : ""; cout << ", data : " << (requestInfo != NULL) ? requestInfo->info.payload : ""; cout << endl; } -void response_handler(CARemoteEndpoint* object, CAResponseInfo* responseInfo) +void response_handler(CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo) { cout << "response_handler, uri : " << (object != NULL) ? object->resourceUri : ""; cout << ", data : " << (responseInfo != NULL) ? responseInfo->info.payload : ""; @@ -23,11 +23,11 @@ void response_handler(CARemoteEndpoint* object, CAResponseInfo* responseInfo) } char* uri; -CARemoteEndpoint* tempRep = NULL; -CARequestInfo requestInfo; -CAInfo responseData; -CAResponseInfo responseInfo; -CAToken tempToken; +CARemoteEndpoint_t* tempRep = NULL; +CARequestInfo_t requestInfo; +CAInfo_t responseData; +CAResponseInfo_t responseInfo; +CAToken_t tempToken; int main(int argc, char **argv) { @@ -78,7 +78,7 @@ TEST(RegisterHandlerTest, TC_05_Positive_01) // check return value TEST(CreateRemoteEndpointTest, TC_06_Positive_01) { - uri = (char *) "referenceUri"; + uri = (char *) "123.123.123.123:1234/b/light"; EXPECT_EQ(CA_STATUS_OK, CACreateRemoteEndpoint(uri, &tempRep)); @@ -88,7 +88,7 @@ TEST(CreateRemoteEndpointTest, TC_06_Positive_01) // check remoteEndpoint and values of remoteEndpoint TEST(CreateRemoteEndpointTest, TC_07_Positive_02) { - uri = (char *) "referenceUri"; + uri = (char *) "123.123.123.123:1234/b/light"; CACreateRemoteEndpoint(uri, &tempRep); EXPECT_TRUE(tempRep != NULL); @@ -129,7 +129,7 @@ TEST(CreateRemoteEndpointTest, TC_09_Nagative_02) // check destroyed remoteEndpoint TEST(DestroyRemoteEndpointTest, TC_10_Positive_01) { - uri = (char *) "referenceUri"; + uri = (char *) "123.123.123.123:1234/b/light"; CACreateRemoteEndpoint(uri, &tempRep); CADestroyRemoteEndpoint(tempRep); @@ -163,7 +163,7 @@ TEST(DestroyTokenTest, TC_12_Positive_01) TEST(FindResourceTest, TC_13_Positive_01) { CARegisterHandler(request_handler, response_handler); - uri = (char *) "referenceUri"; + uri = (char *) "123.123.123.123:1234/b/light"; EXPECT_EQ(CA_STATUS_OK, CAFindResource(uri)); } @@ -172,15 +172,15 @@ TEST(FindResourceTest, TC_14_Nagative_01) { CARegisterHandler(request_handler, response_handler); uri = NULL; - EXPECT_EQ(CA_SEND_FAILED, CAFindResource(uri)); + EXPECT_EQ(CA_STATUS_FAILED, CAFindResource(uri)); } // CASendRequest TC // check return value TEST(SendRequestTest, TC_15_Positive_01) { - uri = (char *) "referenceUri"; - memset(&requestInfo, 0, sizeof(CARequestInfo)); + uri = (char *) "123.123.123.123:1234/b/light"; + memset(&requestInfo, 0, sizeof(CARequestInfo_t)); CACreateRemoteEndpoint(uri, &tempRep); CAGenerateToken(&tempToken); requestInfo.method = CA_GET; @@ -197,14 +197,14 @@ TEST(SendRequestTest, TC_15_Positive_01) TEST(SendRequestTest, TC_16_Nagative_01) { uri = NULL; - memset(&requestInfo, 0, sizeof(CARequestInfo)); + memset(&requestInfo, 0, sizeof(CARequestInfo_t)); CACreateRemoteEndpoint(uri, &tempRep); CAGenerateToken(&tempToken); requestInfo.method = CA_GET; requestInfo.info.token = tempToken; requestInfo.info.payload = (char *) "request payload"; - EXPECT_EQ(CA_SEND_FAILED, CASendRequest(tempRep, &requestInfo)); + EXPECT_EQ(CA_STATUS_FAILED, CASendRequest(tempRep, &requestInfo)); CADestroyToken(tempToken); CADestroyRemoteEndpoint(tempRep); @@ -214,16 +214,16 @@ TEST(SendRequestTest, TC_16_Nagative_01) // check return value TEST(SendResponseTest, TC_17_Positive_01) { - uri = (char *) "referenceUri"; + uri = (char *) "123.123.123.123:1234/b/light"; CACreateRemoteEndpoint(uri, &tempRep); - memset(&responseData, 0, sizeof(CAInfo)); + memset(&responseData, 0, sizeof(CAInfo_t)); CAGenerateToken(&tempToken); responseData.token = tempToken; responseData.payload = (char *) "response payload"; - memset(&responseInfo, 0, sizeof(CAResponseInfo)); - responseInfo.result = CA_SUCCESS; + memset(&responseInfo, 0, sizeof(CAResponseInfo_t)); + responseInfo.result = CA_VALID; responseInfo.info = responseData; EXPECT_EQ(CA_STATUS_OK, CASendResponse(tempRep, &responseInfo)); @@ -238,16 +238,16 @@ TEST(SendResponseTest, TC_18_Nagative_01) uri = NULL; CACreateRemoteEndpoint(uri, &tempRep); - memset(&responseData, 0, sizeof(CAInfo)); + memset(&responseData, 0, sizeof(CAInfo_t)); CAGenerateToken(&tempToken); responseData.token = tempToken; responseData.payload = (char *) "response payload"; - memset(&responseInfo, 0, sizeof(CAResponseInfo)); - responseInfo.result = CA_SUCCESS; + memset(&responseInfo, 0, sizeof(CAResponseInfo_t)); + responseInfo.result = CA_VALID; responseInfo.info = responseData; - EXPECT_EQ(CA_SEND_FAILED, CASendResponse(tempRep, &responseInfo)); + EXPECT_EQ(CA_STATUS_FAILED, CASendResponse(tempRep, &responseInfo)); CADestroyToken(tempToken); CADestroyRemoteEndpoint(tempRep); @@ -257,21 +257,19 @@ TEST(SendResponseTest, TC_18_Nagative_01) // check return value TEST(SendNotificationTest, TC_19_Positive_01) { - uri = (char *) "referenceUri"; + uri = (char *) "123.123.123.123:1234/b/light"; CACreateRemoteEndpoint(uri, &tempRep); - memset(&responseData, 0, sizeof(CAInfo)); - CAGenerateToken(&tempToken); - responseData.token = tempToken; - responseData.payload = (char *) "response payload"; + memset(&responseData, 0, sizeof(CAInfo_t)); + responseData.token = (char *) "client token"; + responseData.payload = (char *) "Temp Notification Data"; - memset(&responseInfo, 0, sizeof(CAResponseInfo)); - responseInfo.result = CA_SUCCESS; + memset(&responseInfo, 0, sizeof(CAResponseInfo_t)); + responseInfo.result = CA_CONTENT; responseInfo.info = responseData; - EXPECT_EQ(CA_NOT_SUPPORTED, CASendNotification(tempRep, &responseInfo)); + EXPECT_EQ(CA_STATUS_OK, CASendNotification(tempRep, &responseInfo)); - CADestroyToken(tempToken); CADestroyRemoteEndpoint(tempRep); } @@ -281,18 +279,16 @@ TEST(SendNotificationTest, TC_20_Nagative_01) uri = NULL; CACreateRemoteEndpoint(uri, &tempRep); - memset(&responseData, 0, sizeof(CAInfo)); - CAGenerateToken(&tempToken); - responseData.token = tempToken; - responseData.payload = (char *) "response payload"; + memset(&responseData, 0, sizeof(CAInfo_t)); + responseData.token = (char *) "client token"; + responseData.payload = (char *) "Temp Notification Data"; - memset(&responseInfo, 0, sizeof(CAResponseInfo)); - responseInfo.result = CA_SUCCESS; + memset(&responseInfo, 0, sizeof(CAResponseInfo_t)); + responseInfo.result = CA_CONTENT; responseInfo.info = responseData; - EXPECT_EQ(CA_NOT_SUPPORTED, CASendNotification(tempRep, &responseInfo)); + EXPECT_EQ(CA_STATUS_FAILED, CASendNotification(tempRep, &responseInfo)); - CADestroyToken(tempToken); CADestroyRemoteEndpoint(tempRep); } @@ -300,21 +296,45 @@ TEST(SendNotificationTest, TC_20_Nagative_01) // check return value TEST(AdvertiseResourceTest, TC_21_Positive_01) { - CAURI uri = (char *) "resourceUri"; - CAHeaderOption* options = NULL; - uint8_t numOptions = 0; - - EXPECT_EQ(CA_NOT_SUPPORTED, CAAdvertiseResource(uri, options, numOptions)); + uri = (char *) "123.123.123.123:1234/b/light"; + int optionNum = 1; + char* optionData; + CAHeaderOption_t* headerOpt; + headerOpt = (CAHeaderOption_t*) malloc(sizeof(CAHeaderOption_t) * optionNum); + memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum); + + int i; + for(i = 0 ; i < optionNum ; i++) + { + int optionID = 2; + headerOpt[i].optionID = optionID; + optionData = (char *) "aaa"; + memcpy(headerOpt[i].optionData, optionData, strlen(optionData)); + headerOpt[i].optionLength = (uint16_t)strlen(optionData); + } + EXPECT_EQ(CA_STATUS_OK, CAAdvertiseResource(uri, headerOpt, (uint8_t)optionNum)); } -// check return value if token is NULL +// check return value if uri is NULL TEST(AdvertiseResourceTest, TC_22_Nagative_01) { - CAURI uri = NULL; - CAHeaderOption* options = NULL; - uint8_t numOptions = 0; - - EXPECT_EQ(CA_NOT_SUPPORTED, CAAdvertiseResource(uri, options, numOptions)); + uri = NULL; + int optionNum = 1; + char* optionData; + CAHeaderOption_t* headerOpt; + headerOpt = (CAHeaderOption_t*) malloc(sizeof(CAHeaderOption_t) * optionNum); + memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum); + + int i; + for(i = 0 ; i < optionNum ; i++) + { + int optionID = 2; + headerOpt[i].optionID = optionID; + optionData = (char *) "aaa"; + memcpy(headerOpt[i].optionData, optionData, strlen(optionData)); + headerOpt[i].optionLength = (uint16_t)strlen(optionData); + } + EXPECT_EQ(CA_STATUS_FAILED, CAAdvertiseResource(uri, headerOpt, (uint8_t)optionNum)); } // CASelectNewwork TC @@ -347,20 +367,12 @@ TEST(UnSelectNetworkTest, TC_26_Nagative_01) EXPECT_EQ(CA_NOT_SUPPORTED, CAUnSelectNetwork(20)); } -// CAGetNetworkInfomation TC -// check return value -TEST (GetNetworkInfomation, TC_27_Positive_01) -{ - CALocalConnectivity* info = NULL; - uint32_t* size = NULL; - - EXPECT_EQ(CA_NOT_SUPPORTED, CAGetNetworkInformation(&info, size)); -} - // CAHandlerRequestResponse TC // check return value -TEST (HandlerRequestResponseTest, TC_28_Positive_01) +TEST (HandlerRequestResponseTest, TC_27_Positive_01) { EXPECT_EQ(CA_STATUS_OK, CAHandleRequestResponse()); } + + diff --git a/resource/csdk/connectivity/unittests/tizen/tct/README.txt b/resource/csdk/connectivity/unittests/tizen/tct/README.txt new file mode 100644 index 0000000..a14099a --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/README.txt @@ -0,0 +1,9 @@ +TCT Unit tests for Tizen: +========================== +1. TCT tool should be setup in linux to execute these test cases. Please refer to "CoreAPI Test Manual.pptx" present in this folder. +2. OIC-Core and InterfaceAPIs should be built first. +3. Copy liboic to /core-api/src. +4. Copy packaging/core-liboic-tests.spec to /packaging. +5. Build oic test case project with "tctbuild build liboic". +6. Install test framework to device with "tctbuild install liboic". +7. Run tct tool with "tct-mgr". \ No newline at end of file diff --git a/resource/csdk/connectivity/unittests/tizen/tct/liboic/CMakeLists.txt b/resource/csdk/connectivity/unittests/tizen/tct/liboic/CMakeLists.txt new file mode 100644 index 0000000..e4474ca --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/CMakeLists.txt @@ -0,0 +1,31 @@ +SET(PKG_NAME "liboic") + +SET(EXEC_NAME "tct-${PKG_NAME}-core") +SET(RPM_NAME "core-${PKG_NAME}-tests") + +SET(CAPI_LIB "liboic") +SET(TC_SOURCES + #utc-liboic.c + wifi/utc-wifi-liboic.c + #bt/utc-bt-liboic.c +) + +#PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED +# ${CAPI_LIB} +#) +PKG_CHECK_MODULES(pkgs REQUIRED + capi-network-bluetooth capi-network-wifi com.samsung.oicca dlog +) + +INCLUDE_DIRECTORIES( + ${${CAPI_LIB}_INCLUDE_DIRS} +) +ADD_DEFINITIONS("-D__TIZEN__") +ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.c ${TC_SOURCES}) +TARGET_LINK_LIBRARIES(${EXEC_NAME} + ${${CAPI_LIB}_LIBRARIES} /usr/lib/liboicinterface.a -lm -lpthread -lrt -ldl -lcapi-network-wifi -lcapi-network-bluetooth -ldlog +) + +INSTALL(PROGRAMS ${EXEC_NAME} + DESTINATION ${BIN_DIR}/${EXEC_NAME} +) 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 new file mode 100644 index 0000000..d38dacb --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/bt/utc-bt-liboic.c @@ -0,0 +1,269 @@ +//#include +#include "assert.h" +#include "interfaceHeaders/cacommon.h" +#include "interfaceHeaders/caadapterinterface.h" +#include "interfaceHeaders/caedradapter.h" + +//& set: Liboic + +//Bt callbacks + +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 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"; +//static GMainLoop *mainloop; +//int gMainloopStatus = 0; + +//Hardcoded values to Test + +char coapData[500] = "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}\]}"; + +typedef struct ConnectivityHandlerList { + CAConnectivityType_t type; + CAConnectivityHandler_t handler; + struct ConnectivityHandlerList* nextHandler; +} ConnectivityHandlerList; + +CAConnectivityHandler_t* gConnectivityHandlers = NULL; + +void storeInterfaceCallbacks(CAConnectivityHandler_t* newHandler) +{ + printf("\nstoreInterfaceCallbacks Entry in Sample"); + #if 0 + newHandler->nextHandler = NULL; + + CAConnectivityHandler* tempCAConnectivityHandlers = gCAConnectivityHandlers; + + if (!tempCAConnectivityHandlers) { + gCAConnectivityHandlers = newHandler; + return; + } + while (tempCAConnectivityHandlers->nextHandler) { + tempCAConnectivityHandlers = tempCAConnectivityHandlers->nextHandler; + } + + tempCAConnectivityHandlers->nextHandler = newHandler; + #endif + printf("\nstoreInterfaceCallbacks Exit in Sample"); +} + +void interfaceRegisterCallback(CAConnectivityHandler_t handler, + CAConnectivityType_t connType) +{ + printf("interfaceRegisterCallback Entry in Sample\n"); + ConnectivityHandlerList* newConnectivityHandler = (ConnectivityHandlerList*) malloc(sizeof(ConnectivityHandlerList)); + if (NULL == newConnectivityHandler) + { + printf("Memory allocation failed!\n"); + return; + } + + newConnectivityHandler->type = connType; + newConnectivityHandler->handler = handler; + storeInterfaceCallbacks(newConnectivityHandler); + printf("interfaceRegisterCallback Exit in Sample\n"); +} + +void requestResponseHandler(CARemoteEndpoint_t* object, void* data) +{ + printf("\nrequestResponseHandler Entry in Sample"); + if (object == NULL || data == NULL) { + printf("\nNULL Object"); + return; + } + + if (object->addressInfo.BT.btMacAddress) + printf("\nData Received from %s\n", object->addressInfo.BT.btMacAddress); + if (data) + printf("\nReceived Data : %s \n", (char*)data); + /* + gMainloopStatus = 1; + if (mainloop) + { + g_main_loop_quit(mainloop); + mainloop = NULL; + } + */ + printf("\nrequestResponseHandler Exit in Sample"); +} + + +void networkInterfaceCallback(CALocalConnectivity_t* localEndPoint, CANetworkStatus_t networkConnectivityState) +{ + printf("\nnetworkInterfaceCallback Entry in Sample"); + if (localEndPoint == NULL) { + printf("\nNULL Object"); + return; + } + + if (localEndPoint->addressInfo.BT.btMacAddress) + printf("\n Interface Address%s\n", localEndPoint->addressInfo.BT.btMacAddress); + + if (networkConnectivityState == CA_INTERFACE_UP) + printf("\n BT Status is UP"); + else + printf("\n BT Status is DOWN"); + printf("\nnetworkInterfaceCallback Exit in Sample"); +} + +void utc_liboic_startup(void) +{ + +} + +void utc_liboic_cleanup(void) +{ + +} + + +int bt_tc_001_intializeBT_p(void) +{ + CAResult_t error = CA_STATUS_FAILED; + error = CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + assert_eq(error, CA_STATUS_OK); + CATerminateEDR(); + return 0; +} + +int bt_tc_002_intializeBT_n(void) +{ + CAResult_t error = CA_STATUS_FAILED; + error = CAInitializeEDR(NULL, NULL, NULL); + assert_eq(error, CA_STATUS_INVALID_PARAM); + return 0; +} + +int bt_tc_003_getBTInterfaceInformation_p(void) +{ + CAResult_t error = CA_STATUS_FAILED; + //Startup + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + + error = CAGetEDRInterfaceInformation(&localBtEndpoint,&size); + assert_eq(error, CA_STATUS_OK); + + CATerminateEDR(); + // Now, check local endpoint information + //assert_neq(localBtEndpoint->endpoint_info, NULL); + //assert_neq(localBtEndpoint->endpoint_info->address, NULL); + return 0; +} + +int bt_tc_004_getBTInterfaceInformation_n(void) +{ + CAResult_t error = CA_STATUS_FAILED; + error = CAGetEDRInterfaceInformation(NULL,NULL); + assert_eq(error, CA_STATUS_INVALID_PARAM); + return 0; +} + +int bt_tc_005_startAdapter_p(void) +{ + CAResult_t error = CA_STATUS_FAILED; + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + error = CAStartEDR(); + assert_eq(error, CA_STATUS_OK); + CAStopEDR(); + CATerminateEDR(); + return 0; +} + +int bt_tc_006_sendBTUnicastData_p(void) +{ + int dataSize = 0; + int ret = -1; + int ref = 0; + + //Startup + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + 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'; + endpoint.resourceUri = NULL; + ret = CASendEDRUnicastData(&endpoint, coapData, strlen(coapData) + 1); + sleep(5); + + //Cleanup + CAStopEDR(); + CATerminateEDR(); + + assert_eq(ret, strlen(coapData) + 1); + return 0; +} + +int bt_tc_007_sendBTUnicastData_n(void) +{ + int dataSize = 0; + int ret = -1; + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + ret = CASendEDRUnicastData(NULL, NULL, NULL); + CATerminateEDR(); + assert_eq(ret, 0); + return 0; +} + +int bt_tc_008_sendBTMulticastDataToAll_p(void) +{ + int dataSize = 0; + int ret = 0; + CAStartEDRListeningServer(); + ret = CASendEDRMulticastData(coapData, strlen(coapData) + 1); + assert_eq(ret, strlen(coapData) + 1); + CAStopEDR(); + CATerminateEDR(); + return 0; +} + +int bt_tc_009_sendBTMulticastDataToAll_n(void) +{ + int dataSize = 0; + int ret = -1; + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + ret = CASendEDRMulticastData(NULL, NULL); + CATerminateEDR(); + assert_eq(ret, 0); + return 0; +} + +int bt_tc_010_StartListeningServer_p(void) +{ + CAResult_t error = CA_STATUS_FAILED; + int ref = 0; + //Startup + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + + error = CAStartEDRListeningServer(); + assert_eq(error, CA_STATUS_OK); + //Cleanup + CAStopEDR(); + CATerminateEDR(); + return 0; +} + +int bt_tc_011_StopRfCommServer_p(void) +{ + CAResult_t error = CA_STATUS_FAILED; + int ref = 0; + //Startup + CAInitializeEDR(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + CAStartEDRListeningServer(); + + error = CAStopEDR(); + assert_eq(error, CA_STATUS_OK); + //Cleanup + CATerminateEDR(); + 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 new file mode 100644 index 0000000..0075867 --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.c @@ -0,0 +1,31 @@ +#include +#include +#include "tct-liboic-core.h" + +int main(int argc, const char* argv[]) +{ + int result = -1; + int i; + + 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)) { + if (tc_array[i].startup) + tc_array[i].startup(); + + result = tc_array[i].function(); + + if (tc_array[i].cleanup) + tc_array[i].cleanup(); + + return result; + } + } + + printf("Unknown testcase name: \"%s\"\n", argv[1]); + return 2; +} 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 new file mode 100644 index 0000000..b2dfe18 --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/tct-liboic-core.h @@ -0,0 +1,36 @@ +#ifndef __TCT_LIBOIC_CORE_H__ +#define __TCT_LIBOIC_CORE_H__ + +#include "testcase.h" + +extern void utc_liboic_startup(void); +extern void utc_liboic_cleanup(void); + +extern int wifi_tc_001_initializeWifi_p(void); +extern int wifi_tc_002_initializeWifi_n(void); +extern int wifi_tc_003_getWIFIInterfaceInformation_p(void); +extern int wifi_tc_004_getWIFIInterfaceInformation_n(void); +extern int wifi_tc_005_sendWifiUnicastData_p(void); +extern int wifi_tc_006_sendWifiUnicastData_n(void); +extern int wifi_tc_007_sendWifiMulticastData_p(void); +extern int wifi_tc_008_sendWifiMulticastData_n(void); +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[] = { + {"wifi_tc_001_initializeWifi_p", wifi_tc_001_initializeWifi_p, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_002_initializeWifi_n", wifi_tc_002_initializeWifi_n, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_003_getWIFIInterfaceInformation_p", wifi_tc_003_getWIFIInterfaceInformation_p, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_004_getWIFIInterfaceInformation_n", wifi_tc_004_getWIFIInterfaceInformation_n, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_005_sendWifiUnicastData_p", wifi_tc_005_sendWifiUnicastData_p, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_006_sendWifiUnicastData_n", wifi_tc_006_sendWifiUnicastData_n, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_007_sendWifiMulticastData_p", wifi_tc_007_sendWifiMulticastData_p, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_008_sendWifiMulticastData_n", wifi_tc_008_sendWifiMulticastData_n, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_009_startWifiServers_p", wifi_tc_009_startWifiServers_p, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_010_startWifiServers_n", wifi_tc_010_startWifiServers_n, utc_liboic_startup, utc_liboic_cleanup}, + {"wifi_tc_011_stopWifiServers_p", wifi_tc_011_stopWifiServers_p, utc_liboic_startup, utc_liboic_cleanup}, + {NULL, NULL} +}; + +#endif // __TCT_LIBOIC_CORE_H__ diff --git a/resource/csdk/connectivity/unittests/tizen/tct/liboic/utc-liboic.c b/resource/csdk/connectivity/unittests/tizen/tct/liboic/utc-liboic.c new file mode 100644 index 0000000..ab84183 --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/utc-liboic.c @@ -0,0 +1,32 @@ +#include "assert.h" +#include "oic-core/logger.h" +#include "oic-core/csdk.h" +#include "interfaceHeaders/common.h" +#include "interfaceHeaders/connectivity_interface.h" +#include "interfaceHeaders/WiFiInterface.h" +#include "interfaceHeaders/bt_interface.h" + +//& set: Liboic + +void utc_liboic_startup(void) +{ + /*Precondition for each TC*/ +} + +void utc_liboic_cleanup(void) +{ + /*Postcondition for each TC*/ +} + + +//& purpose: A purpose of a first positive TC. +int first_tc_p(void) +{ + return 0; +} + +//& purpose: A purpose of a first negative TC. +int first_tc_n(void) +{ + return 0; +} 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 new file mode 100644 index 0000000..8a4d07d --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/liboic/wifi/utc-wifi-liboic.c @@ -0,0 +1,411 @@ +//#include +#include "assert.h" +//#include "oic-core/logger.h" +//#include "oic-core/ocstack.h" +#include "interfaceHeaders/cacommon.h" +#include "interfaceHeaders/caadapterinterface.h" +#include "interfaceHeaders/cawifiethernetadapter.h" + +//& set: Liboic + +//Wifi callbacks + +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 localIPAddress[CA_IPADDR_SIZE] = {0}; +int localPort = -1; +int32_t serverId; +//static GMainLoop *mainloop; +//int gMainloopStatus = 0; + +//Hardcoded values to Test +typedef struct ConnectivityHandlerList { + CAConnectivityType type; + CAConnectivityHandler handler; + struct ConnectivityHandlerList* nextHandler; +} ConnectivityHandlerList; + +char coapData[500] = "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}\]}"; + +#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" + + +CAConnectivityHandler* gCAConnectivityHandlers = NULL; + +int interfaceInitializeEndpoint(int d) +{ + 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 */ + } + + remoteMulticastEndpoint.connectivityType = CA_WIFI; +} + +void storeInterfaceCallbacks(CAConnectivityHandler* newHandler) +{ + printf("\nstoreInterfaceCallbacks Entry in Sample"); + #if 0 + newHandler->nextHandler = NULL; + + CAConnectivityHandler* tempCAConnectivityHandlers = gCAConnectivityHandlers; + + if (!tempCAConnectivityHandlers) { + gCAConnectivityHandlers = newHandler; + return; + } + while (tempCAConnectivityHandlers->nextHandler) { + tempCAConnectivityHandlers = tempCAConnectivityHandlers->nextHandler; + } + + tempCAConnectivityHandlers->nextHandler = newHandler; + #endif + printf("\nstoreInterfaceCallbacks Exit in Sample"); +} + +/* +void interfaceRegisterCallback(CAConnectivityHandler handler , CAConnectivityType cType) +{ + 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); + printf("\ninterfaceRegisterCallback Exit in Sample"); +} +*/ + +void interfaceRegisterCallback(CAConnectivityHandler handler, + CAConnectivityType connType) +{ + printf("interfaceRegisterCallback Entry in Sample\n"); + ConnectivityHandlerList* newConnectivityHandler = (ConnectivityHandlerList*) malloc(sizeof(ConnectivityHandlerList)); + if (NULL == newConnectivityHandler) + { + printf("Memory allocation failed!\n"); + return; + } + + newConnectivityHandler->type = connType; + newConnectivityHandler->handler = handler; + storeInterfaceCallbacks(newConnectivityHandler); + printf("interfaceRegisterCallback Exit in Sample\n"); +} + + +void requestResponseHandler(CARemoteEndpoint* object, void* data) +{ + printf("\nrequestResponseHandler Entry in Sample"); + if (object == NULL || data == NULL) { + printf("\nNULL Object"); + return; + } + + if (object->addressInfo.IP.ipAddress) + printf("\nData Received from %s\n", object->addressInfo.IP.ipAddress); + if (data) + printf("\nReceived Data : %s \n", (char*)data); + /* + gMainloopStatus = 1; + if (mainloop) + { + g_main_loop_quit(mainloop); + mainloop = NULL; + } + */ + printf("\nrequestResponseHandler Exit in Sample"); +} + + +void networkInterfaceCallback(CALocalConnectivity* localEndPoint, CANetworkStatus networkConnectivityState) +{ + printf("\nnetworkInterfaceCallback Entry in Sample"); + if (localEndPoint == NULL) { + printf("\nNULL Object"); + return; + } + + if (localEndPoint->addressInfo.IP.ipAddress) + printf("\n Local Interface Address%s\n", localEndPoint->addressInfo.IP.ipAddress); + + if (networkConnectivityState == CA_INTERFACE_UP) + printf("\n WiFi Network Status is UP"); + else + printf("\n WiFi Network Status is DOWN"); + printf("\nnetworkInterfaceCallback Exit in Sample"); +} + +void utc_liboic_startup(void) +{ + +} + +void utc_liboic_cleanup(void) +{ + +} + + +int wifi_tc_001_initializeWifi_p(void) +{ + CAResult error = CA_STATUS_FAILED; + error = CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + assert_eq(error, CA_STATUS_OK); + return 0; +} + +int wifi_tc_002_initializeWifi_n(void) +{ + CAResult error = CA_STATUS_FAILED; + error = CAInitializeWifi(NULL, NULL, NULL); + assert_eq(error, CA_STATUS_INVALID_PARAM); //Note: initializeWifi always return OC_STACK_OK + return 0; +} + +int wifi_tc_003_getWIFIInterfaceInformation_p(void) +{ + CAResult error = CA_STATUS_FAILED; + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + assert_eq(error, CA_STATUS_OK); + + // Now, check local endpoint information + //assert_neq(localWifiEndpoint->endpoint_info, NULL); + strncpy(localIPAddress, localWifiEndpoint->addressInfo.IP.ipAddress, CA_IPADDR_SIZE); + localPort = localWifiEndpoint->addressInfo.IP.port; + assert_neq(localPort, -1); + return 0; +} + +int wifi_tc_004_getWIFIInterfaceInformation_n(void) +{ + CAResult error = CA_STATUS_FAILED; + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(NULL, &size); + assert_eq(error, CA_STATUS_INVALID_PARAM); + return 0; +} + +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; + //StartWifiAdapter(localWifiEndpoint); + + interfaceInitializeEndpoint(0); + dataSize = CASendWIFIUnicastData(&remoteEndpoint[0], coapData, strlen(coapData)); + sleep(5); + + assert_eq(dataSize, strlen(coapData)); + CATerminateWifi(); + return 0; +} + +int wifi_tc_006_sendWifiUnicastData_n(void) +{ + int dataSize = 0; + interfaceInitializeEndpoint(0); + dataSize = CASendWIFIUnicastData(NULL, NULL, NULL); + assert_eq(dataSize, 0); + return 0; +} + +int wifi_tc_007_sendWifiMulticastData_p(void) +{ + uint32_t dataSize = 0; + interfaceInitializeEndpoint(0); + dataSize = CASendWIFIMulticastData(coapData, strlen(coapData)); + assert_eq(dataSize, strlen(coapData)); + return 0; +} + +int wifi_tc_008_sendWifiMulticastData_n(void) +{ + int dataSize = 0; + interfaceInitializeEndpoint(0); + dataSize = CASendWIFIMulticastData(NULL, NULL); + assert_eq(dataSize, 0); + return 0; +} + +int wifi_tc_009_startUnicastServer_p(void) +{ + CAResult error = CA_STATUS_FAILED; + int16_t unicastPort = CA_PORT; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + + error = CAStartUnicastServer("0.0.0.0", &unicastPort); + assert_eq(error, CA_STATUS_OK); + //Cleanup + CAStopUnicastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_010_startUnicastServer_n(void) +{ + CAResult error = CA_STATUS_FAILED; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + assert_eq(error, CA_STATUS_OK); + + error = CAStartUnicastServer(NULL, localWifiEndpoint->addressInfo.IP.port); + assert_eq(error, CA_STATUS_INVALID_PARAM); + //Cleanup + CAStopUnicastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_011_startUnicastServer_n(void) +{ + CAResult error = CA_STATUS_FAILED; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + 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 + CAStopUnicastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_012_startUnicastServer_n(void) +{ + CAResult error = CA_STATUS_FAILED; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + 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 + CAStopUnicastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_013_startMulticastServer_p(void) +{ + CAResult error = CA_STATUS_FAILED; + int16_t multicastPort = CA_MCAST_PORT; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + + error = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort); + assert_eq(error, CA_STATUS_OK); + //Cleanup + CAStopMulticastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_014_startMulticastServer_n(void) +{ + CAResult error = CA_STATUS_FAILED; + int16_t multicastPort = CA_MCAST_PORT; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + + error = CAStartMulticastServer(NULL, "0.0.0.0", &multicastPort); + assert_eq(error, CA_STATUS_INVALID_PARAM); + //Cleanup + CAStopMulticastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_015_startMulticastServer_n(void) +{ + CAResult error = CA_STATUS_FAILED; + int16_t multicastPort = CA_MCAST_PORT; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + + error = CAStartMulticastServer(CA_MULTICAST_IP, NULL, &multicastPort); + assert_eq(error, CA_STATUS_INVALID_PARAM); + //Cleanup + CAStopMulticastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_016_startMulticastServer_n(void) +{ + CAResult error = CA_STATUS_FAILED; + int16_t multicastPort = CA_MCAST_PORT; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + + error = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", NULL); + assert_eq(error, CA_STATUS_INVALID_PARAM); + //Cleanup + CAStopMulticastServer(); + CATerminateWifi(); + return 0; +} + +int wifi_tc_017_startMulticastServer_n(void) +{ + CAResult error = CA_STATUS_FAILED; + int16_t multicastPort = CA_MCAST_PORT; + //Startup + CAInitializeWifi(interfaceRegisterCallback, requestResponseHandler, networkInterfaceCallback); + uint32_t size = 0; + error = CAGetWIFIInterfaceInformation(&localWifiEndpoint, &size); + + error = CAStartMulticastServer(NULL, NULL, NULL); + assert_eq(error, CA_STATUS_INVALID_PARAM); + //Cleanup + CAStopMulticastServer(); + CATerminateWifi(); + return 0; +} + diff --git a/resource/csdk/connectivity/unittests/tizen/tct/packaging/core-liboic-tests.spec b/resource/csdk/connectivity/unittests/tizen/tct/packaging/core-liboic-tests.spec new file mode 100644 index 0000000..d113e1a --- /dev/null +++ b/resource/csdk/connectivity/unittests/tizen/tct/packaging/core-liboic-tests.spec @@ -0,0 +1,57 @@ +%define MODULE_NAME liboic +%define MODULE_LIBNAME liboic +Name: core-%{MODULE_NAME}-tests +Summary: Core API unit TC (%{name}) +Version: 0.1 +Release: 0 +Group: Development/Tools +License: Apache License, Version 2.0, Samsung Properietary +Source0: %{name}-%{version}.tar.gz +#BuildRequires: pkgconfig(%{MODULE_LIBNAME}) +BuildRequires: pkgconfig(capi-network-wifi) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(capi-network-bluetooth) +BuildRequires: pkgconfig(dlog) +#BuildRequires: pkgconfig(oic-core) +BuildRequires: pkgconfig(com.samsung.oicca) +BuildRequires: cmake + +%description +Core API unit TC (%{name}) + +%prep +%setup -q + +%build + +%define PREFIX "%{_libdir}/%{name}" + +export LDFLAGS+="-Wl,--rpath=%{PREFIX} -Wl,--as-needed" + +cmake . -DMODULE="%{MODULE_NAME}" -DCMAKE_INSTALL_PREFIX=%{_prefix} + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install +mkdir -p %{buildroot}/opt/usr/share/license +cp LICENSE %{buildroot}/opt/usr/share/license/%{name} +mkdir -p %{buildroot}/tmp/ +cp scripts/add_all_smack_rule.sh %{buildroot}/tmp/ +cp scripts/all_smack.rule %{buildroot}/tmp/ +#mkdir -p %{buildroot}/opt/usr/bin/tct-liboic-core +#cp src/liboic/libcapi-network-wifi.so.0 %{buildroot}/opt/usr/bin/tct-liboic-core +#cp src/liboic/libcapi-network-wifi.so.0.1.20 %{buildroot}/opt/usr/bin/tct-liboic-core +#cp src/liboic/libcapi-network-wifi.so.1 %{buildroot}/opt/usr/bin/tct-liboic-core +%post + +%postun + + +%files +/opt/usr/bin/* +#/usr/$(BIN_DIR)/lib*.so* +/opt/usr/share/license/%{name} +/tmp/add_all_smack_rule.sh +/tmp/all_smack.rule -- 2.7.4