From d87913781b94f0e6f23ca8c9789d5842c02aea8b Mon Sep 17 00:00:00 2001 From: "junho13.lee" Date: Mon, 17 Nov 2014 19:31:24 +0900 Subject: [PATCH] Supporting Java Plugin and making plugin manager as a library 1) Cleaned unnecsssary files. 2) Changed plugin manager to support C/C++ and Java Plugin. Java plugin manager is not completed yet. This commit only have template code for Java. 3) Created plugin manager as a separate library(libpm.a) to be linked by application directly. And separated plugin manager implementation as shared library(libpmimpl.so) to support out-proc mode with same libpm.a in the future. Change-Id: I5a80faa0546da1832e15a75dacc7f916faedd868 Signed-off-by: Lee Jun Ho --- service/protocol-plugin/build/linux/Makefile | 12 +- .../plugin-manager/build/linux/Makefile | 48 +- .../plugin-manager/src/CpluffAdapter.cpp | 575 +++++ .../plugin-manager/src/CpluffAdapter.h | 279 +++ .../plugin-manager/src/FelixAdapter.cpp | 125 ++ .../plugin-manager/src/FelixAdapter.h | 272 +++ .../protocol-plugin/plugin-manager/src/Plugin.h | 6 +- .../plugin-manager/src/PluginLifecycleManager.cpp | 109 - .../plugin-manager/src/PluginLifecycleManager.h | 70 - .../plugin-manager/src/PluginManager.cpp | 549 +---- .../plugin-manager/src/PluginManager.h | 220 +- .../plugin-manager/src/PluginManagerImpl.cpp | 346 +++ .../plugin-manager/src/PluginManagerImpl.h | 223 ++ .../plugin-manager/src/PluginManagerService.cpp | 184 -- .../plugins/hue/build/linux/Makefile | 60 - .../plugins/hue/build/linux/plugin.xml | 15 - .../protocol-plugin/plugins/hue/lib/curl/curl.h | 2218 -------------------- .../plugins/hue/lib/curl/curlbuild.h | 191 -- .../plugins/hue/lib/curl/curlrules.h | 261 --- .../protocol-plugin/plugins/hue/lib/curl/curlver.h | 69 - .../protocol-plugin/plugins/hue/lib/curl/easy.h | 102 - .../protocol-plugin/plugins/hue/lib/curl/mprintf.h | 81 - .../protocol-plugin/plugins/hue/lib/curl/multi.h | 350 --- .../plugins/hue/lib/curl/stdcheaders.h | 33 - .../plugins/hue/lib/curl/typecheck-gcc.h | 590 ------ service/protocol-plugin/plugins/hue/readme | 8 - .../protocol-plugin/plugins/hue/src/HueBridge.cpp | 118 -- .../protocol-plugin/plugins/hue/src/HueBridge.h | 18 - .../plugins/hue/src/HueLightHandler.cpp | 209 -- .../plugins/hue/src/HueLightHandler.h | 59 - .../protocol-plugin/plugins/hue/src/HuePlugin.cpp | 395 ---- .../protocol-plugin/plugins/hue/src/HuePlugin.h | 83 - .../plugins/hue/src/OCResourceDesc.cpp | 165 -- .../plugins/hue/src/OCResourceDesc.h | 71 - .../plugins/hue/src/PluginProvider.h | 53 - .../protocol-plugin/plugins/hue/src/http_curl.cpp | 188 -- .../protocol-plugin/plugins/hue/src/http_curl.h | 32 - .../plugins/hue/src/hue_light_sample.cpp | 526 ----- .../protocol-plugin/plugins/hue/src/json_parse.h | 8 - service/protocol-plugin/plugins/hue/src/search.cpp | 32 - .../plugins/hue/src/simple_parse.cpp | 65 - .../protocol-plugin/plugins/hue/src/simple_parse.h | 17 - .../plugins/hue/src/test/client_test.cpp | 354 ---- .../plugins/hue/src/test/hue_web.py | 114 - .../plugins/hue/src/test/server_test.cpp | 367 ---- .../{mqtt => mqtt-fan}/build/linux/Makefile | 6 +- .../{mqtt => mqtt-fan}/build/linux/plugin.xml | 0 .../plugins/{mqtt => mqtt-fan}/lib/CMakeLists.txt | 0 .../plugins/{mqtt => mqtt-fan}/lib/Makefile | 0 .../plugins/{mqtt => mqtt-fan}/lib/config.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/config.mk | 0 .../{mqtt => mqtt-fan}/lib/cpp/CMakeLists.txt | 0 .../plugins/{mqtt => mqtt-fan}/lib/cpp/Makefile | 0 .../{mqtt => mqtt-fan}/lib/cpp/mosquittopp.cpp | 0 .../{mqtt => mqtt-fan}/lib/cpp/mosquittopp.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/cpp/test.txt | 0 .../plugins/{mqtt => mqtt-fan}/lib/dummypthread.h | 0 .../{mqtt => mqtt-fan}/lib/jsws/mosquitto.js | 0 .../plugins/{mqtt => mqtt-fan}/lib/linker.version | 0 .../plugins/{mqtt => mqtt-fan}/lib/logging_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/logging_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/memory_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/memory_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/messages_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/messages_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/mosquitto.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/mosquitto.h | 0 .../{mqtt => mqtt-fan}/lib/mosquitto_internal.h | 0 .../{mqtt => mqtt-fan}/lib/mqtt3_protocol.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/net_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/net_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/python/Makefile | 0 .../{mqtt => mqtt-fan}/lib/python/mosquitto.py | 0 .../plugins/{mqtt => mqtt-fan}/lib/python/setup.py | 0 .../plugins/{mqtt => mqtt-fan}/lib/python/sub.py | 0 .../plugins/{mqtt => mqtt-fan}/lib/read_handle.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/read_handle.h | 0 .../{mqtt => mqtt-fan}/lib/read_handle_client.c | 0 .../{mqtt => mqtt-fan}/lib/read_handle_shared.c | 0 .../{mqtt => mqtt-fan}/lib/send_client_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/send_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/send_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/srv_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/thread_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/time_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/time_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/tls_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/tls_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/util_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/util_mosq.h | 0 .../plugins/{mqtt => mqtt-fan}/lib/will_mosq.c | 0 .../plugins/{mqtt => mqtt-fan}/lib/will_mosq.h | 0 .../plugins/mqtt-fan/src/fanserver.cpp | 525 +++++ .../plugins/{mqtt => mqtt-fan}/src/fanserver.h | 0 .../src/fanserver_mqtt_plugin.cpp | 3 - .../{mqtt => mqtt-fan}/src/fanserver_mqtt_plugin.h | 0 .../plugins/mqtt-light/build/linux/Makefile | 48 + .../plugins/mqtt-light/build/linux/plugin.xml | 7 + .../plugins/mqtt-light/lib/CMakeLists.txt | 71 + .../plugins/mqtt-light/lib/Makefile | 99 + .../plugins/mqtt-light/lib/config.h | 19 + .../plugins/mqtt-light/lib/config.mk | 218 ++ .../plugins/mqtt-light/lib/cpp/CMakeLists.txt | 18 + .../plugins/mqtt-light/lib/cpp/Makefile | 31 + .../plugins/mqtt-light/lib/cpp/mosquittopp.cpp | 305 +++ .../plugins/mqtt-light/lib/cpp/mosquittopp.h | 122 ++ .../plugins/mqtt-light/lib/cpp/test.txt | 883 ++++++++ .../plugins/mqtt-light/lib/dummypthread.h | 13 + .../plugins/mqtt-light/lib/jsws/mosquitto.js | 363 ++++ .../plugins/mqtt-light/lib/linker.version | 71 + .../plugins/mqtt-light/lib/logging_mosq.c | 69 + .../plugins/mqtt-light/lib/logging_mosq.h | 36 + .../plugins/mqtt-light/lib/memory_mosq.c | 134 ++ .../plugins/mqtt-light/lib/memory_mosq.h | 50 + .../plugins/mqtt-light/lib/messages_mosq.c | 400 ++++ .../plugins/mqtt-light/lib/messages_mosq.h | 44 + .../plugins/mqtt-light/lib/mosquitto.c | 1306 ++++++++++++ .../plugins/mqtt-light/lib/mosquitto.h | 1429 +++++++++++++ .../plugins/mqtt-light/lib/mosquitto_internal.h | 243 +++ .../plugins/mqtt-light/lib/mqtt3_protocol.h | 66 + .../plugins/mqtt-light/lib/net_mosq.c | 1129 ++++++++++ .../plugins/mqtt-light/lib/net_mosq.h | 104 + .../plugins/mqtt-light/lib/python/Makefile | 25 + .../lib/python}/mosquitto.py | 0 .../plugins/mqtt-light/lib/python/setup.py | 28 + .../plugins/mqtt-light/lib/python/sub.py | 66 + .../plugins/mqtt-light/lib/read_handle.c | 168 ++ .../plugins/mqtt-light/lib/read_handle.h | 47 + .../plugins/mqtt-light/lib/read_handle_client.c | 76 + .../plugins/mqtt-light/lib/read_handle_shared.c | 271 +++ .../plugins/mqtt-light/lib/send_client_mosq.c | 227 ++ .../plugins/mqtt-light/lib/send_mosq.c | 289 +++ .../plugins/mqtt-light/lib/send_mosq.h | 50 + .../plugins/mqtt-light/lib/srv_mosq.c | 106 + .../plugins/mqtt-light/lib/thread_mosq.c | 114 + .../plugins/mqtt-light/lib/time_mosq.c | 95 + .../plugins/mqtt-light/lib/time_mosq.h | 35 + .../plugins/mqtt-light/lib/tls_mosq.c | 147 ++ .../plugins/mqtt-light/lib/tls_mosq.h | 49 + .../plugins/mqtt-light/lib/util_mosq.c | 320 +++ .../plugins/mqtt-light/lib/util_mosq.h | 48 + .../plugins/mqtt-light/lib/will_mosq.c | 130 ++ .../plugins/mqtt-light/lib/will_mosq.h | 39 + .../plugins/mqtt-light/src/lightserver.cpp | 525 +++++ .../plugins/mqtt-light/src/lightserver.h | 2 + .../mqtt-light/src/lightserver_mqtt_plugin.cpp | 80 + .../mqtt-light/src/lightserver_mqtt_plugin.h | 6 + .../protocol-plugin/plugins/mqtt/src/fanserver.cpp | 419 ---- .../sample-app/linux/fan-control/Makefile | 17 +- .../sample-app/linux/fan-control/fanclient.cpp | 535 +++-- 150 files changed, 13003 insertions(+), 8593 deletions(-) create mode 100644 service/protocol-plugin/plugin-manager/src/CpluffAdapter.cpp create mode 100644 service/protocol-plugin/plugin-manager/src/CpluffAdapter.h create mode 100644 service/protocol-plugin/plugin-manager/src/FelixAdapter.cpp create mode 100644 service/protocol-plugin/plugin-manager/src/FelixAdapter.h delete mode 100644 service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.cpp delete mode 100644 service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.h create mode 100644 service/protocol-plugin/plugin-manager/src/PluginManagerImpl.cpp create mode 100644 service/protocol-plugin/plugin-manager/src/PluginManagerImpl.h delete mode 100644 service/protocol-plugin/plugin-manager/src/PluginManagerService.cpp delete mode 100644 service/protocol-plugin/plugins/hue/build/linux/Makefile delete mode 100644 service/protocol-plugin/plugins/hue/build/linux/plugin.xml delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/curl.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/curlbuild.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/curlrules.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/curlver.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/easy.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/mprintf.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/multi.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/stdcheaders.h delete mode 100644 service/protocol-plugin/plugins/hue/lib/curl/typecheck-gcc.h delete mode 100644 service/protocol-plugin/plugins/hue/readme delete mode 100644 service/protocol-plugin/plugins/hue/src/HueBridge.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/HueBridge.h delete mode 100644 service/protocol-plugin/plugins/hue/src/HueLightHandler.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/HueLightHandler.h delete mode 100644 service/protocol-plugin/plugins/hue/src/HuePlugin.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/HuePlugin.h delete mode 100644 service/protocol-plugin/plugins/hue/src/OCResourceDesc.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/OCResourceDesc.h delete mode 100644 service/protocol-plugin/plugins/hue/src/PluginProvider.h delete mode 100644 service/protocol-plugin/plugins/hue/src/http_curl.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/http_curl.h delete mode 100644 service/protocol-plugin/plugins/hue/src/hue_light_sample.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/json_parse.h delete mode 100644 service/protocol-plugin/plugins/hue/src/search.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/simple_parse.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/simple_parse.h delete mode 100644 service/protocol-plugin/plugins/hue/src/test/client_test.cpp delete mode 100644 service/protocol-plugin/plugins/hue/src/test/hue_web.py delete mode 100644 service/protocol-plugin/plugins/hue/src/test/server_test.cpp rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/build/linux/Makefile (77%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/build/linux/plugin.xml (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/CMakeLists.txt (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/Makefile (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/config.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/config.mk (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/cpp/CMakeLists.txt (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/cpp/Makefile (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/cpp/mosquittopp.cpp (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/cpp/mosquittopp.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/cpp/test.txt (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/dummypthread.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/jsws/mosquitto.js (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/linker.version (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/logging_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/logging_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/memory_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/memory_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/messages_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/messages_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/mosquitto.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/mosquitto.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/mosquitto_internal.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/mqtt3_protocol.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/net_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/net_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/python/Makefile (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/python/mosquitto.py (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/python/setup.py (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/python/sub.py (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/read_handle.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/read_handle.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/read_handle_client.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/read_handle_shared.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/send_client_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/send_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/send_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/srv_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/thread_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/time_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/time_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/tls_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/tls_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/util_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/util_mosq.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/will_mosq.c (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/lib/will_mosq.h (100%) create mode 100644 service/protocol-plugin/plugins/mqtt-fan/src/fanserver.cpp rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/src/fanserver.h (100%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/src/fanserver_mqtt_plugin.cpp (96%) rename service/protocol-plugin/plugins/{mqtt => mqtt-fan}/src/fanserver_mqtt_plugin.h (100%) create mode 100644 service/protocol-plugin/plugins/mqtt-light/build/linux/Makefile create mode 100644 service/protocol-plugin/plugins/mqtt-light/build/linux/plugin.xml create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/CMakeLists.txt create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/Makefile create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/config.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/config.mk create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/cpp/CMakeLists.txt create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/cpp/Makefile create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.cpp create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/cpp/test.txt create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/dummypthread.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/jsws/mosquitto.js create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/linker.version create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/logging_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/logging_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/mosquitto.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/mosquitto.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/mosquitto_internal.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/mqtt3_protocol.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/python/Makefile rename service/protocol-plugin/plugins/{mqtt/lib/python/build/lib.linux-i686-2.7 => mqtt-light/lib/python}/mosquitto.py (100%) create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/python/setup.py create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/python/sub.py create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/read_handle.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/read_handle.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/read_handle_client.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/read_handle_shared.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/send_client_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/srv_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/thread_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.c create mode 100644 service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/src/lightserver.cpp create mode 100644 service/protocol-plugin/plugins/mqtt-light/src/lightserver.h create mode 100644 service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.cpp create mode 100644 service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.h delete mode 100644 service/protocol-plugin/plugins/mqtt/src/fanserver.cpp diff --git a/service/protocol-plugin/build/linux/Makefile b/service/protocol-plugin/build/linux/Makefile index 09a335e..7def475 100644 --- a/service/protocol-plugin/build/linux/Makefile +++ b/service/protocol-plugin/build/linux/Makefile @@ -8,15 +8,16 @@ pre: -mkdir release resource: - cd $(PROTOCOL_ROOT)../../resource/build/linux && $(MAKE) + cd $(PROTOCOL_ROOT)../../resource && $(MAKE) plugin-manager: cd $(PROTOCOL_ROOT)plugin-manager/build/linux && $(MAKE) - cp -Rdp $(PROTOCOL_ROOT)plugin-manager/build/linux/ppm release/ + cp -Rdp $(PROTOCOL_ROOT)plugin-manager/build/linux/libppm.a release/ + cp -Rdp $(PROTOCOL_ROOT)plugin-manager/build/linux/libpmimpl.so release/ plugins: - cd $(PROTOCOL_ROOT)plugins/mqtt/build/linux && $(MAKE) - cd $(PROTOCOL_ROOT)plugins/hue/build/linux && $(MAKE) + cd $(PROTOCOL_ROOT)plugins/mqtt-fan/build/linux && $(MAKE) + cd $(PROTOCOL_ROOT)plugins/mqtt-light/build/linux && $(MAKE) sample-app: cd $(PROTOCOL_ROOT)sample-app/linux/fan-control && $(MAKE) @@ -25,7 +26,8 @@ sample-app: clean: cd $(PROTOCOL_ROOT)plugin-manager/build/linux && $(MAKE) clean - cd $(PROTOCOL_ROOT)plugins/mqtt/build/linux && $(MAKE) clean + cd $(PROTOCOL_ROOT)plugins/mqtt-fan/build/linux && $(MAKE) clean + cd $(PROTOCOL_ROOT)plugins/mqtt-light/build/linux && $(MAKE) clean cd $(PROTOCOL_ROOT)plugins/hue/build/linux && $(MAKE) clean cd $(PROTOCOL_ROOT)sample-app/linux/fan-control && $(MAKE) clean rm -rf release diff --git a/service/protocol-plugin/plugin-manager/build/linux/Makefile b/service/protocol-plugin/plugin-manager/build/linux/Makefile index 908d8b0..f6187f4 100644 --- a/service/protocol-plugin/plugin-manager/build/linux/Makefile +++ b/service/protocol-plugin/plugin-manager/build/linux/Makefile @@ -1,45 +1,43 @@ -include ../../../config.mk - CXX = g++ CXX_FLAGS = -std=c++0x -Wall CPLUFF_DIR = ../../../lib/cpluff/libcpluff -LIB_DIR = ../../../../../resource - SRC = ../../src/ -CXX_INC = -I. -I$(CPLUFF_DIR) -CXX_INC += -I$(BOOST_DIR) -CXX_INC += -I$(LIB_DIR)/include/ -CXX_INC += -I$(LIB_DIR)/csdk/stack/include/ -CXX_INC += -I$(LIB_DIR)/csdk/ocsocket/include/ -CXX_INC += -I$(LIB_DIR)/csdk/ocrandom/include/ -CXX_INC += -I$(LIB_DIR)/csdk/logger/include/ +CXX_INC = -I. -I$(CPLUFF_DIR) -LINK_LIB = -ldl -lexpat -lboost_thread -lboost_system +LINK_LIB = -lboost_system -ldl -lexpat -lboost_thread +CXX_LIBS = $(CPLUFF_DIR)/.libs/libcpluff.a -PHONY : ppm -#PluginLifecycleManager.o +PHONY :libppm.a libpmimpl.so all: .PHONY + +libppm.a:PluginManager.o Plugin.o + ar -cvr libppm.a PluginManager.o Plugin.o + +PluginManager.o : $(SRC)PluginManager.cpp + $(CXX) $(CXX_INC) -c $(CXX_FLAGS) -Wsign-compare $(SRC)PluginManager.cpp -ppm: PluginManager.o Plugin.o PluginManagerService.o - $(CXX) $(CXX_INC) -o $@ $^ $(CPLUFF_DIR)/.libs/libcpluff.a $(LIB_DIR)/build/linux/release/obj/liboc.a $(LIB_DIR)/csdk/build/linux/release/liboctbstack.a $(LINK_LIB) -PluginManagerService.o : $(SRC)PluginManagerService.cpp - $(CXX) $(CXX_INC) -c -fpermissive $(CXX_FLAGS) $(SRC)PluginManagerService.cpp +libpmimpl.so:PluginManagerImpl.o Plugin.o CpluffAdapter.o FelixAdapter.o $(CPLUFF_DIR)/.libs/libcpluff.a + $(CXX) -shared -o libpmimpl.so PluginManagerImpl.o Plugin.o CpluffAdapter.o FelixAdapter.o $(CXX_LIBS) $(LINK_LIB) -PluginManager.o : $(SRC)PluginManager.cpp - $(CXX) $(CXX_INC) -c $(CXX_FLAGS) -Wsign-compare $(SRC)PluginManager.cpp +PluginManagerImpl.o : $(SRC)PluginManagerImpl.cpp + $(CXX) $(CXX_INC) -fPIC -c $(CXX_FLAGS) -Wsign-compare $(SRC)PluginManagerImpl.cpp Plugin.o : $(SRC)Plugin.cpp - $(CXX) $(CXX_INC) -c $(SRC)Plugin.cpp + $(CXX) $(CXX_INC) -fPIC -c $(SRC)Plugin.cpp + +CpluffAdapter.o : $(SRC)CpluffAdapter.cpp + $(CXX) $(CXX_INC) -c $(CXX_FLAGS) -Wsign-compare $(SRC)CpluffAdapter.cpp -#PluginLifecycleManager.o : PluginLifecycleManager.cpp -# $(CXX) $(CXX_INC) -c PluginLifecycleManager.cpp +FelixAdapter.o : $(SRC)FelixAdapter.cpp + $(CXX) $(CXX_INC) -c $(CXX_FLAGS) -Wsign-compare $(SRC)FelixAdapter.cpp -clean: +clean: rm -rf *.o - rm -f ppm + rm -rf *.a + rm -rf *.so diff --git a/service/protocol-plugin/plugin-manager/src/CpluffAdapter.cpp b/service/protocol-plugin/plugin-manager/src/CpluffAdapter.cpp new file mode 100644 index 0000000..b3d60e4 --- /dev/null +++ b/service/protocol-plugin/plugin-manager/src/CpluffAdapter.cpp @@ -0,0 +1,575 @@ +//****************************************************************** +// +// 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 CpluffAdapter.cpp + +/// @brief + +#include "CpluffAdapter.h" + +using namespace OIC; + +CpluffAdapter *CpluffAdapter::s_pinstance; + +CpluffAdapter::CpluffAdapter() +{ + m_status = cp_init(); + m_context = cp_create_context(&m_status); + m_cp_plugins = nullptr; + m_plugin = nullptr; + registerAllPlugin("../../../plugins"); +} + +CpluffAdapter::~CpluffAdapter(void) +{ + cp_release_info(m_context, m_cp_plugins); + m_thread_g.interrupt_all(); + m_thread_g.join_all(); + s_pinstance->deleteinstance(); + s_pinstance = nullptr; +} + +int CpluffAdapter::installPlugin(const std::string path) +{ + char *argv = const_cast(path.c_str()); + + if ((m_plugin = cp_load_plugin_descriptor(m_context, argv, &m_status)) == nullptr) + { + printf("cp_load_plugin_descriptor failed\n"); + return false; + } + else if ((m_status = cp_install_plugin(m_context, m_plugin)) != 0) + { + printf("cp_install_plugin failed\n"); + return false; + } + + return true; +} + +int CpluffAdapter::findPluginRecursive(const std::string path) +{ + ////////FILELIST//////////// + File_list file_list; + getFileList(file_list, path); + File_list::iterator itr; + int flag = FALSE; + + for (itr = file_list.begin(); itr != file_list.end(); itr++) + { + if (itr->second == true) + { + //printf("[Direcotry] %s\n",itr->first.c_str()); + } + else + { + //printf("[FILE] = %s\n" , itr->first.c_str()); + std::string filepath = itr->first.c_str(); + int count = 0; + for (unsigned int i = 0 ; i < filepath.size(); i++) + { + if (filepath.at(i) == '/') + { + count = i; + } + } + std::string filename = filepath.substr(0, count ); + //char *temp_char = const_cast(filename.c_str()); + flag = installPlugin(filename); + //printf("plugin file path %s \n", plugin->plugin_path); + } + } + + return flag; +} + +int CpluffAdapter::loadPluginInfoToManager(const std::string path) +{ + //get plugins information. + if ((m_cp_plugins = cp_get_plugins_info(m_context, &m_status, nullptr)) == nullptr) + { + printf("cp_get_plugins_infor failed\n"); + return FALSE; + } + else + { + printPluginList(m_cp_plugins); + } + + for (int i = 0 ; m_cp_plugins[i] != nullptr; i++) + { + Plugin *plugin = new Plugin; + plugin->setValue("Path", m_cp_plugins[i]->plugin_path); + plugin->setValue("Language", "CPP"); + //printf("add filepath %s\n",m_cp_plugins[i]->plugin_path); + if (m_cp_plugins[i]->identifier != nullptr) + { + plugin->setValue("Id", m_cp_plugins[i]->identifier ); + } + else + { + plugin->setValue("Id", ""); + } + + if (m_cp_plugins[i]->url != nullptr) + { + plugin->setValue("Url", m_cp_plugins[i]->url); + } + else + { + plugin->setValue("Url", ""); + } + + if (m_cp_plugins[i]->name != nullptr) + { + plugin->setValue("Name", m_cp_plugins[i]->name); + } + else + { + plugin->setValue("Name", ""); + } + + if (m_cp_plugins[i]->resourcetype != nullptr) + { + plugin->setValue("ResourceType", m_cp_plugins[i]->resourcetype); + } + else + { + plugin->setValue("ResourceType", ""); + } + + if (m_cp_plugins[i]->version != nullptr) + { + plugin->setValue("Version", m_cp_plugins[i]->version); + } + else + { + plugin->setValue("Version", ""); + } + + bool plugin_compare_flag = true; + for (unsigned int i = 0 ; i < m_plugins.size(); i++) + { + if (*plugin == m_plugins[i]) + { + delete(plugin); + plugin_compare_flag = false; + break; + } + } + if (plugin_compare_flag) + { + m_plugins.push_back(*plugin); + try + { + boost::thread *t = new boost::thread(boost::bind(&CpluffAdapter::observePluginPath, + //this, (void *)path.c_str())); + this, (void *)m_cp_plugins[i]->plugin_path)); + m_thread_g.add_thread(t); + } + catch (...) + { + printf("thread throw exception\n"); + } + delete(plugin); + } + //printf("plugin size = %d\n",m_plugins.size()); + } + + return TRUE; +} + +int CpluffAdapter::registerPlugin(const std::string path) +{ + //printf("CpluffAdapter register\n"); + int flag = FALSE; + + if (path == "") + { + printf("CpluffAdapter path == null\n"); + return flag; + } + + //non recursive + + flag = installPlugin(path); + + flag = loadPluginInfoToManager(path); + + return flag; +} + +int CpluffAdapter::registerAllPlugin(const std::string path) +{ + //printf("CpluffAdapter register\n"); + int flag = FALSE; + if (path == "") + { + printf("CpluffAdapter path == null\n"); + return flag; + } + + //recursive + + flag = findPluginRecursive(path); + + flag = loadPluginInfoToManager(path); + + return flag; +} + +int CpluffAdapter::unregisterPlugin(Plugin *const plugin) +{ + cp_status_t status; + char *argv = nullptr; + std::string id = ""; + + for (unsigned int i = 0; i < m_plugins.size(); i++) + { + + if (*plugin == m_plugins[i]) + { + id = m_plugins[i].getID().c_str(); + argv = const_cast(id.c_str()); + if ((status = cp_uninstall_plugin(m_context, argv)) != 0) + { + printf("unregister failed\n"); + return FALSE; + } + m_plugins.erase(m_plugins.begin() + i); + } + } + return TRUE; +} + +int CpluffAdapter::unregisterAllPlugin(void) +{ + cp_status_t status; + char *argv = nullptr; + std::string id = ""; + + while (true) + { + id = m_plugins[0].getID().c_str(); + argv = const_cast(id.c_str()); + if ((status = cp_uninstall_plugin(m_context, argv)) != 0) + { + printf("unregister failed\n"); + return FALSE; + } + m_plugins.erase(m_plugins.begin()); + if (m_plugins.size() == 0) + { + break; + } + } + + return TRUE; +} + +std::vector &CpluffAdapter::getAllPlugins(void) +{ + return m_plugins; +} + +std::vector *CpluffAdapter::findPlugins(const std::string key, const std::string value) +{ + std::vector *re_plugins; + + re_plugins = new std::vector; + + for (unsigned int i = 0; i < m_plugins.size(); i++) + { + if (!m_plugins[i].getValueByAttribute(key).compare(value)) + { + re_plugins->push_back(m_plugins[i]); + } + } + + return re_plugins; +} +/* +Plugin *CpluffAdapter::getPlugin(const std::string plugID) +{ + for (unsigned int i = 0; i < m_plugins.size(); i++) + { + if (!(m_plugins[i].getID().compare(plugID))) + { + return &(m_plugins[i]); + } + } + + return nullptr; +} +*/ +bool CpluffAdapter::getFileList(File_list &list, const std::string strDir) +{ + struct stat statinfo; + memset(&statinfo, 0, sizeof(statinfo)); + std::string path = strDir; + if (0 != lstat(path.c_str(), &statinfo)) + { + printf("OICPlugManager lstat is 0\n"); + return false; + } + if (!S_ISDIR(statinfo.st_mode)) + { + printf("%s is not directory", strDir.c_str()); + return false; + } + + DIR *dir; + struct dirent *entry; + + if ((dir = opendir(strDir.c_str())) == nullptr) + { + printf("%s open error", strDir.c_str()); + return false; + } + + while ((entry = readdir(dir)) != nullptr) + { + memset(&statinfo, 0, sizeof(statinfo)); + std::string strFilePath = strDir + "/" + entry->d_name; + while (strFilePath.find("//") != std::string::npos) + strFilePath.replace(strFilePath.find("//"), 2, "/"); + + if (0 != lstat(strFilePath.c_str(), &statinfo)) + { + printf("OICPlugManager lstat is 0\n"); + closedir(dir); + return false; + } + + if (S_ISDIR(statinfo.st_mode)) + { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; + + list.insert(std::pair(strFilePath, true)); + std::string strSubDir = strDir + "/" + entry->d_name; + getFileList(list, strSubDir); + } + else + { + int size = strFilePath.size(); + std::string so = strFilePath.substr(size - 2, size - 1); + if (so == "so") + { + list.insert(std::pair(strFilePath, false)); + } + } + } + closedir(dir); + + return true; +} + +const char *CpluffAdapter::state_to_string(int state) +{ + switch (state) + { + case 0: + return "UNINTALLED"; + case 1: + return "INSTALLED"; + case 2: + return "RESOLVED"; + case 3: + return "STARTING"; + case 4: + return "STOPPING"; + case 5: + return "ACTIVE"; + default: + return "Unknown"; + } +} + +void CpluffAdapter::printPluginList(cp_plugin_info_t **plugins) +{ + const char format[] = " %-30s %-15s %-15s %-20s\n"; + printf("\n====== Plugins List ======\n"); + printf(format, + "ID", + "NAME", + "STATE", + "TYPE"); + + for (int i = 0; m_cp_plugins[i] != nullptr; i++) + { + printf(format, + m_cp_plugins[i]->identifier, + m_cp_plugins[i]->name != nullptr ? m_cp_plugins[i]->name : "", + state_to_string(cp_get_plugin_state(m_context, m_cp_plugins[i]->identifier)), + m_cp_plugins[i]->resourcetype != nullptr ? m_cp_plugins[i]->resourcetype : ""); + } + printf("\n"); +} + +int CpluffAdapter::start(Plugin *const plugin, void *const arg) +{ + //printf("start\n"); + std::string id; + cp_status_t status; + cp_context_t *ctx; + + id = plugin->getID(); + for (unsigned int i = 0 ; i < m_plugins.size(); i++) + { + if (*plugin == m_plugins[i]) + { + ctx = cpi_new_context((cp_plugin_t *)hnode_get(hash_lookup(m_context->env->plugins, id.c_str())), + m_context->env, &status); + cp_define_symbol(ctx, "START_ARGUMENT", arg); + //printf("start ocplatform address : %x\n", arg); + + if ((status = cp_start_plugin(m_context, (char *)id.c_str()) ) != CP_OK) + { + printf("API function CpluffAdapter::start() faild with error code.\n"); + return FALSE; + } + else + { + printf("start plug-in %s.\n", (char *)id.c_str()); + } + + break; + } + } + return TRUE; +} + +int CpluffAdapter::stop(Plugin *const plugin) +{ + std::string id; + cp_status_t status; + + id = plugin->getID(); + printf("stop plugin id = %s\n", id.c_str()); + if ((status = cp_stop_plugin(m_context, (char *)id.c_str())) != CP_OK) + { + printf("API function CpluffAdapter::stop() faild with error code.\n"); + return FALSE; + } + else + { + printf("Stop plug-in %s.\n", (char *)id.c_str()); + } + + return TRUE; +} + +bool CpluffAdapter::isStarted(Plugin *plugin) +{ + std::string id; + cp_plugin_state_t state; + + id = plugin->getID(); + + state = cp_get_plugin_state(m_context, (char *)id.c_str()); + if (state == CP_PLUGIN_STARTING || state == CP_PLUGIN_ACTIVE) + { + return TRUE; + } + return FALSE; +} + +void CpluffAdapter::observePluginPath(void *str) +{ + //printf("start observePluginPath\n"); + int length; + int i = 0; + int fd; + int wd; + char *str1 = (char *)str; + std::string original_path(str1); + //printf("Directory is %s\n",(char*)str1)); + char buffer[BUF_LEN]; + + fd = inotify_init(); + + if ( fd < 0 ) + { + printf("inotify_init\n"); + } + + wd = inotify_add_watch( fd, str1, + IN_MODIFY | IN_CREATE | IN_DELETE | IN_DELETE_SELF + | IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO); + + while (true) + { + //printf("read start\n"); + i = 0; + length = read( fd, buffer, BUF_LEN ); + + if ( length < 0 ) + { + printf("observePluginPath read\n"); + } + std::string filepath = original_path; + //printf("filepath = %s\n",filepath.c_str()); + while ( i < length ) + { + if (i < (signed)(BUF_LEN - ( sizeof( struct inotify_event) + 16)) && i > -1) + { + struct inotify_event *event = ( struct inotify_event *) &buffer[ i ]; + + if ((event->mask & IN_CREATE) || (event->mask & IN_MODIFY) || (event->mask & IN_MOVED_TO)) + { + registerAllPlugin(str1); + } + else + { + //filepath += "/"; + //filepath += std::string(event->name); + std::vector *resource_plugin = findPlugins("Path", filepath.c_str()); //add foldername + + //printf("plugin size is %d\n",resource_plugin->size()); + //printf("plugin file path is %s\n",resource_plugin->()); + if (resource_plugin->size() == 1) + { + unregisterPlugin(&(resource_plugin->at(0))); + } + else + { + registerAllPlugin(str1); + } + delete(resource_plugin); + resource_plugin = nullptr; + } + //printf("observePluginPath path = %s \n",str1); + //printf("observePluginPath directory name = %s \n",event->name); + i += EVENT_SIZE + event->len; + } + } + + + } + ( void ) inotify_rm_watch( fd, wd ); + ( void ) close( fd ); + //printf("observePluginPath end\n"); +} + +const std::string CpluffAdapter::getState(const std::string plugID) +{ + return state_to_string(cp_get_plugin_state(m_context, plugID.c_str())); +} \ No newline at end of file diff --git a/service/protocol-plugin/plugin-manager/src/CpluffAdapter.h b/service/protocol-plugin/plugin-manager/src/CpluffAdapter.h new file mode 100644 index 0000000..ec565d3 --- /dev/null +++ b/service/protocol-plugin/plugin-manager/src/CpluffAdapter.h @@ -0,0 +1,279 @@ +//****************************************************************** +// +// 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 CpluffAdapter.h + +/// @brief + +#ifndef __CPLUFFADAPTER_H +#define __CPLUFFADAPTER_H +#define DLOPEN_POSIX + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Plugin.h" + +#define EVENT_SIZE ( sizeof (struct inotify_event) ) +#define BUF_LEN (int)( 1024 * ( EVENT_SIZE + 16 ) ) + +namespace OIC +{ + /** + * @brief After installing a plug-in in a directory, each plug-ins can be managed by this class. + * + * + */ + class CpluffAdapter + { + public: + /** + * A function to register pluins in the path. + * This function will load plugins in plugin manager table. + * + * @param path plugin file path to be registered. + * @return int, 1 is success, 0 is fail. + * + * NOTE: + * + */ + int registerPlugin(const std::string path); + + + /** + * A function to register pluins in the path. + * This function will load plugins in plugin manager table. + * + * @param path plugin file path to be registered. + * recursive load plugins sub folders recursively. + * @return int, 1 is success, 0 is fail. + * + * NOTE: + * + */ + int registerAllPlugin(const std::string path); + + + /** + * Unregister plugin. + * + * @param plugin plugin object to be unregistered. + * @return int, 1 is success, 0 is fail. + */ + int unregisterPlugin(Plugin *const plugin); + + + /** + * Unregister All plugin. + * + * @return int, 1 is success, 0 is fail. + */ + int unregisterAllPlugin(void); + + + /** + * get all plugins which currently registered. + * + * @return vector of currently registered plugins + * + */ + std::vector &getAllPlugins(void); + + + /** + * find plugins which have the key and value + * + * @return vector of currently registered plugins + */ + std::vector *findPlugins(const std::string key, const std::string value); + + + /** + * Get plugin which has the id + * + * @param pluginID plugin id to find + * @return Plugin instance + */ + //Plugin *getPlugin(const std::string pluginID); + + /** + * Start plugin + * This function will load dynamic plugin library on memory and call start function of plugin to be initialized. + * + * @param Plugin + * @param Platform pointer. + * @return int, 1 is success, 0 is fail. + */ + int start(Plugin *const plugin, void *const arg); + + + /** + * Stop Plugin. + * This function will call stop function of plugin and unload dynamic plugin library from memory. + * + * @param Plugin + * @return int, 1 is success, 0 is fail. + */ + int stop(Plugin *const plugin); + + + /** + * Check whether the plugin started or not + * + * @param Plugin to identify the Starting. + * @return true if started, false is stop. + * + */ + bool isStarted(Plugin *plugin); + + + /** + * Get Plugin state. + * + * @param Plugin ID + * @return Plugin state. + */ + const std::string getState(const std::string plugID); + + + /** + * + * new Singleton pattern instance. + * + * @return OICPluginManager pointer Address. + */ + static CpluffAdapter *Getinstance() + { + if (NULL == s_pinstance) + { + s_pinstance = new CpluffAdapter(); + } + + return s_pinstance; + } + + + + private: + + typedef std::map File_list; + std::vector m_plugins; + cp_context_t *m_context; + cp_status_t m_status; + cp_plugin_info_t **m_cp_plugins; + cp_plugin_info_t *m_plugin; + boost::thread m_file_detect_thread; + boost::thread_group m_thread_g; + std::string m_path; + static CpluffAdapter *s_pinstance; + + /** + * Constructor for CpluffAdapter. + * During construction time, all plugins under the root plugin path will be loaded. + * + */ + CpluffAdapter(); + + /** + * Virtual destructor + */ + virtual ~CpluffAdapter(void); + + /** + * delete Singleton pattern instance. + */ + static void deleteinstance() + { + if (NULL != s_pinstance) + { + delete s_pinstance; + s_pinstance = NULL; + } + } + + /** + * detect plugins(add, delete, move) + * + * @param plugin file path. + * @return void + */ + void observePluginPath(void *); + + + /** + * change Number to String. + * + * @param int. + * @return State String. + */ + const char *state_to_string(int state); + + /** + * Get whole "SO" file list. + * + * @param OUT, SO file list. + * @param Root path. + * @return true or false. + */ + bool getFileList(File_list &list, const std::string strDir); + + /** + * print whole plugin info. + * + * @param cpluff plugins + */ + void printPluginList(cp_plugin_info_t **plugins); + + /** + * install plugin using c-pluff. + * + * @param Root path. + * @return int, 1 is success, 0 is fail. + */ + int installPlugin(const std::string path); + + + /** + * find Plugin and install plugin.(Recursive) + * + * @param Root path. + * @return int, 1 is success, 0 is fail. + */ + int findPluginRecursive(const std::string path); + + /** + * load Plugin information to PluginManager table. + * + * @param path to observe + * @return int, 1 is success, 0 is fail. + */ + int loadPluginInfoToManager(const std::string path); + }; +} + +#endif //__CPLUFFADAPTER_H diff --git a/service/protocol-plugin/plugin-manager/src/FelixAdapter.cpp b/service/protocol-plugin/plugin-manager/src/FelixAdapter.cpp new file mode 100644 index 0000000..0247e74 --- /dev/null +++ b/service/protocol-plugin/plugin-manager/src/FelixAdapter.cpp @@ -0,0 +1,125 @@ +//****************************************************************** +// +// 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 FelixAdapter.cpp + +/// @brief + +#include "FelixAdapter.h" + +using namespace OIC; + +FelixAdapter *FelixAdapter::s_pinstance; + +FelixAdapter::FelixAdapter() +{ + +} + +FelixAdapter::~FelixAdapter(void) +{ + s_pinstance->deleteinstance(); +} + +int FelixAdapter::installPlugin(const std::string path) +{ + return 1; +} + +int FelixAdapter::findPluginRecursive(const std::string path) +{ + return 1; +} + +int FelixAdapter::loadPluginInfoToManager(const std::string path) +{ + return 1; +} + +int FelixAdapter::registerPlugin(const std::string path) +{ + return 1; +} + +int FelixAdapter::registerAllPlugin(const std::string path) +{ + return 1; +} + +int FelixAdapter::unregisterPlugin(Plugin *const plugin) +{ + return 1; +} + +int FelixAdapter::unregisterAllPlugin(void) +{ + return 1; +} + +std::vector &FelixAdapter::getAllPlugins(void) +{ + return m_plugins; +} + +std::vector *FelixAdapter::findPlugins(const std::string key, const std::string value) +{ + return nullptr; +} +/* +Plugin *FelixAdapter::getPlugin(const std::string plugID) +{ + return nullptr; +} +*/ +bool FelixAdapter::getFileList(File_list &list, const std::string strDir) +{ + return true; +} + + +void FelixAdapter::printPluginList(cp_plugin_info_t **plugins) +{ + +} + +int FelixAdapter::start(Plugin *const plugin, void *const arg) +{ + return TRUE; +} + +int FelixAdapter::stop(Plugin *const plugin) +{ + return TRUE; +} + +bool FelixAdapter::isStarted(Plugin *plugin) +{ + return FALSE; +} + +void FelixAdapter::observePluginPath(void *str) +{ + +} + +const std::string FelixAdapter::getState(const std::string plugID) +{ + return ""; +} \ No newline at end of file diff --git a/service/protocol-plugin/plugin-manager/src/FelixAdapter.h b/service/protocol-plugin/plugin-manager/src/FelixAdapter.h new file mode 100644 index 0000000..3842184 --- /dev/null +++ b/service/protocol-plugin/plugin-manager/src/FelixAdapter.h @@ -0,0 +1,272 @@ +//****************************************************************** +// +// 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 FelixAdapter.h + +/// @brief + +#ifndef __FELIXADAPTER_H__ +#define __FELIXADAPTER_H__ +#define DLOPEN_POSIX + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Plugin.h" + +#define EVENT_SIZE ( sizeof (struct inotify_event) ) +#define BUF_LEN (int)( 1024 * ( EVENT_SIZE + 16 ) ) + +namespace OIC +{ + /** + * @brief After installing a plug-in in a directory, each plug-ins can be managed by this class. + * + * + */ + class FelixAdapter + { + public: + /** + * A function to register pluins in the path. + * This function will load plugins in plugin manager table. + * + * @param path plugin file path to be registered. + * @return int, 1 is success, 0 is fail. + * + * NOTE: + * + */ + int registerPlugin(const std::string path); + + + /** + * A function to register pluins in the path. + * This function will load plugins in plugin manager table. + * + * @param path plugin file path to be registered. + * recursive load plugins sub folders recursively. + * @return int, 1 is success, 0 is fail. + * + * NOTE: + * + */ + int registerAllPlugin(const std::string path); + + + /** + * Unregister plugin. + * + * @param plugin plugin object to be unregistered. + * @return int, 1 is success, 0 is fail. + */ + int unregisterPlugin(Plugin *const plugin); + + + /** + * Unregister All plugin. + * + * @return int, 1 is success, 0 is fail. + */ + int unregisterAllPlugin(void); + + + /** + * get all plugins which currently registered. + * + * @return vector of currently registered plugins + * + */ + std::vector &getAllPlugins(void); + + + /** + * find plugins which have the key and value + * + * @return vector of currently registered plugins + */ + std::vector *findPlugins(const std::string key, const std::string value); + + + /** + * Get plugin which has the id + * + * @param pluginID plugin id to find + * @return Plugin instance + */ + //Plugin *getPlugin(const std::string pluginID); + + /** + * Start plugin + * This function will load dynamic plugin library on memory and call start function of plugin to be initialized. + * + * @param Plugin + * @param Platform pointer. + * @return int, 1 is success, 0 is fail. + */ + int start(Plugin *const plugin, void *const arg); + + + /** + * Stop Plugin. + * This function will call stop function of plugin and unload dynamic plugin library from memory. + * + * @param Plugin + * @return int, 1 is success, 0 is fail. + */ + int stop(Plugin *const plugin); + + + /** + * Check whether the plugin started or not + * + * @param Plugin to identify the Starting. + * @return true if started, false is stop. + * + */ + bool isStarted(Plugin *plugin); + + + /** + * Get Plugin state. + * + * @param Plugin ID + * @return Plugin state. + */ + const std::string getState(const std::string plugID); + + + /** + * + * new Singleton pattern instance. + * + * @return OICPluginManager pointer Address. + */ + static FelixAdapter *Getinstance() + { + if (NULL == s_pinstance) + { + s_pinstance = new FelixAdapter(); + } + + return s_pinstance; + } + + + + private: + + typedef std::map File_list; + std::vector m_plugins; + boost::thread m_file_detect_thread; + /* + cp_context_t *m_context; + cp_status_t m_status; + cp_plugin_info_t **m_cp_plugins; + cp_plugin_info_t *m_plugin; + boost::thread_group m_thread_g; + std::string m_path; + */ + static FelixAdapter *s_pinstance; + + /** + * Constructor for FelixAdapter. + * During construction time, all plugins under the root plugin path will be loaded. + * + */ + FelixAdapter(); + + /** + * Virtual destructor + */ + virtual ~FelixAdapter(void); + + /** + * delete Singleton pattern instance. + */ + static void deleteinstance() + { + if (NULL != s_pinstance) + { + delete s_pinstance; + s_pinstance = NULL; + } + } + + /** + * detect plugins(add, delete, move) + * + * @param plugin file path. + * @return void + */ + void observePluginPath(void *); + + /** + * Get whole "SO" file list. + * + * @param OUT, SO file list. + * @param Root path. + * @return true or false. + */ + bool getFileList(File_list &list, const std::string strDir); + + /** + * print whole plugin info. + * + * @param Felix plugins + */ + void printPluginList(cp_plugin_info_t **plugins); + + /** + * install plugin using c-pluff. + * + * @param Root path. + * @return int, 1 is success, 0 is fail. + */ + int installPlugin(const std::string path); + + + /** + * find Plugin and install plugin.(Recursive) + * + * @param Root path. + * @return int, 1 is success, 0 is fail. + */ + int findPluginRecursive(const std::string path); + + /** + * load Plugin information to PluginManager table. + * + * @param path to observe + * @return int, 1 is success, 0 is fail. + */ + int loadPluginInfoToManager(const std::string path); + }; +} + +#endif //__FELIXADAPTER_H__ diff --git a/service/protocol-plugin/plugin-manager/src/Plugin.h b/service/protocol-plugin/plugin-manager/src/Plugin.h index 8694143..bd823d8 100644 --- a/service/protocol-plugin/plugin-manager/src/Plugin.h +++ b/service/protocol-plugin/plugin-manager/src/Plugin.h @@ -23,8 +23,8 @@ /// @brief -#ifndef __OCPLUGIN_H__ -#define __OCPLUGIN_H__ +#ifndef __Plugin_H__ +#define __Plugin_H__ #define TRUE 1 #define FALSE 0 @@ -165,4 +165,4 @@ namespace OIC } -#endif //__OCPLUGIN_H__ +#endif //__Plugin_H__ diff --git a/service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.cpp b/service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.cpp deleted file mode 100644 index 2f4937a..0000000 --- a/service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 Samsung Electronics All Rights Reserved. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -/// @file PluginLifecycleManager.cpp - -/// @brief - -#include - -using namespace OIC; - -PluginLifeCycleManager::PluginLifeCycleManager() -{ - //struct PluginManagerConfig pmconfig; - //pmconfig.rootPluinPath = "./../plugins"; - pm = new PluginManager(); -} - -PluginLifeCycleManager::~PluginLifeCycleManager() -{ - delete(pm); -} - -void PluginLifeCycleManager::startPluginsByResourceType(const std::string type) -{ - std::string resourcetype = ""; - int size = type.size(); - - //Parsing Resource_Type - for (int i = size - 1; i > -1 ; i--) - { - if (type.at(i) == '.' && type.at(i) == '/') - { - break; - } - resourcetype += type.at(i); - } - - //Reverse string(Resource type) - - reverse(resourcetype.begin(), resourcetype.end()); - - // printf("resource type = %s\n", resourcetype.c_str()); - - //Search Plugin - std::vector resource_plugin = pm->getPlugins("ResourceType", resourcetype); - - //start Plugin - std::vector::iterator it; - for (it = resource_plugin.begin(); it != resource_plugin.end(); it++) - { - if (!pm->isStarted(&(*it))) // started : 1, stop : 0 - { - pm->start(&(*it)); - } - } -} - -void PluginLifeCycleManager::stopPluginsByResourceType(const std::string type) -{ - std::string resourcetype = ""; - int size = type.size(); - - //Parsing Resource_Type - for (int i = size - 1; i > -1 ; i--) - { - if (type.at(i) == '.' && type.at(i) == '/') - { - break; - } - resourcetype += type.at(i); - } - - //Reverse string(Resource type) - - reverse(resourcetype.begin(), resourcetype.end()); - - // printf("resource type = %s\n", resourcetype.c_str()); - - //Search Plugin - std::vector resource_plugin = pm->getPlugins("ResourceType", resourcetype); - - //stop Plugin - std::vector::iterator it; - for (it = resource_plugin.begin(); it != resource_plugin.end(); it++) - { - if (pm->isStarted(&(*it))) // started : 1, stop : 0 - { - pm->stop(&(*it)); - } - } -} \ No newline at end of file diff --git a/service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.h b/service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.h deleted file mode 100644 index 7179298..0000000 --- a/service/protocol-plugin/plugin-manager/src/PluginLifecycleManager.h +++ /dev/null @@ -1,70 +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 ProtocolLifecycleManager.h - -/// @brief - -#ifndef __PLUGINLIFECYCLEMANAGER_H -#define __PLUGINLIFECYCLEMANAGER_H - -#include -#include - -namespace OIC -{ - - /** - * @brief Protocol plugin's lifecycle can be controlled by this class. - * - * - */ - class PluginLifeCycleManager - { - public: - - PluginLifeCycleManager(); - - ~PluginLifeCycleManager(); - - - /** - * Start protocol plugins by resource type - * - * @param type resouce type string to be started. - * - */ - void startPluginsByResourceType(const std::string type); - - /** - * Stop protocol plugins by resource type - * - * @param type resouce type string to be started. - * - */ - void stopPluginsByResourceType(const std::string type); - private: - PluginManager *pm; - - }; -} - -#endif __PLUGINLIFECYCLEMANAGER_H - diff --git a/service/protocol-plugin/plugin-manager/src/PluginManager.cpp b/service/protocol-plugin/plugin-manager/src/PluginManager.cpp index 2d8b634..7c158ca 100644 --- a/service/protocol-plugin/plugin-manager/src/PluginManager.cpp +++ b/service/protocol-plugin/plugin-manager/src/PluginManager.cpp @@ -22,555 +22,52 @@ /// @brief + #include "PluginManager.h" using namespace OIC; PluginManager::PluginManager() { - //printf("PluginManager construct\n"); - m_status = cp_init(); - m_context = cp_create_context(&m_status); - m_cp_plugins = NULL; - m_plugin = NULL; -} - -PluginManager::~PluginManager(void) -{ - //printf("~PlugingManager\n"); - cp_release_info(m_context, m_cp_plugins); - m_thread_g.interrupt_all(); - m_thread_g.join_all(); - s_pinstance->deleteinstance(); - s_pinstance = NULL; -} - -int PluginManager::installPlugin(const std::string path) -{ - char *argv = const_cast(path.c_str()); - - if ((m_plugin = cp_load_plugin_descriptor(m_context, argv, &m_status)) == NULL) - { - printf("cp_load_plugin_descriptor failed\n"); - return false; - } - else if ((m_status = cp_install_plugin(m_context, m_plugin)) != 0) - { - printf("cp_install_plugin failed\n"); - return false; - } - - return true; -} - -int PluginManager::findPluginRecursive(const std::string path) -{ - ////////FILELIST//////////// - File_list file_list; - getFileList(file_list, path); - File_list::iterator itr; - int flag = FALSE; - - for (itr = file_list.begin(); itr != file_list.end(); itr++) - { - if (itr->second == true) - { - //printf("[Direcotry] %s\n",itr->first.c_str()); - } - else - { - //printf("[FILE] = %s\n" , itr->first.c_str()); - std::string filepath = itr->first.c_str(); - int count = 0; - for (unsigned int i = 0 ; i < filepath.size(); i++) - { - if (filepath.at(i) == '/') - { - count = i; - } - } - std::string filename = filepath.substr(0, count ); - //char *temp_char = const_cast(filename.c_str()); - flag = installPlugin(filename); - //printf("plugin file path %s \n", plugin->plugin_path); - } - } - - return flag; -} - -int PluginManager::loadPluginInfoToManager(const std::string path) -{ - //get plugins information. - if ((m_cp_plugins = cp_get_plugins_info(m_context, &m_status, NULL)) == NULL) - { - printf("cp_get_plugins_infor failed\n"); - return FALSE; - } - else - { - printPluginList(m_cp_plugins); - } - - for (int i = 0 ; m_cp_plugins[i] != NULL; i++) - { - Plugin *plugin = new Plugin; - plugin->setValue("Path", m_cp_plugins[i]->plugin_path); - //printf("add filepath %s\n",m_cp_plugins[i]->plugin_path); - if (m_cp_plugins[i]->identifier != NULL) - { - plugin->setValue("Id", m_cp_plugins[i]->identifier ); - } - else - { - plugin->setValue("Id", ""); - } - - if (m_cp_plugins[i]->url != NULL) - { - plugin->setValue("Url", m_cp_plugins[i]->url); - } - else - { - plugin->setValue("Url", ""); - } - - if (m_cp_plugins[i]->name != NULL) - { - plugin->setValue("Name", m_cp_plugins[i]->name); - } - else - { - plugin->setValue("Name", ""); - } - - if (m_cp_plugins[i]->resourcetype != NULL) - { - plugin->setValue("ResourceType", m_cp_plugins[i]->resourcetype); - } - else - { - plugin->setValue("ResourceType", ""); - } - - if (m_cp_plugins[i]->version != NULL) - { - plugin->setValue("Version", m_cp_plugins[i]->version); - } - else - { - plugin->setValue("Version", ""); - } - - bool plugin_compare_flag = true; - for (unsigned int i = 0 ; i < m_plugins.size(); i++) - { - if (*plugin == m_plugins[i]) - { - delete(plugin); - plugin_compare_flag = false; - break; - } - } - if (plugin_compare_flag) - { - m_plugins.push_back(*plugin); - try - { - boost::thread *t = new boost::thread(boost::bind(&PluginManager::observePluginPath, - //this, (void *)path.c_str())); - this, (void *)m_cp_plugins[i]->plugin_path)); - m_thread_g.add_thread(t); - } - catch (...) - { - printf("thread throw exception\n"); - } - delete(plugin); - } - //printf("plugin size = %d\n",m_plugins.size()); - } - - return TRUE; -} - -int PluginManager::registerPlugin(const std::string path) -{ - //printf("PluginManager register\n"); - int flag = FALSE; - - if (path == "") - { - printf("PluginManager path == null\n"); - return flag; - } - - //non recursive - - flag = installPlugin(path); - - flag = loadPluginInfoToManager(path); - - return flag; -} - -int PluginManager::registerAllPlugin(const std::string path) -{ - //printf("PluginManager register\n"); - int flag = FALSE; - if (path == "") - { - printf("PluginManager path == null\n"); - return flag; - } - - //recursive - - flag = findPluginRecursive(path); - - flag = loadPluginInfoToManager(path); - - return flag; -} - -int PluginManager::unregisterPlugin(Plugin *const plugin) -{ - cp_status_t status; - char *argv = NULL; - std::string id = ""; - - for (unsigned int i = 0; i < m_plugins.size(); i++) - { - - if (*plugin == m_plugins[i]) - { - id = m_plugins[i].getID().c_str(); - argv = const_cast(id.c_str()); - if ((status = cp_uninstall_plugin(m_context, argv)) != 0) - { - printf("unregister failed\n"); - return FALSE; - } - m_plugins.erase(m_plugins.begin() + i); - } - } - return TRUE; -} - -int PluginManager::unregisterAllPlugin(void) -{ - cp_status_t status; - char *argv = NULL; - std::string id = ""; - - while (true) + void *handle = dlopen("./libpmimpl.so", RTLD_LAZY); + if (!handle) { - id = m_plugins[0].getID().c_str(); - argv = const_cast(id.c_str()); - if ((status = cp_uninstall_plugin(m_context, argv)) != 0) - { - printf("unregister failed\n"); - return FALSE; - } - m_plugins.erase(m_plugins.begin()); - if (m_plugins.size() == 0) - { - break; - } + fprintf(stderr, "%s\n", dlerror()); + exit(EXIT_FAILURE); } - - return TRUE; + PluginManagerImpl* (*create)(); + create = (PluginManagerImpl * (*)())dlsym(handle, "create_object"); + destroy = (void (*)(PluginManagerImpl *))dlsym(handle, "destroy_object"); + pluginManagerImpl = (PluginManagerImpl *)create(); } -std::vector &PluginManager::getAllPlugins(void) -{ - return m_plugins; -} - -std::vector *PluginManager::findPlugins(const std::string key, - const std::string value) -{ - std::vector *re_plugins; - - re_plugins = new std::vector; - - for (unsigned int i = 0; i < m_plugins.size(); i++) - { - if (!m_plugins[i].getValueByAttribute(key).compare(value)) - { - re_plugins->push_back(m_plugins[i]); - } - } - - return re_plugins; -} - - - -Plugin *PluginManager::getPlugin(const std::string plugID) -{ - for (unsigned int i = 0; i < m_plugins.size(); i++) - { - if (!(m_plugins[i].getID().compare(plugID))) - { - return &(m_plugins[i]); - } - } - - return NULL; -} - -bool PluginManager::getFileList(File_list &list, const std::string strDir) -{ - struct stat statinfo; - memset(&statinfo, 0, sizeof(statinfo)); - std::string path = strDir; - if (0 != lstat(path.c_str(), &statinfo)) - { - printf("PlugManager lstat is 0\n"); - return false; - } - if (!S_ISDIR(statinfo.st_mode)) - { - printf("%s is not directory", strDir.c_str()); - return false; - } - - DIR *dir; - struct dirent *entry; - - if ((dir = opendir(strDir.c_str())) == NULL) - { - printf("%s open error", strDir.c_str()); - return false; - } - - while ((entry = readdir(dir)) != NULL) - { - memset(&statinfo, 0, sizeof(statinfo)); - std::string strFilePath = strDir + "/" + entry->d_name; - while (strFilePath.find("//") != std::string::npos) - strFilePath.replace(strFilePath.find("//"), 2, "/"); - - if (0 != lstat(strFilePath.c_str(), &statinfo)) - { - printf("PlugManager lstat is 0\n"); - closedir(dir); - return false; - } - - if (S_ISDIR(statinfo.st_mode)) - { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - - list.insert(std::pair(strFilePath, true)); - std::string strSubDir = strDir + "/" + entry->d_name; - getFileList(list, strSubDir); - } - else - { - int size = strFilePath.size(); - std::string so = strFilePath.substr(size - 2, size - 1); - if (so == "so") - { - list.insert(std::pair(strFilePath, false)); - } - } - } - closedir(dir); - - return true; -} - -const char *PluginManager::state_to_string(int state) -{ - switch (state) - { - case 0: - return "uninstalled"; - case 1: - return "installed"; - case 2: - return "resolved"; - case 3: - return "starting"; - case 4: - return "stopping"; - case 5: - return "active"; - default: - return "unknown"; - } -} - -void PluginManager::printPluginList(cp_plugin_info_t **plugins) +PluginManager::~PluginManager(void) { - const char format[] = " %-30s %-15s %-15s %-20s\n"; - printf("\n====== Plugins List ======\n"); - printf(format, - "ID", - "NAME", - "STATE", - "TYPE"); - - for (int i = 0; m_cp_plugins[i] != NULL; i++) - { - printf(format, - m_cp_plugins[i]->identifier, - m_cp_plugins[i]->name != NULL ? m_cp_plugins[i]->name : "", - state_to_string(cp_get_plugin_state(m_context, m_cp_plugins[i]->identifier)), - m_cp_plugins[i]->resourcetype != NULL ? m_cp_plugins[i]->resourcetype : ""); - } - printf("\n"); + destroy(pluginManagerImpl); } -int PluginManager::start(Plugin *const plugin, void *const arg) +int PluginManager::startPlugins(const std::string key, const std::string value) { - //printf("start\n"); - std::string id; - cp_status_t status; - cp_context_t *ctx; - - id = plugin->getID(); - for (unsigned int i = 0 ; i < m_plugins.size(); i++) - { - if (*plugin == m_plugins[i]) - { - ctx = cpi_new_context((cp_plugin_t *)hnode_get(hash_lookup(m_context->env->plugins, id.c_str())), - m_context->env, &status); - cp_define_symbol(ctx, "START_ARGUMENT", arg); - //printf("start ocplatform address : %x\n", arg); - - if ((status = cp_start_plugin(m_context, (char *)id.c_str()) ) != CP_OK) - { - printf("API function PluginManager::start() faild with error code.\n"); - return FALSE; - } - else - { - printf("start plug-in %s.\n", (char *)id.c_str()); - } - - break; - } - } - return TRUE; + return pluginManagerImpl->startPlugins(key, value); } -int PluginManager::stop(Plugin *const plugin) +int PluginManager::stopPlugins(const std::string key, const std::string value) { - std::string id; - cp_status_t status; - - id = plugin->getID(); - printf("stop plugin id = %s\n", id.c_str()); - if ((status = cp_stop_plugin(m_context, (char *)id.c_str())) != CP_OK) - { - printf("API function PluginManager::stop() faild with error code.\n"); - return FALSE; - } - else - { - printf("Stop plug-in %s.\n", (char *)id.c_str()); - } - - return TRUE; + return pluginManagerImpl->stopPlugins(key, value); } -bool PluginManager::isStarted(Plugin *plugin) +int PluginManager::startPlugins(Plugin *const plugin) { - std::string id; - cp_plugin_state_t state; - - id = plugin->getID(); - - state = cp_get_plugin_state(m_context, (char *)id.c_str()); - if (state == CP_PLUGIN_STARTING || state == CP_PLUGIN_ACTIVE) - { - return TRUE; - } - return FALSE; + printf("PluginManager::startPlugins\n"); + return pluginManagerImpl->startPlugins(plugin); } -void PluginManager::observePluginPath(void *str) +int PluginManager::stopPlugins(Plugin *const plugin) { - //printf("start observePluginPath\n"); - int length; - int i = 0; - int fd; - int wd; - char *str1 = (char *)str; - std::string original_path(str1); - //printf("Directory is %s\n",(char*)str1)); - char buffer[BUF_LEN]; - - fd = inotify_init(); - - if ( fd < 0 ) - { - printf("inotify_init\n"); - } - - wd = inotify_add_watch( fd, str1, - IN_MODIFY | IN_CREATE | IN_DELETE | IN_DELETE_SELF - | IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO); - - while (true) - { - //printf("read start\n"); - i = 0; - length = read( fd, buffer, BUF_LEN ); - - if ( length < 0 ) - { - printf("observePluginPath read\n"); - } - std::string filepath = original_path; - //printf("filepath = %s\n",filepath.c_str()); - while ( i < length ) - { - if (i < (signed)(BUF_LEN - ( sizeof( struct inotify_event) + 16)) && i > -1) - { - struct inotify_event *event = ( struct inotify_event *) &buffer[ i ]; - - if ((event->mask & IN_CREATE) || (event->mask & IN_MODIFY) || (event->mask & IN_MOVED_TO)) - { - registerAllPlugin(str1); - } - else - { - //filepath += "/"; - //filepath += std::string(event->name); - std::vector *resource_plugin = findPlugins("Path", filepath.c_str()); //add foldername - - //printf("plugin size is %d\n",resource_plugin->size()); - //printf("plugin file path is %s\n",resource_plugin->()); - if (resource_plugin->size() == 1) - { - unregisterPlugin(&(resource_plugin->at(0))); - } - else - { - registerAllPlugin(str1); - } - delete(resource_plugin); - resource_plugin = NULL; - } - //printf("observePluginPath path = %s \n",str1); - //printf("observePluginPath directory name = %s \n",event->name); - i += EVENT_SIZE + event->len; - } - } - - - } - ( void ) inotify_rm_watch( fd, wd ); - ( void ) close( fd ); - //printf("observePluginPath end\n"); + return pluginManagerImpl->stopPlugins(plugin); } -const std::string PluginManager::getState(const std::string plugID) +std::vector PluginManager::getPlugins(void) { - return state_to_string(cp_get_plugin_state(m_context, plugID.c_str())); -} + return pluginManagerImpl->getAllPlugins(); +} \ No newline at end of file diff --git a/service/protocol-plugin/plugin-manager/src/PluginManager.h b/service/protocol-plugin/plugin-manager/src/PluginManager.h index 5575bfd..41a631e 100644 --- a/service/protocol-plugin/plugin-manager/src/PluginManager.h +++ b/service/protocol-plugin/plugin-manager/src/PluginManager.h @@ -30,29 +30,13 @@ #include #include #include -#include -#include -#include -#include -#include -#include - +#include +#include "PluginManagerImpl.h" #include "Plugin.h" -#include "OCPlatform.h" -#include "OCApi.h" - -#define EVENT_SIZE ( sizeof (struct inotify_event) ) -#define BUF_LEN (int)( 1024 * ( EVENT_SIZE + 16 ) ) namespace OIC { - - struct PluginManagerConfig - { - std::string rootPluinPath; - }; - /** * @brief After installing a plug-in in a directory, each plug-ins can be managed by this class. * @@ -61,84 +45,36 @@ namespace OIC class PluginManager { public: - /** - * A function to register pluins in the path. - * This function will load plugins in plugin manager table. - * - * @param path plugin file path to be registered. - * @return int, 1 is success, 0 is fail. - * - * NOTE: - * - */ - int registerPlugin(const std::string path); - - - /** - * A function to register pluins in the path. - * This function will load plugins in plugin manager table. - * - * @param path plugin file path to be registered. - * recursive load plugins sub folders recursively. - * @return int, 1 is success, 0 is fail. - * - * NOTE: - * - */ - int registerAllPlugin(const std::string path); - - - /** - * Unregister plugin. - * - * @param plugin plugin object to be unregistered. - * @return int, 1 is success, 0 is fail. - */ - int unregisterPlugin(Plugin *const plugin); - + PluginManager(); /** - * Unregister All plugin. - * - * @return int, 1 is success, 0 is fail. + * Virtual destructor */ - int unregisterAllPlugin(void); - - + ~PluginManager(void); /** - * get all plugins which currently registered. + * Start plugins by resource type * - * @return vector of currently registered plugins + * @param type resouce type string to be started. * */ - std::vector &getAllPlugins(void); - + int startPlugins(const std::string key, const std::string value); /** - * find plugins which have the key and value + * Stop plugins by resource type * - * @return vector of currently registered plugins - */ - std::vector *findPlugins(const std::string key, const std::string value); - - - /** - * Get plugin which has the id + * @param type resouce type string to be started. * - * @param pluginID plugin id to find - * @return Plugin instance */ - Plugin *getPlugin(const std::string pluginID); + int stopPlugins(const std::string key, const std::string value); /** * Start plugin * This function will load dynamic plugin library on memory and call start function of plugin to be initialized. * * @param Plugin - * @param Platform pointer. * @return int, 1 is success, 0 is fail. */ - int start(Plugin *const plugin, void *const arg); + int startPlugins(Plugin *const plugin); /** @@ -148,140 +84,20 @@ namespace OIC * @param Plugin * @return int, 1 is success, 0 is fail. */ - int stop(Plugin *const plugin); - - - /** - * Check whether the plugin started or not - * - * @param Plugin to identify the Starting. - * @return true if started, false is stop. - * - */ - bool isStarted(Plugin *plugin); + int stopPlugins(Plugin *const plugin); /** - * Get Plugin state. + * Get Plugin list. * - * @param Plugin ID - * @return Plugin state. - */ - const std::string getState(const std::string plugID); - - - /** * - * new Singleton pattern instance. * - * @return PluginManager pointer Address. + * @return */ - static PluginManager *Getinstance() - { - if (NULL == s_pinstance) - { - s_pinstance = new PluginManager(); - } - - return s_pinstance; - } - - + std::vector getPlugins(void); private: - - typedef std::map File_list; - std::vector m_plugins; - cp_context_t *m_context; - cp_status_t m_status; - cp_plugin_info_t **m_cp_plugins; - cp_plugin_info_t *m_plugin; - boost::thread m_file_detect_thread; - boost::thread_group m_thread_g; - std::string m_path; - static PluginManager *s_pinstance; - - /** - * Constructor for PluginManager. - * During construction time, all plugins under the root plugin path will be loaded. - * - */ - PluginManager(); - - /** - * Virtual destructor - */ - virtual ~PluginManager(void); - - /** - * delete Singleton pattern instance. - */ - static void deleteinstance() - { - if (NULL != s_pinstance) - { - delete s_pinstance; - s_pinstance = NULL; - } - } - - /** - * detect plugins(add, delete, move) - * - * @param plugin file path. - * @return void - */ - void observePluginPath(void *); - - - /** - * change Number to String. - * - * @param int. - * @return State String. - */ - const char *state_to_string(int state); - - /** - * Get whole "SO" file list. - * - * @param OUT, SO file list. - * @param Root path. - * @return true or false. - */ - bool getFileList(File_list &list, const std::string strDir); - - /** - * print whole plugin info. - * - * @param cpluff plugins - */ - void printPluginList(cp_plugin_info_t **plugins); - - /** - * install plugin using c-pluff. - * - * @param Root path. - * @return int, 1 is success, 0 is fail. - */ - int installPlugin(const std::string path); - - - /** - * find Plugin and install plugin.(Recursive) - * - * @param Root path. - * @return int, 1 is success, 0 is fail. - */ - int findPluginRecursive(const std::string path); - - /** - * load Plugin information to PluginManager table. - * - * @param path to observe - * @return int, 1 is success, 0 is fail. - */ - int loadPluginInfoToManager(const std::string path); + PluginManagerImpl *pluginManagerImpl; + void (*destroy)(PluginManagerImpl *); }; } - #endif //__PLUGINMANAGER_H diff --git a/service/protocol-plugin/plugin-manager/src/PluginManagerImpl.cpp b/service/protocol-plugin/plugin-manager/src/PluginManagerImpl.cpp new file mode 100644 index 0000000..d501786 --- /dev/null +++ b/service/protocol-plugin/plugin-manager/src/PluginManagerImpl.cpp @@ -0,0 +1,346 @@ +//****************************************************************** +// +// 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 PluginManagerImpl.cpp + +/// @brief + +#include "PluginManagerImpl.h" + +using namespace OIC; + +PluginManagerImpl *PluginManagerImpl::s_pinstance = nullptr; + +extern "C" PluginManagerImpl *create_object() +{ + PluginManagerImpl *newobj; + newobj = new PluginManagerImpl; + return newobj; +} + +extern "C" void destroy_object( PluginManagerImpl *object ) +{ + delete object; +} + +PluginManagerImpl::PluginManagerImpl() +{ + cppm = CpluffAdapter::Getinstance(); + javappm = FelixAdapter::Getinstance(); + refreshPluginInfo(); +} + +PluginManagerImpl::~PluginManagerImpl() +{ + +} + +int PluginManagerImpl::registerPlugin(std::string path) +{ + int flag = 0; + flag = cppm->registerPlugin(path); + flag = javappm->registerPlugin(path); + refreshPluginInfo(); + return flag; +} + +int PluginManagerImpl::registerAllPlugin(std::string path) +{ + int flag = 0; + flag = cppm->registerAllPlugin(path); + flag = javappm->registerAllPlugin(path); + refreshPluginInfo(); + return flag; +} + +int PluginManagerImpl::unregisterPlugin(std::string id) +{ + int flag = 0; + + Plugin *plugin = new Plugin; + plugin->setValue("Id", id); + + for (unsigned int i = 0 ; i < m_plugins.size(); i++) + { + if (!m_plugins[i].getID().compare(id)) + { + if (!m_plugins[i].getValueByAttribute("Language").compare("CPP")) + { + if ((flag = cppm->unregisterPlugin(&m_plugins[i]))) + { + m_plugins.erase(m_plugins.begin() + i); + } + } + else if (!m_plugins[i].getValueByAttribute("Language").compare("JAVA")) + { + if ((flag = javappm->unregisterPlugin(&m_plugins[i]))) + { + m_plugins.erase(m_plugins.begin() + i); + } + } + } + } + + return flag; +} + +int PluginManagerImpl::unregisterAllPlugin() +{ + int flag = 0; + flag = cppm->unregisterAllPlugin(); + flag = javappm->unregisterAllPlugin(); + m_plugins.clear(); + return flag; +} + + +std::vector &PluginManagerImpl::getAllPlugins(void) +{ + return m_plugins; +} + +std::vector *PluginManagerImpl::findPlugins(const std::string key, + const std::string value) +{ + std::vector *re_plugins; + re_plugins = new std::vector; + for (unsigned int i = 0; i < m_plugins.size(); i++) + { + if (!m_plugins[i].getValueByAttribute(key).compare(value)) + { + re_plugins->push_back(m_plugins[i]); + } + } + + return re_plugins; +} + +Plugin *PluginManagerImpl::getPlugin(const std::string pluginID) +{ + for (unsigned int i = 0; i < m_plugins.size(); i++) + { + if (!(m_plugins[i].getID().compare(pluginID))) + { + return &(m_plugins[i]); + } + } + + return nullptr; +} +int PluginManagerImpl::startPlugins(const std::string key, const std::string value) +{ + int flag = FALSE; + std::string resourcetype = ""; + int size = value.size(); + + //Parsing Resource_Type + for (int i = size - 1; i > -1 ; i--) + { + if (value.at(i) == '.' && value.at(i) == '/') + { + break; + } + resourcetype += value.at(i); + } + + //Reverse string(Resource value) + reverse(resourcetype.begin(), resourcetype.end()); + + //Search Plugin + std::vector *resource_plugin = findPlugins(key, resourcetype); + + //start Plugin + std::vector::iterator it; + for (it = resource_plugin->begin(); it != resource_plugin->end(); it++) + { + if (!isStarted(&(*it))) // started : 1, stop : 0 + { + flag = startPlugins(&(*it));//TODO PASS the OCPlatform + } + } + delete(resource_plugin); + resource_plugin = nullptr; + return flag; +} + +int PluginManagerImpl::startPlugins(Plugin *const plugin) +{ + int flag = FALSE; + void *arg = nullptr; + + flag = startbyPlatform(plugin, arg); + + return flag; +} + +int PluginManagerImpl::stopPlugins(const std::string key, const std::string value) +{ + int flag = FALSE; + std::string resourcetype = ""; + int size = value.size(); + + //Parsing Resource_Type + for (int i = size - 1; i > -1 ; i--) + { + if (value.at(i) == '.' && value.at(i) == '/') + { + break; + } + resourcetype += value.at(i); + } + + //Reverse string(Resource value) + + reverse(resourcetype.begin(), resourcetype.end()); + + // printf("resource value = %s\n", resourcetype.c_str()); + + //Search Plugin + std::vector *resource_plugin = findPlugins(key, resourcetype); + + //stop Plugin + std::vector::iterator it; + for (it = resource_plugin->begin(); it != resource_plugin->end(); it++) + { + if (isStarted(&(*it))) // started : 1, stop : 0 + { + flag = stopPlugins(&(*it));//TODO PASS the OCPlatform + } + } + delete(resource_plugin); + resource_plugin = nullptr; + return flag; +} + +int PluginManagerImpl::stopPlugins(Plugin *const plugin) +{ + int flag = FALSE; + + flag = stopbyPlatform(plugin); + + return flag; +} + +int PluginManagerImpl::startbyPlatform(Plugin *const plugin, void *const arg) +{ + int flag = 0; + + for (unsigned int i = 0 ; i < m_plugins.size(); i++) + { + if (!m_plugins[i].getID().compare(plugin->getID())) + { + if (!m_plugins[i].getValueByAttribute("Language").compare("CPP")) + { + flag = cppm->start(plugin, arg); + } + else if (!m_plugins[i].getValueByAttribute("Language").compare("JAVA")) + { + flag = javappm->start(plugin, arg); + } + } + } + + if (flag) + { + refreshPluginInfo(); + } + return flag; +} + +int PluginManagerImpl::stopbyPlatform(Plugin *const plugin) +{ + int flag = 0; + + for (unsigned int i = 0 ; i < m_plugins.size(); i++) + { + if (!m_plugins[i].getID().compare(plugin->getID())) + { + if (!m_plugins[i].getValueByAttribute("Language").compare("CPP")) + { + flag = cppm->stop(plugin); + } + else if (!m_plugins[i].getValueByAttribute("Language").compare("JAVA")) + { + flag = javappm->stop(plugin); + } + } + } + + if (flag) + { + refreshPluginInfo(); + } + return flag; +} + +bool PluginManagerImpl::isStarted(Plugin *plugin) +{ + bool flag = 0; + if (cppm->isStarted(plugin)) + { + flag = TRUE; + return flag; + } + + if (javappm->isStarted(plugin)) + { + flag = TRUE; + return flag; + } + return flag; +} + +std::string PluginManagerImpl::getState(std::string plugID) +{ + std::string str = ""; + + for (unsigned int i = 0 ; i < m_plugins.size(); i++) + { + if (!m_plugins[i].getID().compare(plugID)) + { + if (!m_plugins[i].getValueByAttribute("Language").compare("CPP")) + { + str = cppm->getState(plugID); + } + else if (!m_plugins[i].getValueByAttribute("Language").compare("JAVA")) + { + str = javappm->getState(plugID); + } + } + } + + return str; +} + +std::vector PluginManagerImpl::refreshPluginInfo() +{ + m_plugins.clear(); + m_plugins = cppm->getAllPlugins(); + + std::vector java_plugins = javappm->getAllPlugins(); + int size = java_plugins.size(); + + for (int i = 0 ; i < size ; i++) + { + m_plugins.push_back(java_plugins[i]); + } + + return m_plugins; +} \ No newline at end of file diff --git a/service/protocol-plugin/plugin-manager/src/PluginManagerImpl.h b/service/protocol-plugin/plugin-manager/src/PluginManagerImpl.h new file mode 100644 index 0000000..f42236a --- /dev/null +++ b/service/protocol-plugin/plugin-manager/src/PluginManagerImpl.h @@ -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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// @file PluginManagerImpl.h + +/// @brief + +#ifndef __PLUGINMANAGERIMPL_H__ +#define __PLUGINMANAGERIMPL_H__ + +#include "Plugin.h" +#include "CpluffAdapter.h" +#include "FelixAdapter.h" + +namespace OIC +{ + class PluginManagerImpl + { + public: + + /** + * Constructor for PluginManagerImpl. + * During construction time, all plugins under the root plugin path will be loaded. + * + */ + PluginManagerImpl(); + + /** + * Virtual destructor + */ + virtual ~PluginManagerImpl(void); + + + /** + * A function to register pluins in the path. + * This function will load plugins in plugin manager table. + * + * @param path plugin file path to be registered. + * @return int, 1 is success, 0 is fail. + * + * NOTE: + * + */ + int registerPlugin(std::string path); + + + + /** + * A function to register pluins in the path. + * This function will load plugins in plugin manager table. + * + * @param path plugin file path to be registered. + * recursive load plugins sub folders recursively. + * @return int, 1 is success, 0 is fail. + * + * NOTE: + * + */ + int registerAllPlugin(std::string path); + + /** + * Unregister plugin. + * + * @param plugin plugin object to be unregistered. + * @return int, 1 is success, 0 is fail. + */ + int unregisterPlugin(std::string path); + + /** + * Unregister All plugin. + * + * @return int, 1 is success, 0 is fail. + */ + int unregisterAllPlugin(void); + + /** + * find plugins which have the key and value + * + * @return vector of currently registered plugins + */ + std::vector *findPlugins(const std::string key, const std::string value); + + /** + * Get plugin which has the id + * + * @param pluginID plugin id to find + * @return Plugin instance + */ + Plugin *getPlugin(const std::string pluginID); + + /** + * Check whether the plugin started or not + * + * @param Plugin to identify the Starting. + * @return true if started, false is stop. + * + */ + bool isStarted(Plugin *plugin); + + /** + * Get Plugin state. + * + * @param Plugin ID + * @return Plugin state. + */ + std::string getState(const std::string plugID); + + /** + * Start plugins by resource type + * + * @param type resouce type string to be started. + * + */ + virtual int startPlugins(const std::string key, const std::string value); + + /** + * Stop plugins by resource type + * + * @param type resouce type string to be started. + * + */ + virtual int stopPlugins(const std::string key, const std::string value); + + /** + * Start plugin + * This function will load dynamic plugin library on memory and call start function of plugin to be initialized. + * + * @param Plugin + * @return int, 1 is success, 0 is fail. + */ + virtual int startPlugins(Plugin *const plugin); + + + /** + * Stop Plugin. + * This function will call stop function of plugin and unload dynamic plugin library from memory. + * + * @param Plugin + * @return int, 1 is success, 0 is fail. + */ + virtual int stopPlugins(Plugin *const plugin); + + /** + * get all plugins which currently registered. + * + * @return vector of currently registered plugins + * + */ + virtual std::vector &getAllPlugins(void); + + static PluginManagerImpl *Getinstance() + { + if (NULL == s_pinstance) + { + s_pinstance = new PluginManagerImpl(); + } + + return s_pinstance; + } + + private: + + CpluffAdapter *cppm; + FelixAdapter *javappm; + + std::vector m_plugins; + static PluginManagerImpl *s_pinstance; + + static void deleteinstance() + { + if (NULL != s_pinstance) + { + delete s_pinstance; + s_pinstance = NULL; + } + } + + /* + * refresh All Plugin information. + * + * @return vector is all Plugin. + */ + std::vector refreshPluginInfo(); + + /** + * Start plugin by platform. + * This function will load dynamic plugin library on memory and call start function of plugin to be initialized. + * + * @param Plugin + * @param Platform pointer. + * @return int, 1 is success, 0 is fail. + */ + int startbyPlatform(Plugin *const plugin, void *const arg); + + /** + * Stop Plugin by platform. + * This function will call stop function of plugin and unload dynamic plugin library from memory. + * + * @param Plugin + * @return int, 1 is success, 0 is fail. + */ + int stopbyPlatform(Plugin *const plugin); + }; +} + +#endif //__PLUGINMANAGERIMPL_H__ \ No newline at end of file diff --git a/service/protocol-plugin/plugin-manager/src/PluginManagerService.cpp b/service/protocol-plugin/plugin-manager/src/PluginManagerService.cpp deleted file mode 100644 index 66885c0..0000000 --- a/service/protocol-plugin/plugin-manager/src/PluginManagerService.cpp +++ /dev/null @@ -1,184 +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 PluginManagerService.cpp - -/// @brief - -#include "PluginManager.h" -#include - -using namespace OIC; -using namespace std; -using namespace OC; - -OCPlatform *g_platform; - -void printMenu() -{ - cout << endl << "====== Menu ======" << endl; - cout << "1. Set Plugins Directory" << endl; - cout << "2. Add a Plugin " << endl; - cout << "3. Delete a Plugin" << endl; - cout << "4. Start " << endl; - cout << "5. Stop" << endl; - cout << "6. List" << endl; - cout << "0. Exit " << endl << endl; -} - -void loading(const int recursive) -{ - PluginManager *pm = PluginManager::Getinstance(); - string str; - if (recursive == 1) - { - cout << "Enter Plugins Directory Path = "; - cin >> str; - cout << "All plugins in all sub-directories of the path will be added and new "; - cout << "plugins will be automatically detected and added from now on." << endl; - cout << "To see the current list of plugins, select \"List\" menu." << endl; - pm->registerAllPlugin(str); - } - else - { - cout << "Enter Path of the plugin = "; - cin >> str; - pm->registerPlugin(str); - } - -} - -void unregister() -{ - PluginManager *pm = PluginManager::Getinstance(); - Plugin *plugin = new Plugin; - string str1; - cout << "Enter Plugin ID = " ; - cin >> str1; - plugin->setValue("Id", str1); - //pm->unregisterPlugin(plugin); - pm->unregisterAllPlugin(); - delete plugin; -} - -void pluginstart() -{ - PluginManager *pm = PluginManager::Getinstance(); - Plugin *plugin = new Plugin; - string str1; - cout << "Enter the id of the plugin = "; - cin >> str1; - plugin->setValue("Id", str1); - pm->start(plugin, (void *)g_platform); - delete plugin; -} - -void pluginstop() -{ - PluginManager *pm = PluginManager::Getinstance(); - Plugin *plugin = new Plugin; - string str1; - cout << "Enter the id of the plugin = "; - cin >> str1; - plugin->setValue("Id", str1); - pm->stop(plugin); - delete plugin; -} - -void printfplugs() -{ - PluginManager *pm = PluginManager::Getinstance(); - const char format[] = " %-30s %-15s %-15s %-20s\n"; - printf("\n====== Plugins List ======\n"); - printf(format, - "ID", - "NAME", - "STATE", - "TYPE"); - std::vector plugins = pm->getAllPlugins(); - std::vector::iterator it; - - for (it = plugins.begin(); it != plugins.end() ; it++) - { - printf(format, - it->getID().c_str(), - it->getName().c_str() != NULL ? it->getName().c_str() : "", - pm->getState(it->getID()).c_str(), - it->getValueByAttribute("ResourceType").c_str() != NULL ? - it->getValueByAttribute("ResourceType").c_str() : ""); - } - printf("\n"); -} - -PluginManager *PluginManager::s_pinstance = NULL; - -int main(int argc, char *argv[]) -{ - //PluginManager *pm = PluginManager::Getinstance(); - //Setting OCPlatform - ///////////////////////////////// - - PlatformConfig cfg - { - OC::ServiceType::InProc, - OC::ModeType::Server, - "192.168.2.5", - 5683, - OC::QualityOfService::NonConfirmable - }; - ///////////////////////////////// - - g_platform = new OCPlatform(cfg); - int num = 0; - while (true) - { - printMenu(); - cout << "Enter the number of Menu = "; - cin >> num; - switch (num) - { - case 1: - loading(1); - break; - case 2: - loading(0); - break; - case 3: - unregister(); - break; - case 4: - pluginstart(); - break; - case 5: - pluginstop(); - break; - case 6: - printfplugs(); - break; - case 0: - return 0; - break; - default: - cout << "Wrong number." << endl; - break; - } - } - return 0; -} diff --git a/service/protocol-plugin/plugins/hue/build/linux/Makefile b/service/protocol-plugin/plugins/hue/build/linux/Makefile deleted file mode 100644 index 02c5de3..0000000 --- a/service/protocol-plugin/plugins/hue/build/linux/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -COMMON_DIR = ../.. -include $(COMMON_DIR)/../../config.mk -BUILD = release - -CXX = g++ -CXX_FLAGS = -g3 -std=c++0x -Wall -pthread -LDFLAGS = -fPIC -shared -LIBS = -lpthread -lcurl -INC = . -INC+=-I../ -I$(COMMON_DIR)/lib/curl - -SRC_DIR = $(COMMON_DIR)/src - -SRC_CPP := $(SRC_DIR)/hue_light_sample.cpp -SRC_CPP += $(SRC_DIR)/HuePlugin.cpp -SRC_CPP += $(SRC_DIR)/simple_parse.cpp -SRC_CPP += $(SRC_DIR)/OCResourceDesc.cpp -SRC_CPP += $(SRC_DIR)/http_curl.cpp -SRC_CPP += $(SRC_DIR)/HueLightHandler.cpp -SRC_CPP += $(SRC_DIR)/HueBridge.cpp - -OIC_DIR = $(COMMON_DIR)/../../../../resource -OCLIB_DIR = $(OIC_DIR)/build/linux/$(BUILD)/obj -CSDK_DIR = $(OIC_DIR)/csdk/build/linux/$(BUILD) - -CXX_INC := -I$(OIC_DIR)/include/ -CXX_INC += -I$(OIC_DIR)/csdk/stack/include -CXX_INC += -I$(OIC_DIR)/csdk/ocsocket/include -CXX_INC += -I$(OIC_DIR)/csdk/ocrandom/include -CXX_INC += -I$(OIC_DIR)/csdk/logger/include -CXX_INC += -I$(BOOST_DIR) -CXX_INC += -I$(OIC_DIR)/examples/lib -CXX_INC += -I../../../../lib/cpluff/libcpluff - -TARGET_DY_LIB=libplugin-hue-light.so - - -LDFLAGS=-fPIC -shared - - -.PHONY: hue-environment oic-light-client oic-light-server hue-light-plugin -all: .PHONY - -hue-environment: - -mkdir $(BUILD) - cp plugin.xml $(BUILD)/ - -oic-light-client: $(SRC_DIR)/test/client_test.cpp $(OCLIB_DIR)/liboc.a - $(CXX) $(CXX_FLAGS) -o $(BUILD)/oic-light-client $(SRC_DIR)/test/client_test.cpp $(OCLIB_DIR)/liboc.a $(CSDK_DIR)/liboctbstack.a $(CXX_INC) - -oic-light-server: $(SRC_DIR)/test/server_test.cpp $(OCLIB_DIR)/liboc.a - $(CXX) $(CXX_FLAGS) -o $(BUILD)/oic-light-server $(SRC_DIR)/test/server_test.cpp $(OCLIB_DIR)/liboc.a $(CSDK_DIR)/liboctbstack.a $(CXX_INC) - -hue-light-plugin: $(SRC_CPP) $(OCLIB_DIR)/liboc.a - $(CXX) $(CXX_FLAGS) -o $(BUILD)/$(TARGET_DY_LIB) $^ $(CSDK_DIR)/liboctbstack.a $(CXX_INC) -I $(INC) $(LDFLAGS) $(LIBS) - -clean: - rm -rf release debug - - diff --git a/service/protocol-plugin/plugins/hue/build/linux/plugin.xml b/service/protocol-plugin/plugins/hue/build/linux/plugin.xml deleted file mode 100644 index eb73e67..0000000 --- a/service/protocol-plugin/plugins/hue/build/linux/plugin.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/service/protocol-plugin/plugins/hue/lib/curl/curl.h b/service/protocol-plugin/plugins/hue/lib/curl/curl.h deleted file mode 100644 index 017a36c..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/curl.h +++ /dev/null @@ -1,2218 +0,0 @@ -#ifndef __CURL_CURL_H -#define __CURL_CURL_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* - * If you have libcurl problems, all docs and details are found here: - * http://curl.haxx.se/libcurl/ - * - * curl-library mailing list subscription and unsubscription web interface: - * http://cool.haxx.se/mailman/listinfo/curl-library/ - */ - -#include "curlver.h" /* libcurl version defines */ -#include "curlbuild.h" /* libcurl build definitions */ -#include "curlrules.h" /* libcurl rules enforcement */ - -/* - * Define WIN32 when build target is Win32 API - */ - -#if (defined(_WIN32) || defined(__WIN32__)) && \ - !defined(WIN32) && !defined(__SYMBIAN32__) -#define WIN32 -#endif - -#include -#include - -#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) -/* Needed for __FreeBSD_version symbol definition */ -#include -#endif - -/* The include stuff here below is mainly for time_t! */ -#include -#include - -#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) -#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || defined(__LWIP_OPT_H__)) -/* The check above prevents the winsock2 inclusion if winsock.h already was - included, since they can't co-exist without problems */ -#include -#include -#endif -#endif - -/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish - libc5-based Linux systems. Only include it on systems that are known to - require it! */ -#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ - defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(ANDROID) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) -#include -#endif - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#include -#endif - -#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) -#include -#endif - -#ifdef __BEOS__ -#include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURL; - -/* - * Decorate exportable functions for Win32 and Symbian OS DLL linking. - * This avoids using a .def file for building libcurl.dll. - */ -#if (defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__)) && \ - !defined(CURL_STATICLIB) -#if defined(BUILDING_LIBCURL) -#define CURL_EXTERN __declspec(dllexport) -#else -#define CURL_EXTERN __declspec(dllimport) -#endif -#else - -#ifdef CURL_HIDDEN_SYMBOLS -/* - * This definition is used to make external definitions visible in the - * shared library when symbols are hidden by default. It makes no - * difference when compiling applications whether this is set or not, - * only when compiling the library. - */ -#define CURL_EXTERN CURL_EXTERN_SYMBOL -#else -#define CURL_EXTERN -#endif -#endif - -#ifndef curl_socket_typedef -/* socket typedef */ -#if defined(WIN32) && !defined(__LWIP_OPT_H__) -typedef SOCKET curl_socket_t; -#define CURL_SOCKET_BAD INVALID_SOCKET -#else -typedef int curl_socket_t; -#define CURL_SOCKET_BAD -1 -#endif -#define curl_socket_typedef -#endif /* curl_socket_typedef */ - -struct curl_httppost -{ - struct curl_httppost *next; /* next entry in the list */ - char *name; /* pointer to allocated name */ - long namelength; /* length of name length */ - char *contents; /* pointer to allocated data contents */ - long contentslength; /* length of contents field */ - char *buffer; /* pointer to allocated buffer contents */ - long bufferlength; /* length of buffer field */ - char *contenttype; /* Content-Type */ - struct curl_slist *contentheader; /* list of extra headers for this form */ - struct curl_httppost *more; /* if one field name has more than one - file, this link should link to following - files */ - long flags; /* as defined below */ -#define HTTPPOST_FILENAME (1<<0) /* specified content is a file name */ -#define HTTPPOST_READFILE (1<<1) /* specified content is a file name */ -#define HTTPPOST_PTRNAME (1<<2) /* name is only stored pointer - do not free in formfree */ -#define HTTPPOST_PTRCONTENTS (1<<3) /* contents is only stored pointer - do not free in formfree */ -#define HTTPPOST_BUFFER (1<<4) /* upload file from buffer */ -#define HTTPPOST_PTRBUFFER (1<<5) /* upload file from pointer contents */ -#define HTTPPOST_CALLBACK (1<<6) /* upload file contents by using the - regular read callback to get the data - and pass the given pointer as custom - pointer */ - - char *showfilename; /* The file name to show. If not set, the - actual file name will be used (if this - is a file part) */ - void *userp; /* custom pointer used for - HTTPPOST_CALLBACK posts */ -}; - -typedef int (*curl_progress_callback)(void *clientp, - double dltotal, - double dlnow, - double ultotal, - double ulnow); - -#ifndef CURL_MAX_WRITE_SIZE -/* Tests have proven that 20K is a very bad buffer size for uploads on - Windows, while 16K for some odd reason performed a lot better. - We do the ifndef check to allow this value to easier be changed at build - time for those who feel adventurous. The practical minimum is about - 400 bytes since libcurl uses a buffer of this size as a scratch area - (unrelated to network send operations). */ -#define CURL_MAX_WRITE_SIZE 16384 -#endif - -#ifndef CURL_MAX_HTTP_HEADER -/* The only reason to have a max limit for this is to avoid the risk of a bad - server feeding libcurl with a never-ending header that will cause reallocs - infinitely */ -#define CURL_MAX_HTTP_HEADER (100*1024) -#endif - - -/* This is a magic return code for the write callback that, when returned, - will signal libcurl to pause receiving on the current transfer. */ -#define CURL_WRITEFUNC_PAUSE 0x10000001 -typedef size_t (*curl_write_callback)(char *buffer, - size_t size, - size_t nitems, - void *outstream); - - - -/* enumeration of file types */ -typedef enum -{ - CURLFILETYPE_FILE = 0, - CURLFILETYPE_DIRECTORY, - CURLFILETYPE_SYMLINK, - CURLFILETYPE_DEVICE_BLOCK, - CURLFILETYPE_DEVICE_CHAR, - CURLFILETYPE_NAMEDPIPE, - CURLFILETYPE_SOCKET, - CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ - - CURLFILETYPE_UNKNOWN /* should never occur */ -} curlfiletype; - -#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) -#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) -#define CURLFINFOFLAG_KNOWN_TIME (1<<2) -#define CURLFINFOFLAG_KNOWN_PERM (1<<3) -#define CURLFINFOFLAG_KNOWN_UID (1<<4) -#define CURLFINFOFLAG_KNOWN_GID (1<<5) -#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) -#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) - -/* Content of this structure depends on information which is known and is - achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man - page for callbacks returning this structure -- some fields are mandatory, - some others are optional. The FLAG field has special meaning. */ -struct curl_fileinfo -{ - char *filename; - curlfiletype filetype; - time_t time; - unsigned int perm; - int uid; - int gid; - curl_off_t size; - long int hardlinks; - - struct - { - /* If some of these fields is not NULL, it is a pointer to b_data. */ - char *time; - char *perm; - char *user; - char *group; - char *target; /* pointer to the target filename of a symlink */ - } strings; - - unsigned int flags; - - /* used internally */ - char *b_data; - size_t b_size; - size_t b_used; -}; - -/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ -#define CURL_CHUNK_BGN_FUNC_OK 0 -#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ -#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ - -/* if splitting of data transfer is enabled, this callback is called before - download of an individual chunk started. Note that parameter "remains" works - only for FTP wildcard downloading (for now), otherwise is not used */ -typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, - void *ptr, - int remains); - -/* return codes for CURLOPT_CHUNK_END_FUNCTION */ -#define CURL_CHUNK_END_FUNC_OK 0 -#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ - -/* If splitting of data transfer is enabled this callback is called after - download of an individual chunk finished. - Note! After this callback was set then it have to be called FOR ALL chunks. - Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. - This is the reason why we don't need "transfer_info" parameter in this - callback and we are not interested in "remains" parameter too. */ -typedef long (*curl_chunk_end_callback)(void *ptr); - -/* return codes for FNMATCHFUNCTION */ -#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ -#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ -#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ - -/* callback type for wildcard downloading pattern matching. If the - string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ -typedef int (*curl_fnmatch_callback)(void *ptr, - const char *pattern, - const char *string); - -/* These are the return codes for the seek callbacks */ -#define CURL_SEEKFUNC_OK 0 -#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ -#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so - libcurl might try other means instead */ -typedef int (*curl_seek_callback)(void *instream, - curl_off_t offset, - int origin); /* 'whence' */ - -/* This is a return code for the read callback that, when returned, will - signal libcurl to immediately abort the current transfer. */ -#define CURL_READFUNC_ABORT 0x10000000 -/* This is a return code for the read callback that, when returned, will - signal libcurl to pause sending data on the current transfer. */ -#define CURL_READFUNC_PAUSE 0x10000001 - -typedef size_t (*curl_read_callback)(char *buffer, - size_t size, - size_t nitems, - void *instream); - -typedef enum -{ - CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ - CURLSOCKTYPE_LAST /* never use */ -} curlsocktype; - -/* The return code from the sockopt_callback can signal information back - to libcurl: */ -#define CURL_SOCKOPT_OK 0 -#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return - CURLE_ABORTED_BY_CALLBACK */ -#define CURL_SOCKOPT_ALREADY_CONNECTED 2 - -typedef int (*curl_sockopt_callback)(void *clientp, - curl_socket_t curlfd, - curlsocktype purpose); - -struct curl_sockaddr -{ - int family; - int socktype; - int protocol; - unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it - turned really ugly and painful on the systems that - lack this type */ - struct sockaddr addr; -}; - -typedef curl_socket_t -(*curl_opensocket_callback)(void *clientp, - curlsocktype purpose, - struct curl_sockaddr *address); - -typedef int -(*curl_closesocket_callback)(void *clientp, curl_socket_t item); - -typedef enum -{ - CURLIOE_OK, /* I/O operation successful */ - CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ - CURLIOE_FAILRESTART, /* failed to restart the read */ - CURLIOE_LAST /* never use */ -} curlioerr; - -typedef enum -{ - CURLIOCMD_NOP, /* no operation */ - CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ - CURLIOCMD_LAST /* never use */ -} curliocmd; - -typedef curlioerr (*curl_ioctl_callback)(CURL *handle, - int cmd, - void *clientp); - -/* - * The following typedef's are signatures of malloc, free, realloc, strdup and - * calloc respectively. Function pointers of these types can be passed to the - * curl_global_init_mem() function to set user defined memory management - * callback routines. - */ -typedef void *(*curl_malloc_callback)(size_t size); -typedef void (*curl_free_callback)(void *ptr); -typedef void *(*curl_realloc_callback)(void *ptr, size_t size); -typedef char *(*curl_strdup_callback)(const char *str); -typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); - -/* the kind of data that is passed to information_callback*/ -typedef enum -{ - CURLINFO_TEXT = 0, - CURLINFO_HEADER_IN, /* 1 */ - CURLINFO_HEADER_OUT, /* 2 */ - CURLINFO_DATA_IN, /* 3 */ - CURLINFO_DATA_OUT, /* 4 */ - CURLINFO_SSL_DATA_IN, /* 5 */ - CURLINFO_SSL_DATA_OUT, /* 6 */ - CURLINFO_END -} curl_infotype; - -typedef int (*curl_debug_callback) -(CURL *handle, /* the handle/transfer this concerns */ - curl_infotype type, /* what kind of data */ - char *data, /* points to the data */ - size_t size, /* size of the data pointed to */ - void *userptr); /* whatever the user please */ - -/* All possible error codes from all sorts of curl functions. Future versions - may return other values, stay prepared. - - Always add new return codes last. Never *EVER* remove any. The return - codes must remain the same! - */ - -typedef enum -{ - CURLE_OK = 0, - CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ - CURLE_FAILED_INIT, /* 2 */ - CURLE_URL_MALFORMAT, /* 3 */ - CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for - 7.17.0, reused in April 2011 for 7.21.5] */ - CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ - CURLE_COULDNT_RESOLVE_HOST, /* 6 */ - CURLE_COULDNT_CONNECT, /* 7 */ - CURLE_FTP_WEIRD_SERVER_REPLY, /* 8 */ - CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server - due to lack of access - when login fails - this is not returned. */ - CURLE_OBSOLETE10, /* 10 - NOT USED */ - CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ - CURLE_OBSOLETE12, /* 12 - NOT USED */ - CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ - CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ - CURLE_FTP_CANT_GET_HOST, /* 15 */ - CURLE_OBSOLETE16, /* 16 - NOT USED */ - CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ - CURLE_PARTIAL_FILE, /* 18 */ - CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ - CURLE_OBSOLETE20, /* 20 - NOT USED */ - CURLE_QUOTE_ERROR, /* 21 - quote command failure */ - CURLE_HTTP_RETURNED_ERROR, /* 22 */ - CURLE_WRITE_ERROR, /* 23 */ - CURLE_OBSOLETE24, /* 24 - NOT USED */ - CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ - CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ - CURLE_OUT_OF_MEMORY, /* 27 */ - /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error - instead of a memory allocation error if CURL_DOES_CONVERSIONS - is defined - */ - CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ - CURLE_OBSOLETE29, /* 29 - NOT USED */ - CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ - CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ - CURLE_OBSOLETE32, /* 32 - NOT USED */ - CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ - CURLE_HTTP_POST_ERROR, /* 34 */ - CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ - CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ - CURLE_FILE_COULDNT_READ_FILE, /* 37 */ - CURLE_LDAP_CANNOT_BIND, /* 38 */ - CURLE_LDAP_SEARCH_FAILED, /* 39 */ - CURLE_OBSOLETE40, /* 40 - NOT USED */ - CURLE_FUNCTION_NOT_FOUND, /* 41 */ - CURLE_ABORTED_BY_CALLBACK, /* 42 */ - CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ - CURLE_OBSOLETE44, /* 44 - NOT USED */ - CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ - CURLE_OBSOLETE46, /* 46 - NOT USED */ - CURLE_TOO_MANY_REDIRECTS , /* 47 - catch endless re-direct loops */ - CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ - CURLE_TELNET_OPTION_SYNTAX , /* 49 - Malformed telnet option */ - CURLE_OBSOLETE50, /* 50 - NOT USED */ - CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint - wasn't verified fine */ - CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ - CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ - CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as - default */ - CURLE_SEND_ERROR, /* 55 - failed sending network data */ - CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ - CURLE_OBSOLETE57, /* 57 - NOT IN USE */ - CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ - CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ - CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ - CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ - CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ - CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ - CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ - CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind - that failed */ - CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ - CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not - accepted and we failed to login */ - CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ - CURLE_TFTP_PERM, /* 69 - permission problem on server */ - CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ - CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ - CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ - CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ - CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ - CURLE_CONV_FAILED, /* 75 - conversion failed */ - CURLE_CONV_REQD, /* 76 - caller must register conversion - callbacks using curl_easy_setopt options - CURLOPT_CONV_FROM_NETWORK_FUNCTION, - CURLOPT_CONV_TO_NETWORK_FUNCTION, and - CURLOPT_CONV_FROM_UTF8_FUNCTION */ - CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing - or wrong format */ - CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ - CURLE_SSH, /* 79 - error from the SSH layer, somewhat - generic so the error message will be of - interest when this has happened */ - - CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL - connection */ - CURLE_AGAIN, /* 81 - socket is not ready for send/recv, - wait till it's ready and try again (Added - in 7.18.2) */ - CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or - wrong format (Added in 7.19.0) */ - CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in - 7.19.0) */ - CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ - CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ - CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ - CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ - CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ - - CURL_LAST /* never use! */ -} CURLcode; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* compatibility with older names */ -#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING - -/* The following were added in 7.21.5, April 2011 */ -#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION - -/* The following were added in 7.17.1 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION - -/* The following were added in 7.17.0 */ -/* These are scheduled to disappear by 2009 */ -#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ -#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 -#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 -#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 -#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 -#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 -#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 -#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 -#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 -#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 -#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 -#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 -#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN - -#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED -#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE -#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR -#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL -#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS -#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR -#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED - -/* The following were added earlier */ - -#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT - -#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR -#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED -#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED - -#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE -#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME - -/* This was the error code 50 in 7.7.3 and a few earlier versions, this - is no longer used by libcurl but is instead #defined here only to not - make programs break */ -#define CURLE_ALREADY_COMPLETE 99999 - -#endif /*!CURL_NO_OLDIES*/ - -/* This prototype applies to all conversion callbacks */ -typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); - -typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ - void *ssl_ctx, /* actually an - OpenSSL SSL_CTX */ - void *userptr); - -typedef enum -{ - CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use - CONNECT HTTP/1.1 */ - CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT - HTTP/1.0 */ - CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already - in 7.10 */ - CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ - CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ - CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the - host name rather than the IP address. added - in 7.18.0 */ -} curl_proxytype; /* this enum was added in 7.10 */ - -#define CURLAUTH_NONE 0 /* nothing */ -#define CURLAUTH_BASIC (1<<0) /* Basic (default) */ -#define CURLAUTH_DIGEST (1<<1) /* Digest */ -#define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ -#define CURLAUTH_NTLM (1<<3) /* NTLM */ -#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ -#define CURLAUTH_NTLM_WB (1<<5) /* NTLM delegating to winbind helper */ -#define CURLAUTH_ONLY (1<<31) /* used together with a single other - type to force no auth or just that - single type */ -#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ -#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) - -#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ -#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ -#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ -#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ -#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ -#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ -#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY - -#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ -#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ -#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ - -#define CURL_ERROR_SIZE 256 - -struct curl_khkey -{ - const char *key; /* points to a zero-terminated string encoded with base64 - if len is zero, otherwise to the "raw" data */ - size_t len; - enum type - { - CURLKHTYPE_UNKNOWN, - CURLKHTYPE_RSA1, - CURLKHTYPE_RSA, - CURLKHTYPE_DSS - } keytype; -}; - -/* this is the set of return values expected from the curl_sshkeycallback - callback */ -enum curl_khstat -{ - CURLKHSTAT_FINE_ADD_TO_FILE, - CURLKHSTAT_FINE, - CURLKHSTAT_REJECT, /* reject the connection, return an error */ - CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so - this causes a CURLE_DEFER error but otherwise the - connection will be left intact etc */ - CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ -}; - -/* this is the set of status codes pass in to the callback */ -enum curl_khmatch -{ - CURLKHMATCH_OK, /* match */ - CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ - CURLKHMATCH_MISSING, /* no matching host/key found */ - CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ -}; - -typedef int -(*curl_sshkeycallback) (CURL *easy, /* easy handle */ - const struct curl_khkey *knownkey, /* known */ - const struct curl_khkey *foundkey, /* found */ - enum curl_khmatch, /* libcurl's view on the keys */ - void *clientp); /* custom pointer passed from app */ - -/* parameter for the CURLOPT_USE_SSL option */ -typedef enum -{ - CURLUSESSL_NONE, /* do not attempt to use SSL */ - CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ - CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ - CURLUSESSL_ALL, /* SSL for all communication or fail */ - CURLUSESSL_LAST /* not an option, never use */ -} curl_usessl; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2009 */ - -#define CURLFTPSSL_NONE CURLUSESSL_NONE -#define CURLFTPSSL_TRY CURLUSESSL_TRY -#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL -#define CURLFTPSSL_ALL CURLUSESSL_ALL -#define CURLFTPSSL_LAST CURLUSESSL_LAST -#define curl_ftpssl curl_usessl -#endif /*!CURL_NO_OLDIES*/ - -/* parameter for the CURLOPT_FTP_SSL_CCC option */ -typedef enum -{ - CURLFTPSSL_CCC_NONE, /* do not send CCC */ - CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ - CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ - CURLFTPSSL_CCC_LAST /* not an option, never use */ -} curl_ftpccc; - -/* parameter for the CURLOPT_FTPSSLAUTH option */ -typedef enum -{ - CURLFTPAUTH_DEFAULT, /* let libcurl decide */ - CURLFTPAUTH_SSL, /* use "AUTH SSL" */ - CURLFTPAUTH_TLS, /* use "AUTH TLS" */ - CURLFTPAUTH_LAST /* not an option, never use */ -} curl_ftpauth; - -/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ -typedef enum -{ - CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ - CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD - again if MKD succeeded, for SFTP this does - similar magic */ - CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD - again even if MKD failed! */ - CURLFTP_CREATE_DIR_LAST /* not an option, never use */ -} curl_ftpcreatedir; - -/* parameter for the CURLOPT_FTP_FILEMETHOD option */ -typedef enum -{ - CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ - CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ - CURLFTPMETHOD_NOCWD, /* no CWD at all */ - CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ - CURLFTPMETHOD_LAST /* not an option, never use */ -} curl_ftpmethod; - -/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ -#define CURLPROTO_HTTP (1<<0) -#define CURLPROTO_HTTPS (1<<1) -#define CURLPROTO_FTP (1<<2) -#define CURLPROTO_FTPS (1<<3) -#define CURLPROTO_SCP (1<<4) -#define CURLPROTO_SFTP (1<<5) -#define CURLPROTO_TELNET (1<<6) -#define CURLPROTO_LDAP (1<<7) -#define CURLPROTO_LDAPS (1<<8) -#define CURLPROTO_DICT (1<<9) -#define CURLPROTO_FILE (1<<10) -#define CURLPROTO_TFTP (1<<11) -#define CURLPROTO_IMAP (1<<12) -#define CURLPROTO_IMAPS (1<<13) -#define CURLPROTO_POP3 (1<<14) -#define CURLPROTO_POP3S (1<<15) -#define CURLPROTO_SMTP (1<<16) -#define CURLPROTO_SMTPS (1<<17) -#define CURLPROTO_RTSP (1<<18) -#define CURLPROTO_RTMP (1<<19) -#define CURLPROTO_RTMPT (1<<20) -#define CURLPROTO_RTMPE (1<<21) -#define CURLPROTO_RTMPTE (1<<22) -#define CURLPROTO_RTMPS (1<<23) -#define CURLPROTO_RTMPTS (1<<24) -#define CURLPROTO_GOPHER (1<<25) -#define CURLPROTO_ALL (~0) /* enable everything */ - -/* long may be 32 or 64 bits, but we should never depend on anything else - but 32 */ -#define CURLOPTTYPE_LONG 0 -#define CURLOPTTYPE_OBJECTPOINT 10000 -#define CURLOPTTYPE_FUNCTIONPOINT 20000 -#define CURLOPTTYPE_OFF_T 30000 - -/* name is uppercase CURLOPT_, - type is one of the defined CURLOPTTYPE_ - number is unique identifier */ -#ifdef CINIT -#undef CINIT -#endif - -#ifdef CURL_ISOCPP -#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLOPT_/**/name = type + number -#endif - -/* - * This macro-mania below setups the CURLOPT_[what] enum, to be used with - * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] - * word. - */ - -typedef enum -{ - /* This is the FILE * or void * the regular output should be written to. */ - CINIT(FILE, OBJECTPOINT, 1), - - /* The full URL to get/put */ - CINIT(URL, OBJECTPOINT, 2), - - /* Port number to connect to, if other than default. */ - CINIT(PORT, LONG, 3), - - /* Name of proxy to use. */ - CINIT(PROXY, OBJECTPOINT, 4), - - /* "name:password" to use when fetching. */ - CINIT(USERPWD, OBJECTPOINT, 5), - - /* "name:password" to use with proxy. */ - CINIT(PROXYUSERPWD, OBJECTPOINT, 6), - - /* Range to get, specified as an ASCII string. */ - CINIT(RANGE, OBJECTPOINT, 7), - - /* not used */ - - /* Specified file stream to upload from (use as input): */ - CINIT(INFILE, OBJECTPOINT, 9), - - /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE - * bytes big. If this is not used, error messages go to stderr instead: */ - CINIT(ERRORBUFFER, OBJECTPOINT, 10), - - /* Function that will be called to store the output (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), - - /* Function that will be called to read the input (instead of fread). The - * parameters will use fread() syntax, make sure to follow them. */ - CINIT(READFUNCTION, FUNCTIONPOINT, 12), - - /* Time-out the read operation after this amount of seconds */ - CINIT(TIMEOUT, LONG, 13), - - /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about - * how large the file being sent really is. That allows better error - * checking and better verifies that the upload was successful. -1 means - * unknown size. - * - * For large file support, there is also a _LARGE version of the key - * which takes an off_t type, allowing platforms with larger off_t - * sizes to handle larger files. See below for INFILESIZE_LARGE. - */ - CINIT(INFILESIZE, LONG, 14), - - /* POST static input fields. */ - CINIT(POSTFIELDS, OBJECTPOINT, 15), - - /* Set the referrer page (needed by some CGIs) */ - CINIT(REFERER, OBJECTPOINT, 16), - - /* Set the FTP PORT string (interface name, named or numerical IP address) - Use i.e '-' to use default address. */ - CINIT(FTPPORT, OBJECTPOINT, 17), - - /* Set the User-Agent string (examined by some CGIs) */ - CINIT(USERAGENT, OBJECTPOINT, 18), - - /* If the download receives less than "low speed limit" bytes/second - * during "low speed time" seconds, the operations is aborted. - * You could i.e if you have a pretty high speed connection, abort if - * it is less than 2000 bytes/sec during 20 seconds. - */ - - /* Set the "low speed limit" */ - CINIT(LOW_SPEED_LIMIT, LONG, 19), - - /* Set the "low speed time" */ - CINIT(LOW_SPEED_TIME, LONG, 20), - - /* Set the continuation offset. - * - * Note there is also a _LARGE version of this key which uses - * off_t types, allowing for large file offsets on platforms which - * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. - */ - CINIT(RESUME_FROM, LONG, 21), - - /* Set cookie in request: */ - CINIT(COOKIE, OBJECTPOINT, 22), - - /* This points to a linked list of headers, struct curl_slist kind */ - CINIT(HTTPHEADER, OBJECTPOINT, 23), - - /* This points to a linked list of post entries, struct curl_httppost */ - CINIT(HTTPPOST, OBJECTPOINT, 24), - - /* name of the file keeping your private SSL-certificate */ - CINIT(SSLCERT, OBJECTPOINT, 25), - - /* password for the SSL or SSH private key */ - CINIT(KEYPASSWD, OBJECTPOINT, 26), - - /* send TYPE parameter? */ - CINIT(CRLF, LONG, 27), - - /* send linked-list of QUOTE commands */ - CINIT(QUOTE, OBJECTPOINT, 28), - - /* send FILE * or void * to store headers to, if you use a callback it - is simply passed to the callback unmodified */ - CINIT(WRITEHEADER, OBJECTPOINT, 29), - - /* point to a file to read the initial cookies from, also enables - "cookie awareness" */ - CINIT(COOKIEFILE, OBJECTPOINT, 31), - - /* What version to specifically try to use. - See CURL_SSLVERSION defines below. */ - CINIT(SSLVERSION, LONG, 32), - - /* What kind of HTTP time condition to use, see defines */ - CINIT(TIMECONDITION, LONG, 33), - - /* Time to use with the above condition. Specified in number of seconds - since 1 Jan 1970 */ - CINIT(TIMEVALUE, LONG, 34), - - /* 35 = OBSOLETE */ - - /* Custom request, for customizing the get command like - HTTP: DELETE, TRACE and others - FTP: to use a different list command - */ - CINIT(CUSTOMREQUEST, OBJECTPOINT, 36), - - /* HTTP request, for odd commands like DELETE, TRACE and others */ - CINIT(STDERR, OBJECTPOINT, 37), - - /* 38 is not used */ - - /* send linked-list of post-transfer QUOTE commands */ - CINIT(POSTQUOTE, OBJECTPOINT, 39), - - CINIT(WRITEINFO, OBJECTPOINT, 40), /* DEPRECATED, do not use! */ - - CINIT(VERBOSE, LONG, 41), /* talk a lot */ - CINIT(HEADER, LONG, 42), /* throw the header out too */ - CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ - CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ - CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 300 */ - CINIT(UPLOAD, LONG, 46), /* this is an upload */ - CINIT(POST, LONG, 47), /* HTTP POST method */ - CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ - - CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ - - /* Specify whether to read the user+password from the .netrc or the URL. - * This must be one of the CURL_NETRC_* enums below. */ - CINIT(NETRC, LONG, 51), - - CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ - - CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ - CINIT(PUT, LONG, 54), /* HTTP PUT */ - - /* 55 = OBSOLETE */ - - /* Function that will be called instead of the internal progress display - * function. This function should be defined as the curl_progress_callback - * prototype defines. */ - CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), - - /* Data passed to the progress callback */ - CINIT(PROGRESSDATA, OBJECTPOINT, 57), - - /* We want the referrer field set automatically when following locations */ - CINIT(AUTOREFERER, LONG, 58), - - /* Port of the proxy, can be set in the proxy string as well with: - "[host]:[port]" */ - CINIT(PROXYPORT, LONG, 59), - - /* size of the POST input data, if strlen() is not good to use */ - CINIT(POSTFIELDSIZE, LONG, 60), - - /* tunnel non-http operations through a HTTP proxy */ - CINIT(HTTPPROXYTUNNEL, LONG, 61), - - /* Set the interface string to use as outgoing network interface */ - CINIT(INTERFACE, OBJECTPOINT, 62), - - /* Set the krb4/5 security level, this also enables krb4/5 awareness. This - * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string - * is set but doesn't match one of these, 'private' will be used. */ - CINIT(KRBLEVEL, OBJECTPOINT, 63), - - /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ - CINIT(SSL_VERIFYPEER, LONG, 64), - - /* The CApath or CAfile used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAINFO, OBJECTPOINT, 65), - - /* 66 = OBSOLETE */ - /* 67 = OBSOLETE */ - - /* Maximum number of http redirects to follow */ - CINIT(MAXREDIRS, LONG, 68), - - /* Pass a long set to 1 to get the date of the requested document (if - possible)! Pass a zero to shut it off. */ - CINIT(FILETIME, LONG, 69), - - /* This points to a linked list of telnet options */ - CINIT(TELNETOPTIONS, OBJECTPOINT, 70), - - /* Max amount of cached alive connections */ - CINIT(MAXCONNECTS, LONG, 71), - - CINIT(CLOSEPOLICY, LONG, 72), /* DEPRECATED, do not use! */ - - /* 73 = OBSOLETE */ - - /* Set to explicitly use a new connection for the upcoming transfer. - Do not use this unless you're absolutely sure of this, as it makes the - operation slower and is less friendly for the network. */ - CINIT(FRESH_CONNECT, LONG, 74), - - /* Set to explicitly forbid the upcoming transfer's connection to be re-used - when done. Do not use this unless you're absolutely sure of this, as it - makes the operation slower and is less friendly for the network. */ - CINIT(FORBID_REUSE, LONG, 75), - - /* Set to a file name that contains random data for libcurl to use to - seed the random engine when doing SSL connects. */ - CINIT(RANDOM_FILE, OBJECTPOINT, 76), - - /* Set to the Entropy Gathering Daemon socket pathname */ - CINIT(EGDSOCKET, OBJECTPOINT, 77), - - /* Time-out connect operations after this amount of seconds, if connects - are OK within this time, then fine... This only aborts the connect - phase. [Only works on unix-style/SIGALRM operating systems] */ - CINIT(CONNECTTIMEOUT, LONG, 78), - - /* Function that will be called to store headers (instead of fwrite). The - * parameters will use fwrite() syntax, make sure to follow them. */ - CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), - - /* Set this to force the HTTP request to get back to GET. Only really usable - if POST, PUT or a custom request have been used first. - */ - CINIT(HTTPGET, LONG, 80), - - /* Set if we should verify the Common name from the peer certificate in ssl - * handshake, set 1 to check existence, 2 to ensure that it matches the - * provided hostname. */ - CINIT(SSL_VERIFYHOST, LONG, 81), - - /* Specify which file name to write all known cookies in after completed - operation. Set file name to "-" (dash) to make it go to stdout. */ - CINIT(COOKIEJAR, OBJECTPOINT, 82), - - /* Specify which SSL ciphers to use */ - CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83), - - /* Specify which HTTP version to use! This must be set to one of the - CURL_HTTP_VERSION* enums set below. */ - CINIT(HTTP_VERSION, LONG, 84), - - /* Specifically switch on or off the FTP engine's use of the EPSV command. By - default, that one will always be attempted before the more traditional - PASV command. */ - CINIT(FTP_USE_EPSV, LONG, 85), - - /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ - CINIT(SSLCERTTYPE, OBJECTPOINT, 86), - - /* name of the file keeping your private SSL-key */ - CINIT(SSLKEY, OBJECTPOINT, 87), - - /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ - CINIT(SSLKEYTYPE, OBJECTPOINT, 88), - - /* crypto engine for the SSL-sub system */ - CINIT(SSLENGINE, OBJECTPOINT, 89), - - /* set the crypto engine for the SSL-sub system as default - the param has no meaning... - */ - CINIT(SSLENGINE_DEFAULT, LONG, 90), - - /* Non-zero value means to use the global dns cache */ - CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ - - /* DNS cache timeout */ - CINIT(DNS_CACHE_TIMEOUT, LONG, 92), - - /* send linked-list of pre-transfer QUOTE commands */ - CINIT(PREQUOTE, OBJECTPOINT, 93), - - /* set the debug function */ - CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), - - /* set the data for the debug function */ - CINIT(DEBUGDATA, OBJECTPOINT, 95), - - /* mark this as start of a cookie session */ - CINIT(COOKIESESSION, LONG, 96), - - /* The CApath directory used to validate the peer certificate - this option is used only if SSL_VERIFYPEER is true */ - CINIT(CAPATH, OBJECTPOINT, 97), - - /* Instruct libcurl to use a smaller receive buffer */ - CINIT(BUFFERSIZE, LONG, 98), - - /* Instruct libcurl to not use any signal/alarm handlers, even when using - timeouts. This option is useful for multi-threaded applications. - See libcurl-the-guide for more background information. */ - CINIT(NOSIGNAL, LONG, 99), - - /* Provide a CURLShare for mutexing non-ts data */ - CINIT(SHARE, OBJECTPOINT, 100), - - /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), - CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */ - CINIT(PROXYTYPE, LONG, 101), - - /* Set the Accept-Encoding string. Use this to tell a server you would like - the response to be compressed. Before 7.21.6, this was known as - CURLOPT_ENCODING */ - CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102), - - /* Set pointer to private data */ - CINIT(PRIVATE, OBJECTPOINT, 103), - - /* Set aliases for HTTP 200 in the HTTP Response header */ - CINIT(HTTP200ALIASES, OBJECTPOINT, 104), - - /* Continue to send authentication (user+password) when following locations, - even when hostname changed. This can potentially send off the name - and password to whatever host the server decides. */ - CINIT(UNRESTRICTED_AUTH, LONG, 105), - - /* Specifically switch on or off the FTP engine's use of the EPRT command ( - it also disables the LPRT attempt). By default, those ones will always be - attempted before the good old traditional PORT command. */ - CINIT(FTP_USE_EPRT, LONG, 106), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_USERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(HTTPAUTH, LONG, 107), - - /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx - in second argument. The function must be matching the - curl_ssl_ctx_callback proto. */ - CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), - - /* Set the userdata for the ssl context callback function's third - argument */ - CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), - - /* FTP Option that causes missing dirs to be created on the remote server. - In 7.19.4 we introduced the convenience enums for this option using the - CURLFTP_CREATE_DIR prefix. - */ - CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), - - /* Set this to a bitmask value to enable the particular authentications - methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. - Note that setting multiple bits may cause extra network round-trips. */ - CINIT(PROXYAUTH, LONG, 111), - - /* FTP option that changes the timeout, in seconds, associated with - getting a response. This is different from transfer timeout time and - essentially places a demand on the FTP server to acknowledge commands - in a timely manner. */ - CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), -#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT - - /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to - tell libcurl to resolve names to those IP versions only. This only has - affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ - CINIT(IPRESOLVE, LONG, 113), - - /* Set this option to limit the size of a file that will be downloaded from - an HTTP or FTP server. - - Note there is also _LARGE version which adds large file support for - platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ - CINIT(MAXFILESIZE, LONG, 114), - - /* See the comment for INFILESIZE above, but in short, specifies - * the size of the file being uploaded. -1 means unknown. - */ - CINIT(INFILESIZE_LARGE, OFF_T, 115), - - /* Sets the continuation offset. There is also a LONG version of this; - * look above for RESUME_FROM. - */ - CINIT(RESUME_FROM_LARGE, OFF_T, 116), - - /* Sets the maximum size of data that will be downloaded from - * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. - */ - CINIT(MAXFILESIZE_LARGE, OFF_T, 117), - - /* Set this option to the file name of your .netrc file you want libcurl - to parse (using the CURLOPT_NETRC option). If not set, libcurl will do - a poor attempt to find the user's home directory and check for a .netrc - file in there. */ - CINIT(NETRC_FILE, OBJECTPOINT, 118), - - /* Enable SSL/TLS for FTP, pick one of: - CURLFTPSSL_TRY - try using SSL, proceed anyway otherwise - CURLFTPSSL_CONTROL - SSL for the control connection or fail - CURLFTPSSL_ALL - SSL for all communication or fail - */ - CINIT(USE_SSL, LONG, 119), - - /* The _LARGE version of the standard POSTFIELDSIZE option */ - CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), - - /* Enable/disable the TCP Nagle algorithm */ - CINIT(TCP_NODELAY, LONG, 121), - - /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 123 OBSOLETE. Gone in 7.16.0 */ - /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ - /* 127 OBSOLETE. Gone in 7.16.0 */ - /* 128 OBSOLETE. Gone in 7.16.0 */ - - /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option - can be used to change libcurl's default action which is to first try - "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK - response has been received. - - Available parameters are: - CURLFTPAUTH_DEFAULT - let libcurl decide - CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS - CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL - */ - CINIT(FTPSSLAUTH, LONG, 129), - - CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), - CINIT(IOCTLDATA, OBJECTPOINT, 131), - - /* 132 OBSOLETE. Gone in 7.16.0 */ - /* 133 OBSOLETE. Gone in 7.16.0 */ - - /* zero terminated string for pass on to the FTP server when asked for - "account" info */ - CINIT(FTP_ACCOUNT, OBJECTPOINT, 134), - - /* feed cookies into cookie engine */ - CINIT(COOKIELIST, OBJECTPOINT, 135), - - /* ignore Content-Length */ - CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), - - /* Set to non-zero to skip the IP address received in a 227 PASV FTP server - response. Typically used for FTP-SSL purposes but is not restricted to - that. libcurl will then instead use the same IP address it used for the - control connection. */ - CINIT(FTP_SKIP_PASV_IP, LONG, 137), - - /* Select "file method" to use when doing FTP, see the curl_ftpmethod - above. */ - CINIT(FTP_FILEMETHOD, LONG, 138), - - /* Local port number to bind the socket to */ - CINIT(LOCALPORT, LONG, 139), - - /* Number of ports to try, including the first one set with LOCALPORT. - Thus, setting it to 1 will make no additional attempts but the first. - */ - CINIT(LOCALPORTRANGE, LONG, 140), - - /* no transfer, set up connection and let application use the socket by - extracting it with CURLINFO_LASTSOCKET */ - CINIT(CONNECT_ONLY, LONG, 141), - - /* Function that will be called to convert from the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), - - /* Function that will be called to convert to the - network encoding (instead of using the iconv calls in libcurl) */ - CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), - - /* Function that will be called to convert from UTF8 - (instead of using the iconv calls in libcurl) - Note that this is used only for SSL certificate processing */ - CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), - - /* if the connection proceeds too quickly then need to slow it down */ - /* limit-rate: maximum number of bytes per second to send or receive */ - CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), - CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), - - /* Pointer to command string to send if USER/PASS fails. */ - CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147), - - /* callback function for setting socket options */ - CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), - CINIT(SOCKOPTDATA, OBJECTPOINT, 149), - - /* set to 0 to disable session ID re-use for this transfer, default is - enabled (== 1) */ - CINIT(SSL_SESSIONID_CACHE, LONG, 150), - - /* allowed SSH authentication methods */ - CINIT(SSH_AUTH_TYPES, LONG, 151), - - /* Used by scp/sftp to do public/private key authentication */ - CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152), - CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153), - - /* Send CCC (Clear Command Channel) after authentication */ - CINIT(FTP_SSL_CCC, LONG, 154), - - /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ - CINIT(TIMEOUT_MS, LONG, 155), - CINIT(CONNECTTIMEOUT_MS, LONG, 156), - - /* set to zero to disable the libcurl's decoding and thus pass the raw body - data to the application even when it is encoded/compressed */ - CINIT(HTTP_TRANSFER_DECODING, LONG, 157), - CINIT(HTTP_CONTENT_DECODING, LONG, 158), - - /* Permission used when creating new files and directories on the remote - server for protocols that support it, SFTP/SCP/FILE */ - CINIT(NEW_FILE_PERMS, LONG, 159), - CINIT(NEW_DIRECTORY_PERMS, LONG, 160), - - /* Set the behaviour of POST when redirecting. Values must be set to one - of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ - CINIT(POSTREDIR, LONG, 161), - - /* used by scp/sftp to verify the host's public key */ - CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162), - - /* Callback function for opening socket (instead of socket(2)). Optionally, - callback is able change the address or refuse to connect returning - CURL_SOCKET_BAD. The callback should have type - curl_opensocket_callback */ - CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), - CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), - - /* POST volatile input fields. */ - CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), - - /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ - CINIT(PROXY_TRANSFER_MODE, LONG, 166), - - /* Callback function for seeking in the input stream */ - CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), - CINIT(SEEKDATA, OBJECTPOINT, 168), - - /* CRL file */ - CINIT(CRLFILE, OBJECTPOINT, 169), - - /* Issuer certificate */ - CINIT(ISSUERCERT, OBJECTPOINT, 170), - - /* (IPv6) Address scope */ - CINIT(ADDRESS_SCOPE, LONG, 171), - - /* Collect certificate chain info and allow it to get retrievable with - CURLINFO_CERTINFO after the transfer is complete. (Unfortunately) only - working with OpenSSL-powered builds. */ - CINIT(CERTINFO, LONG, 172), - - /* "name" and "pwd" to use when fetching. */ - CINIT(USERNAME, OBJECTPOINT, 173), - CINIT(PASSWORD, OBJECTPOINT, 174), - - /* "name" and "pwd" to use with Proxy when fetching. */ - CINIT(PROXYUSERNAME, OBJECTPOINT, 175), - CINIT(PROXYPASSWORD, OBJECTPOINT, 176), - - /* Comma separated list of hostnames defining no-proxy zones. These should - match both hostnames directly, and hostnames within a domain. For - example, local.com will match local.com and www.local.com, but NOT - notlocal.com or www.notlocal.com. For compatibility with other - implementations of this, .local.com will be considered to be the same as - local.com. A single * is the only valid wildcard, and effectively - disables the use of proxy. */ - CINIT(NOPROXY, OBJECTPOINT, 177), - - /* block size for TFTP transfers */ - CINIT(TFTP_BLKSIZE, LONG, 178), - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179), - - /* Socks Service */ - CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), - - /* set the bitmask for the protocols that are allowed to be used for the - transfer, which thus helps the app which takes URLs from users or other - external inputs and want to restrict what protocol(s) to deal - with. Defaults to CURLPROTO_ALL. */ - CINIT(PROTOCOLS, LONG, 181), - - /* set the bitmask for the protocols that libcurl is allowed to follow to, - as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs - to be set in both bitmasks to be allowed to get redirected to. Defaults - to all protocols except FILE and SCP. */ - CINIT(REDIR_PROTOCOLS, LONG, 182), - - /* set the SSH knownhost file name to use */ - CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183), - - /* set the SSH host key callback, must point to a curl_sshkeycallback - function */ - CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), - - /* set the SSH host key callback custom pointer */ - CINIT(SSH_KEYDATA, OBJECTPOINT, 185), - - /* set the SMTP mail originator */ - CINIT(MAIL_FROM, OBJECTPOINT, 186), - - /* set the SMTP mail receiver(s) */ - CINIT(MAIL_RCPT, OBJECTPOINT, 187), - - /* FTP: send PRET before PASV */ - CINIT(FTP_USE_PRET, LONG, 188), - - /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ - CINIT(RTSP_REQUEST, LONG, 189), - - /* The RTSP session identifier */ - CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190), - - /* The RTSP stream URI */ - CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191), - - /* The Transport: header to use in RTSP requests */ - CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192), - - /* Manually initialize the client RTSP CSeq for this handle */ - CINIT(RTSP_CLIENT_CSEQ, LONG, 193), - - /* Manually initialize the server RTSP CSeq for this handle */ - CINIT(RTSP_SERVER_CSEQ, LONG, 194), - - /* The stream to pass to INTERLEAVEFUNCTION. */ - CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), - - /* Let the application define a custom write method for RTP data */ - CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), - - /* Turn on wildcard matching */ - CINIT(WILDCARDMATCH, LONG, 197), - - /* Directory matching callback called before downloading of an - individual file (chunk) started */ - CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), - - /* Directory matching callback called after the file (chunk) - was downloaded, or skipped */ - CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), - - /* Change match (fnmatch-like) callback for wildcard matching */ - CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), - - /* Let the application define custom chunk data pointer */ - CINIT(CHUNK_DATA, OBJECTPOINT, 201), - - /* FNMATCH_FUNCTION user pointer */ - CINIT(FNMATCH_DATA, OBJECTPOINT, 202), - - /* send linked-list of name:port:address sets */ - CINIT(RESOLVE, OBJECTPOINT, 203), - - /* Set a username for authenticated TLS */ - CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204), - - /* Set a password for authenticated TLS */ - CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205), - - /* Set authentication type for authenticated TLS */ - CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206), - - /* Set to 1 to enable the "TE:" header in HTTP requests to ask for - compressed transfer-encoded responses. Set to 0 to disable the use of TE: - in outgoing requests. The current default is 0, but it might change in a - future libcurl release. - - libcurl will ask for the compressed methods it knows of, and if that - isn't any, it will not ask for transfer-encoding at all even if this - option is set to 1. - - */ - CINIT(TRANSFER_ENCODING, LONG, 207), - - /* Callback function for closing socket (instead of close(2)). The callback - should have type curl_closesocket_callback */ - CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), - CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), - - /* allow GSSAPI credential delegation */ - CINIT(GSSAPI_DELEGATION, LONG, 210), - - CURLOPT_LASTENTRY /* the last unused */ -} CURLoption; - -#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all - the obsolete stuff removed! */ - -/* Backwards compatibility with older names */ -/* These are scheduled to disappear by 2011 */ - -/* This was added in version 7.19.1 */ -#define CURLOPT_POST301 CURLOPT_POSTREDIR - -/* These are scheduled to disappear by 2009 */ - -/* The following were added in 7.17.0 */ -#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_FTPAPPEND CURLOPT_APPEND -#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY -#define CURLOPT_FTP_SSL CURLOPT_USE_SSL - -/* The following were added earlier */ - -#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD -#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL - -#else -/* This is set if CURL_NO_OLDIES is defined at compile-time */ -#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ -#endif - - -/* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host - name resolves addresses using more than one IP protocol version, this - option might be handy to force libcurl to use a specific IP version. */ -#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP - versions that your system allows */ -#define CURL_IPRESOLVE_V4 1 /* resolve to ipv4 addresses */ -#define CURL_IPRESOLVE_V6 2 /* resolve to ipv6 addresses */ - -/* three convenient "aliases" that follow the name scheme better */ -#define CURLOPT_WRITEDATA CURLOPT_FILE -#define CURLOPT_READDATA CURLOPT_INFILE -#define CURLOPT_HEADERDATA CURLOPT_WRITEHEADER -#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER - -/* These enums are for use with the CURLOPT_HTTP_VERSION option. */ -enum -{ - CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd - like the library to choose the best possible - for us! */ - CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ - CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ - - CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ -}; - -/* - * Public API enums for RTSP requests - */ -enum -{ - CURL_RTSPREQ_NONE, /* first in list */ - CURL_RTSPREQ_OPTIONS, - CURL_RTSPREQ_DESCRIBE, - CURL_RTSPREQ_ANNOUNCE, - CURL_RTSPREQ_SETUP, - CURL_RTSPREQ_PLAY, - CURL_RTSPREQ_PAUSE, - CURL_RTSPREQ_TEARDOWN, - CURL_RTSPREQ_GET_PARAMETER, - CURL_RTSPREQ_SET_PARAMETER, - CURL_RTSPREQ_RECORD, - CURL_RTSPREQ_RECEIVE, - CURL_RTSPREQ_LAST /* last in list */ -}; - -/* These enums are for use with the CURLOPT_NETRC option. */ -enum CURL_NETRC_OPTION -{ - CURL_NETRC_IGNORED, /* The .netrc will never be read. - * This is the default. */ - CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred - * to one in the .netrc. */ - CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. - * Unless one is set programmatically, the .netrc - * will be queried. */ - CURL_NETRC_LAST -}; - -enum -{ - CURL_SSLVERSION_DEFAULT, - CURL_SSLVERSION_TLSv1, - CURL_SSLVERSION_SSLv2, - CURL_SSLVERSION_SSLv3, - - CURL_SSLVERSION_LAST /* never use, keep last */ -}; - -enum CURL_TLSAUTH -{ - CURL_TLSAUTH_NONE, - CURL_TLSAUTH_SRP, - CURL_TLSAUTH_LAST /* never use, keep last */ -}; - -/* symbols to use with CURLOPT_POSTREDIR. - CURL_REDIR_POST_301 and CURL_REDIR_POST_302 can be bitwise ORed so that - CURL_REDIR_POST_301 | CURL_REDIR_POST_302 == CURL_REDIR_POST_ALL */ - -#define CURL_REDIR_GET_ALL 0 -#define CURL_REDIR_POST_301 1 -#define CURL_REDIR_POST_302 2 -#define CURL_REDIR_POST_ALL (CURL_REDIR_POST_301|CURL_REDIR_POST_302) - -typedef enum -{ - CURL_TIMECOND_NONE, - - CURL_TIMECOND_IFMODSINCE, - CURL_TIMECOND_IFUNMODSINCE, - CURL_TIMECOND_LASTMOD, - - CURL_TIMECOND_LAST -} curl_TimeCond; - - -/* curl_strequal() and curl_strnequal() are subject for removal in a future - libcurl, see lib/README.curlx for details */ -CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); -CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); - -/* name is uppercase CURLFORM_ */ -#ifdef CFINIT -#undef CFINIT -#endif - -#ifdef CURL_ISOCPP -#define CFINIT(name) CURLFORM_ ## name -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define CFINIT(name) CURLFORM_/**/name -#endif - -typedef enum -{ - CFINIT(NOTHING), /********* the first one is unused ************/ - - /* */ - CFINIT(COPYNAME), - CFINIT(PTRNAME), - CFINIT(NAMELENGTH), - CFINIT(COPYCONTENTS), - CFINIT(PTRCONTENTS), - CFINIT(CONTENTSLENGTH), - CFINIT(FILECONTENT), - CFINIT(ARRAY), - CFINIT(OBSOLETE), - CFINIT(FILE), - - CFINIT(BUFFER), - CFINIT(BUFFERPTR), - CFINIT(BUFFERLENGTH), - - CFINIT(CONTENTTYPE), - CFINIT(CONTENTHEADER), - CFINIT(FILENAME), - CFINIT(END), - CFINIT(OBSOLETE2), - - CFINIT(STREAM), - - CURLFORM_LASTENTRY /* the last unused */ -} CURLformoption; - -#undef CFINIT /* done */ - -/* structure to be used as parameter for CURLFORM_ARRAY */ -struct curl_forms -{ - CURLformoption option; - const char *value; -}; - -/* use this for multipart formpost building */ -/* Returns code for curl_formadd() - * - * Returns: - * CURL_FORMADD_OK on success - * CURL_FORMADD_MEMORY if the FormInfo allocation fails - * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form - * CURL_FORMADD_NULL if a null pointer was given for a char - * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed - * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used - * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) - * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated - * CURL_FORMADD_MEMORY if some allocation for string copying failed. - * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array - * - ***************************************************************************/ -typedef enum -{ - CURL_FORMADD_OK, /* first, no error */ - - CURL_FORMADD_MEMORY, - CURL_FORMADD_OPTION_TWICE, - CURL_FORMADD_NULL, - CURL_FORMADD_UNKNOWN_OPTION, - CURL_FORMADD_INCOMPLETE, - CURL_FORMADD_ILLEGAL_ARRAY, - CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ - - CURL_FORMADD_LAST /* last */ -} CURLFORMcode; - -/* - * NAME curl_formadd() - * - * DESCRIPTION - * - * Pretty advanced function for building multi-part formposts. Each invoke - * adds one part that together construct a full post. Then use - * CURLOPT_HTTPPOST to send it off to libcurl. - */ -CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, - struct curl_httppost **last_post, - ...); - -/* - * callback function for curl_formget() - * The void *arg pointer will be the one passed as second argument to - * curl_formget(). - * The character buffer passed to it must not be freed. - * Should return the buffer length passed to it as the argument "len" on - * success. - */ -typedef size_t (*curl_formget_callback)(void *arg, const char *buf, - size_t len); - -/* - * NAME curl_formget() - * - * DESCRIPTION - * - * Serialize a curl_httppost struct built with curl_formadd(). - * Accepts a void pointer as second argument which will be passed to - * the curl_formget_callback function. - * Returns 0 on success. - */ -CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, - curl_formget_callback append); -/* - * NAME curl_formfree() - * - * DESCRIPTION - * - * Free a multipart formpost previously built with curl_formadd(). - */ -CURL_EXTERN void curl_formfree(struct curl_httppost *form); - -/* - * NAME curl_getenv() - * - * DESCRIPTION - * - * Returns a malloc()'ed string that MUST be curl_free()ed after usage is - * complete. DEPRECATED - see lib/README.curlx - */ -CURL_EXTERN char *curl_getenv(const char *variable); - -/* - * NAME curl_version() - * - * DESCRIPTION - * - * Returns a static ascii string of the libcurl version. - */ -CURL_EXTERN char *curl_version(void); - -/* - * NAME curl_easy_escape() - * - * DESCRIPTION - * - * Escapes URL strings (converts all letters consider illegal in URLs to their - * %XX versions). This function returns a new allocated string or NULL if an - * error occurred. - */ -CURL_EXTERN char *curl_easy_escape(CURL *handle, - const char *string, - int length); - -/* the previous version: */ -CURL_EXTERN char *curl_escape(const char *string, - int length); - - -/* - * NAME curl_easy_unescape() - * - * DESCRIPTION - * - * Unescapes URL encoding in strings (converts all %XX codes to their 8bit - * versions). This function returns a new allocated string or NULL if an error - * occurred. - * Conversion Note: On non-ASCII platforms the ASCII %XX codes are - * converted into the host encoding. - */ -CURL_EXTERN char *curl_easy_unescape(CURL *handle, - const char *string, - int length, - int *outlength); - -/* the previous version */ -CURL_EXTERN char *curl_unescape(const char *string, - int length); - -/* - * NAME curl_free() - * - * DESCRIPTION - * - * Provided for de-allocation in the same translation unit that did the - * allocation. Added in libcurl 7.10 - */ -CURL_EXTERN void curl_free(void *p); - -/* - * NAME curl_global_init() - * - * DESCRIPTION - * - * curl_global_init() should be invoked exactly once for each application that - * uses libcurl and before any call of other libcurl functions. - * - * This function is not thread-safe! - */ -CURL_EXTERN CURLcode curl_global_init(long flags); - -/* - * NAME curl_global_init_mem() - * - * DESCRIPTION - * - * curl_global_init() or curl_global_init_mem() should be invoked exactly once - * for each application that uses libcurl. This function can be used to - * initialize libcurl and set user defined memory management callback - * functions. Users can implement memory management routines to check for - * memory leaks, check for mis-use of the curl library etc. User registered - * callback routines with be invoked by this library instead of the system - * memory management routines like malloc, free etc. - */ -CURL_EXTERN CURLcode curl_global_init_mem(long flags, - curl_malloc_callback m, - curl_free_callback f, - curl_realloc_callback r, - curl_strdup_callback s, - curl_calloc_callback c); - -/* - * NAME curl_global_cleanup() - * - * DESCRIPTION - * - * curl_global_cleanup() should be invoked exactly once for each application - * that uses libcurl - */ -CURL_EXTERN void curl_global_cleanup(void); - -/* linked-list structure for the CURLOPT_QUOTE option (and other) */ -struct curl_slist -{ - char *data; - struct curl_slist *next; -}; - -/* - * NAME curl_slist_append() - * - * DESCRIPTION - * - * Appends a string to a linked list. If no list exists, it will be created - * first. Returns the new list, after appending. - */ -CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, - const char *); - -/* - * NAME curl_slist_free_all() - * - * DESCRIPTION - * - * free a previously built curl_slist. - */ -CURL_EXTERN void curl_slist_free_all(struct curl_slist *); - -/* - * NAME curl_getdate() - * - * DESCRIPTION - * - * Returns the time, in seconds since 1 Jan 1970 of the time string given in - * the first argument. The time argument in the second parameter is unused - * and should be set to NULL. - */ -CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); - -/* info about the certificate chain, only for OpenSSL builds. Asked - for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ -struct curl_certinfo -{ - int num_of_certs; /* number of certificates with information */ - struct curl_slist **certinfo; /* for each index in this array, there's a - linked list with textual information in the - format "name: value" */ -}; - -#define CURLINFO_STRING 0x100000 -#define CURLINFO_LONG 0x200000 -#define CURLINFO_DOUBLE 0x300000 -#define CURLINFO_SLIST 0x400000 -#define CURLINFO_MASK 0x0fffff -#define CURLINFO_TYPEMASK 0xf00000 - -typedef enum -{ - CURLINFO_NONE, /* first, never use this */ - CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, - CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, - CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, - CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, - CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, - CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, - CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, - CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, - CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, - CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, - CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, - CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, - CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, - CURLINFO_FILETIME = CURLINFO_LONG + 14, - CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, - CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, - CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, - CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, - CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, - CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, - CURLINFO_PRIVATE = CURLINFO_STRING + 21, - CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, - CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, - CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, - CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, - CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, - CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, - CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, - CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, - CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, - CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, - CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, - CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, - CURLINFO_CERTINFO = CURLINFO_SLIST + 34, - CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, - CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, - CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, - CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, - CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, - CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, - CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, - CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, - /* Fill in new entries below here! */ - - CURLINFO_LASTONE = 42 -} CURLINFO; - -/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as - CURLINFO_HTTP_CODE */ -#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE - -typedef enum -{ - CURLCLOSEPOLICY_NONE, /* first, never use this */ - - CURLCLOSEPOLICY_OLDEST, - CURLCLOSEPOLICY_LEAST_RECENTLY_USED, - CURLCLOSEPOLICY_LEAST_TRAFFIC, - CURLCLOSEPOLICY_SLOWEST, - CURLCLOSEPOLICY_CALLBACK, - - CURLCLOSEPOLICY_LAST /* last, never use this */ -} curl_closepolicy; - -#define CURL_GLOBAL_SSL (1<<0) -#define CURL_GLOBAL_WIN32 (1<<1) -#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) -#define CURL_GLOBAL_NOTHING 0 -#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL - - -/***************************************************************************** - * Setup defines, protos etc for the sharing stuff. - */ - -/* Different data locks for a single share */ -typedef enum -{ - CURL_LOCK_DATA_NONE = 0, - /* CURL_LOCK_DATA_SHARE is used internally to say that - * the locking is just made to change the internal state of the share - * itself. - */ - CURL_LOCK_DATA_SHARE, - CURL_LOCK_DATA_COOKIE, - CURL_LOCK_DATA_DNS, - CURL_LOCK_DATA_SSL_SESSION, - CURL_LOCK_DATA_CONNECT, - CURL_LOCK_DATA_LAST -} curl_lock_data; - -/* Different lock access types */ -typedef enum -{ - CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ - CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ - CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ - CURL_LOCK_ACCESS_LAST /* never use */ -} curl_lock_access; - -typedef void (*curl_lock_function)(CURL *handle, - curl_lock_data data, - curl_lock_access locktype, - void *userptr); -typedef void (*curl_unlock_function)(CURL *handle, - curl_lock_data data, - void *userptr); - -typedef void CURLSH; - -typedef enum -{ - CURLSHE_OK, /* all is fine */ - CURLSHE_BAD_OPTION, /* 1 */ - CURLSHE_IN_USE, /* 2 */ - CURLSHE_INVALID, /* 3 */ - CURLSHE_NOMEM, /* out of memory */ - CURLSHE_LAST /* never use */ -} CURLSHcode; - -typedef enum -{ - CURLSHOPT_NONE, /* don't use */ - CURLSHOPT_SHARE, /* specify a data type to share */ - CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ - CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ - CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ - CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock - callback functions */ - CURLSHOPT_LAST /* never use */ -} CURLSHoption; - -CURL_EXTERN CURLSH *curl_share_init(void); -CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); -CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); - -/**************************************************************************** - * Structures for querying information about the curl library at runtime. - */ - -typedef enum -{ - CURLVERSION_FIRST, - CURLVERSION_SECOND, - CURLVERSION_THIRD, - CURLVERSION_FOURTH, - CURLVERSION_LAST /* never actually use this */ -} CURLversion; - -/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by - basically all programs ever that want to get version information. It is - meant to be a built-in version number for what kind of struct the caller - expects. If the struct ever changes, we redefine the NOW to another enum - from above. */ -#define CURLVERSION_NOW CURLVERSION_FOURTH - -typedef struct -{ - CURLversion age; /* age of the returned struct */ - const char *version; /* LIBCURL_VERSION */ - unsigned int version_num; /* LIBCURL_VERSION_NUM */ - const char *host; /* OS/host/cpu/machine when configured */ - int features; /* bitmask, see defines below */ - const char *ssl_version; /* human readable string */ - long ssl_version_num; /* not used anymore, always 0 */ - const char *libz_version; /* human readable string */ - /* protocols is terminated by an entry with a NULL protoname */ - const char *const *protocols; - - /* The fields below this were added in CURLVERSION_SECOND */ - const char *ares; - int ares_num; - - /* This field was added in CURLVERSION_THIRD */ - const char *libidn; - - /* These field were added in CURLVERSION_FOURTH */ - - /* Same as '_libiconv_version' if built with HAVE_ICONV */ - int iconv_ver_num; - - const char *libssh_version; /* human readable string */ - -} curl_version_info_data; - -#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ -#define CURL_VERSION_KERBEROS4 (1<<1) /* kerberos auth is supported */ -#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ -#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ -#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ -#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth support */ -#define CURL_VERSION_DEBUG (1<<6) /* built with debug capabilities */ -#define CURL_VERSION_ASYNCHDNS (1<<7) /* asynchronous dns resolves */ -#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth */ -#define CURL_VERSION_LARGEFILE (1<<9) /* supports files bigger than 2GB */ -#define CURL_VERSION_IDN (1<<10) /* International Domain Names support */ -#define CURL_VERSION_SSPI (1<<11) /* SSPI is supported */ -#define CURL_VERSION_CONV (1<<12) /* character conversions supported */ -#define CURL_VERSION_CURLDEBUG (1<<13) /* debug memory tracking supported */ -#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ -#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegating to winbind helper */ - -/* -* NAME curl_version_info() -* -* DESCRIPTION -* -* This function returns a pointer to a static copy of the version info -* struct. See above. -*/ -CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); - -/* - * NAME curl_easy_strerror() - * - * DESCRIPTION - * - * The curl_easy_strerror function may be used to turn a CURLcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_easy_strerror(CURLcode); - -/* - * NAME curl_share_strerror() - * - * DESCRIPTION - * - * The curl_share_strerror function may be used to turn a CURLSHcode value - * into the equivalent human readable error string. This is useful - * for printing meaningful error messages. - */ -CURL_EXTERN const char *curl_share_strerror(CURLSHcode); - -/* - * NAME curl_easy_pause() - * - * DESCRIPTION - * - * The curl_easy_pause function pauses or unpauses transfers. Select the new - * state by setting the bitmask, use the convenience defines below. - * - */ -CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); - -#define CURLPAUSE_RECV (1<<0) -#define CURLPAUSE_RECV_CONT (0) - -#define CURLPAUSE_SEND (1<<2) -#define CURLPAUSE_SEND_CONT (0) - -#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) -#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) - -#ifdef __cplusplus -} -#endif - -/* unfortunately, the easy.h and multi.h include files need options and info - stuff before they can be included! */ -#include "easy.h" /* nothing in curl is fun without the easy stuff */ -#include "multi.h" - -/* the typechecker doesn't work in C++ (yet) */ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ - !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) -#include "typecheck-gcc.h" -#else -#if defined(__STDC__) && (__STDC__ >= 1) -/* This preprocessor magic that replaces a call with the exact same call is - only done to make sure application authors pass exactly three arguments - to these functions. */ -#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) -#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) -#endif /* __STDC__ >= 1 */ -#endif /* gcc >= 4.3 && !__cplusplus */ - -#endif /* __CURL_CURL_H */ diff --git a/service/protocol-plugin/plugins/hue/lib/curl/curlbuild.h b/service/protocol-plugin/plugins/hue/lib/curl/curlbuild.h deleted file mode 100644 index 566b322..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/curlbuild.h +++ /dev/null @@ -1,191 +0,0 @@ -/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ -#ifndef __CURL_CURLBUILD_H -#define __CURL_CURLBUILD_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * If you think that something actually needs to be changed, adjusted - * or fixed in this file, then, report it on the libcurl development - * mailing list: http://cool.haxx.se/mailman/listinfo/curl-library/ - * - * This header file shall only export symbols which are 'curl' or 'CURL' - * prefixed, otherwise public name space would be polluted. - * - * NOTE 2: - * ------- - * - * Right now you might be staring at file include/curl/curlbuild.h.in or - * at file include/curl/curlbuild.h, this is due to the following reason: - * - * On systems capable of running the configure script, the configure process - * will overwrite the distributed include/curl/curlbuild.h file with one that - * is suitable and specific to the library being configured and built, which - * is generated from the include/curl/curlbuild.h.in template file. - * - */ - -/* ================================================================ */ -/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ -/* ================================================================ */ - -#ifdef CURL_SIZEOF_LONG -#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_SOCKLEN_T -#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_SOCKLEN_T -#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined -#endif - -#ifdef CURL_TYPEOF_CURL_OFF_T -#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_T -#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_FORMAT_CURL_OFF_TU -#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined -#endif - -#ifdef CURL_FORMAT_OFF_T -#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined -#endif - -#ifdef CURL_SIZEOF_CURL_OFF_T -#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_T -#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined -#endif - -#ifdef CURL_SUFFIX_CURL_OFF_TU -#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" -Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined -#endif - -/* ================================================================ */ -/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ -/* ================================================================ */ - -/* Configure process defines this to 1 when it finds out that system */ -/* header file ws2tcpip.h must be included by the external interface. */ -/* #undef CURL_PULL_WS2TCPIP_H */ -#ifdef CURL_PULL_WS2TCPIP_H -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/types.h must be included by the external interface. */ -#define CURL_PULL_SYS_TYPES_H 1 -#ifdef CURL_PULL_SYS_TYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file stdint.h must be included by the external interface. */ -/* #undef CURL_PULL_STDINT_H */ -#ifdef CURL_PULL_STDINT_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file inttypes.h must be included by the external interface. */ -/* #undef CURL_PULL_INTTYPES_H */ -#ifdef CURL_PULL_INTTYPES_H -# include -#endif - -/* Configure process defines this to 1 when it finds out that system */ -/* header file sys/socket.h must be included by the external interface. */ -#define CURL_PULL_SYS_SOCKET_H 1 -#ifdef CURL_PULL_SYS_SOCKET_H -# include -#endif - -/* The size of `long', as computed by sizeof. */ -#define CURL_SIZEOF_LONG 4 - -/* Integral data type used for curl_socklen_t. */ -#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t - -/* The size of `curl_socklen_t', as computed by sizeof. */ -#define CURL_SIZEOF_CURL_SOCKLEN_T 4 - -/* Data type definition of curl_socklen_t. */ -typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; - -/* Signed integral data type used for curl_off_t. */ -#define CURL_TYPEOF_CURL_OFF_T long - -/* Data type definition of curl_off_t. */ -typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; - -/* curl_off_t formatting string directive without "%" conversion specifier. */ -#define CURL_FORMAT_CURL_OFF_T "ld" - -/* unsigned curl_off_t formatting string without "%" conversion specifier. */ -#define CURL_FORMAT_CURL_OFF_TU "lu" - -/* curl_off_t formatting string directive with "%" conversion specifier. */ -#define CURL_FORMAT_OFF_T "%ld" - -/* The size of `curl_off_t', as computed by sizeof. */ -#define CURL_SIZEOF_CURL_OFF_T 4 - -/* curl_off_t constant suffix. */ -#define CURL_SUFFIX_CURL_OFF_T L - -/* unsigned curl_off_t constant suffix. */ -#define CURL_SUFFIX_CURL_OFF_TU UL - -#endif /* __CURL_CURLBUILD_H */ diff --git a/service/protocol-plugin/plugins/hue/lib/curl/curlrules.h b/service/protocol-plugin/plugins/hue/lib/curl/curlrules.h deleted file mode 100644 index 5226347..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/curlrules.h +++ /dev/null @@ -1,261 +0,0 @@ -#ifndef __CURL_CURLRULES_H -#define __CURL_CURLRULES_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* ================================================================ */ -/* COMPILE TIME SANITY CHECKS */ -/* ================================================================ */ - -/* - * NOTE 1: - * ------- - * - * All checks done in this file are intentionally placed in a public - * header file which is pulled by curl/curl.h when an application is - * being built using an already built libcurl library. Additionally - * this file is also included and used when building the library. - * - * If compilation fails on this file it is certainly sure that the - * problem is elsewhere. It could be a problem in the curlbuild.h - * header file, or simply that you are using different compilation - * settings than those used to build the library. - * - * Nothing in this file is intended to be modified or adjusted by the - * curl library user nor by the curl library builder. - * - * Do not deactivate any check, these are done to make sure that the - * library is properly built and used. - * - * You can find further help on the libcurl development mailing list: - * http://cool.haxx.se/mailman/listinfo/curl-library/ - * - * NOTE 2 - * ------ - * - * Some of the following compile time checks are based on the fact - * that the dimension of a constant array can not be a negative one. - * In this way if the compile time verification fails, the compilation - * will fail issuing an error. The error description wording is compiler - * dependent but it will be quite similar to one of the following: - * - * "negative subscript or subscript is too large" - * "array must have at least one element" - * "-1 is an illegal array size" - * "size of array is negative" - * - * If you are building an application which tries to use an already - * built libcurl library and you are getting this kind of errors on - * this file, it is a clear indication that there is a mismatch between - * how the library was built and how you are trying to use it for your - * application. Your already compiled or binary library provider is the - * only one who can give you the details you need to properly use it. - */ - -/* - * Verify that some macros are actually defined. - */ - -#ifndef CURL_SIZEOF_LONG -# error "CURL_SIZEOF_LONG definition is missing!" -Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing -#endif - -#ifndef CURL_TYPEOF_CURL_SOCKLEN_T -# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" -Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing -#endif - -#ifndef CURL_SIZEOF_CURL_SOCKLEN_T -# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" -Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing -#endif - -#ifndef CURL_TYPEOF_CURL_OFF_T -# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" -Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_FORMAT_CURL_OFF_T -# error "CURL_FORMAT_CURL_OFF_T definition is missing!" -Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_FORMAT_CURL_OFF_TU -# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" -Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing -#endif - -#ifndef CURL_FORMAT_OFF_T -# error "CURL_FORMAT_OFF_T definition is missing!" -Error Compilation_aborted_CURL_FORMAT_OFF_T_is_missing -#endif - -#ifndef CURL_SIZEOF_CURL_OFF_T -# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" -Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_SUFFIX_CURL_OFF_T -# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" -Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing -#endif - -#ifndef CURL_SUFFIX_CURL_OFF_TU -# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" -Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing -#endif - -/* - * Macros private to this header file. - */ - -#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 - -#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 - -/* - * Verify that the size previously defined and expected for long - * is the same as the one reported by sizeof() at compile time. - */ - -typedef char -__curl_rule_01__ -[CurlchkszEQ(long, CURL_SIZEOF_LONG)]; - -/* - * Verify that the size previously defined and expected for - * curl_off_t is actually the the same as the one reported - * by sizeof() at compile time. - */ - -typedef char -__curl_rule_02__ -[CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; - -/* - * Verify at compile time that the size of curl_off_t as reported - * by sizeof() is greater or equal than the one reported for long - * for the current compilation. - */ - -typedef char -__curl_rule_03__ -[CurlchkszGE(curl_off_t, long)]; - -/* - * Verify that the size previously defined and expected for - * curl_socklen_t is actually the the same as the one reported - * by sizeof() at compile time. - */ - -typedef char -__curl_rule_04__ -[CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; - -/* - * Verify at compile time that the size of curl_socklen_t as reported - * by sizeof() is greater or equal than the one reported for int for - * the current compilation. - */ - -typedef char -__curl_rule_05__ -[CurlchkszGE(curl_socklen_t, int)]; - -/* ================================================================ */ -/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ -/* ================================================================ */ - -/* - * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow - * these to be visible and exported by the external libcurl interface API, - * while also making them visible to the library internals, simply including - * setup.h, without actually needing to include curl.h internally. - * If some day this section would grow big enough, all this should be moved - * to its own header file. - */ - -/* - * Figure out if we can use the ## preprocessor operator, which is supported - * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ - * or __cplusplus so we need to carefully check for them too. - */ - -#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ - defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ - defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ - defined(__ILEC400__) -/* This compiler is believed to have an ISO compatible preprocessor */ -#define CURL_ISOCPP -#else -/* This compiler is believed NOT to have an ISO compatible preprocessor */ -#undef CURL_ISOCPP -#endif - -/* - * Macros for minimum-width signed and unsigned curl_off_t integer constants. - */ - -#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) -# define __CURL_OFF_T_C_HLPR2(x) x -# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ - __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) -#else -# ifdef CURL_ISOCPP -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix -# else -# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix -# endif -# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) -# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) -# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) -#endif - -/* - * Get rid of macros private to this header file. - */ - -#undef CurlchkszEQ -#undef CurlchkszGE - -/* - * Get rid of macros not intended to exist beyond this point. - */ - -#undef CURL_PULL_WS2TCPIP_H -#undef CURL_PULL_SYS_TYPES_H -#undef CURL_PULL_SYS_SOCKET_H -#undef CURL_PULL_STDINT_H -#undef CURL_PULL_INTTYPES_H - -#undef CURL_TYPEOF_CURL_SOCKLEN_T -#undef CURL_TYPEOF_CURL_OFF_T - -#ifdef CURL_NO_OLDIES -#undef CURL_FORMAT_OFF_T /* not required since 7.19.0 - obsoleted in 7.20.0 */ -#endif - -#endif /* __CURL_CURLRULES_H */ diff --git a/service/protocol-plugin/plugins/hue/lib/curl/curlver.h b/service/protocol-plugin/plugins/hue/lib/curl/curlver.h deleted file mode 100644 index c2357b4..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/curlver.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __CURL_CURLVER_H -#define __CURL_CURLVER_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* This header file contains nothing but libcurl version info, generated by - a script at release-time. This was made its own header file in 7.11.2 */ - -/* This is the global package copyright */ -#define LIBCURL_COPYRIGHT "1996 - 2011 Daniel Stenberg, ." - -/* This is the version number of the libcurl package from which this header - file origins: */ -#define LIBCURL_VERSION "7.22.0" - -/* The numeric version number is also available "in parts" by using these - defines: */ -#define LIBCURL_VERSION_MAJOR 7 -#define LIBCURL_VERSION_MINOR 22 -#define LIBCURL_VERSION_PATCH 0 - -/* This is the numeric version of the libcurl version number, meant for easier - parsing and comparions by programs. The LIBCURL_VERSION_NUM define will - always follow this syntax: - - 0xXXYYZZ - - Where XX, YY and ZZ are the main version, release and patch numbers in - hexadecimal (using 8 bits each). All three numbers are always represented - using two digits. 1.2 would appear as "0x010200" while version 9.11.7 - appears as "0x090b07". - - This 6-digit (24 bits) hexadecimal number does not show pre-release number, - and it is always a greater number in a more recent release. It makes - comparisons with greater than and less than work. -*/ -#define LIBCURL_VERSION_NUM 0x071600 - -/* - * This is the date and time when the full source package was created. The - * timestamp is not stored in git, as the timestamp is properly set in the - * tarballs by the maketgz script. - * - * The format of the date should follow this template: - * - * "Mon Feb 12 11:35:33 UTC 2007" - */ -#define LIBCURL_TIMESTAMP "Tue Sep 13 16:53:51 UTC 2011" - -#endif /* __CURL_CURLVER_H */ diff --git a/service/protocol-plugin/plugins/hue/lib/curl/easy.h b/service/protocol-plugin/plugins/hue/lib/curl/easy.h deleted file mode 100644 index 9ef1669..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/easy.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __CURL_EASY_H -#define __CURL_EASY_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2008, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN CURL *curl_easy_init(void); -CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); -CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); -CURL_EXTERN void curl_easy_cleanup(CURL *curl); - -/* - * NAME curl_easy_getinfo() - * - * DESCRIPTION - * - * Request internal information from the curl session with this function. The - * third argument MUST be a pointer to a long, a pointer to a char * or a - * pointer to a double (as the documentation describes elsewhere). The data - * pointed to will be filled in accordingly and can be relied upon only if the - * function returns CURLE_OK. This function is intended to get used *AFTER* a - * performed transfer, all results from this function are undefined until the - * transfer is completed. - */ -CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); - - -/* - * NAME curl_easy_duphandle() - * - * DESCRIPTION - * - * Creates a new curl session handle with the same options set for the handle - * passed in. Duplicating a handle could only be a matter of cloning data and - * options, internal state info and things like persistent connections cannot - * be transferred. It is useful in multithreaded applications when you can run - * curl_easy_duphandle() for each new thread to avoid a series of identical - * curl_easy_setopt() invokes in every thread. - */ -CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); - -/* - * NAME curl_easy_reset() - * - * DESCRIPTION - * - * Re-initializes a CURL handle to the default values. This puts back the - * handle to the same state as it was in when it was just created. - * - * It does keep: live connections, the Session ID cache, the DNS cache and the - * cookies. - */ -CURL_EXTERN void curl_easy_reset(CURL *curl); - -/* - * NAME curl_easy_recv() - * - * DESCRIPTION - * - * Receives data from the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, - size_t *n); - -/* - * NAME curl_easy_send() - * - * DESCRIPTION - * - * Sends data over the connected socket. Use after successful - * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. - */ -CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, - size_t buflen, size_t *n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/service/protocol-plugin/plugins/hue/lib/curl/mprintf.h b/service/protocol-plugin/plugins/hue/lib/curl/mprintf.h deleted file mode 100644 index de7dd2f..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/mprintf.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef __CURL_MPRINTF_H -#define __CURL_MPRINTF_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include -#include /* needed for FILE */ - -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -CURL_EXTERN int curl_mprintf(const char *format, ...); -CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); -CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); -CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, - const char *format, ...); -CURL_EXTERN int curl_mvprintf(const char *format, va_list args); -CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); -CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); -CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, - const char *format, va_list args); -CURL_EXTERN char *curl_maprintf(const char *format, ...); -CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); - -#ifdef _MPRINTF_REPLACE -# undef printf -# undef fprintf -# undef sprintf -# undef vsprintf -# undef snprintf -# undef vprintf -# undef vfprintf -# undef vsnprintf -# undef aprintf -# undef vaprintf -# define printf curl_mprintf -# define fprintf curl_mfprintf -#ifdef CURLDEBUG -/* When built with CURLDEBUG we define away the sprintf() functions since we - don't want internal code to be using them */ -# define sprintf sprintf_was_used -# define vsprintf vsprintf_was_used -#else -# define sprintf curl_msprintf -# define vsprintf curl_mvsprintf -#endif -# define snprintf curl_msnprintf -# define vprintf curl_mvprintf -# define vfprintf curl_mvfprintf -# define vsnprintf curl_mvsnprintf -# define aprintf curl_maprintf -# define vaprintf curl_mvaprintf -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __CURL_MPRINTF_H */ diff --git a/service/protocol-plugin/plugins/hue/lib/curl/multi.h b/service/protocol-plugin/plugins/hue/lib/curl/multi.h deleted file mode 100644 index e095a7c..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/multi.h +++ /dev/null @@ -1,350 +0,0 @@ -#ifndef __CURL_MULTI_H -#define __CURL_MULTI_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ -/* - This is an "external" header file. Don't give away any internals here! - - GOALS - - o Enable a "pull" interface. The application that uses libcurl decides where - and when to ask libcurl to get/send data. - - o Enable multiple simultaneous transfers in the same thread without making it - complicated for the application. - - o Enable the application to select() on its own file descriptors and curl's - file descriptors simultaneous easily. - -*/ - -/* - * This header file should not really need to include "curl.h" since curl.h - * itself includes this file and we expect user applications to do #include - * without the need for especially including multi.h. - * - * For some reason we added this include here at one point, and rather than to - * break existing (wrongly written) libcurl applications, we leave it as-is - * but with this warning attached. - */ -#include "curl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void CURLM; - -typedef enum -{ - CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or - curl_multi_socket*() soon */ - CURLM_OK, - CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ - CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ - CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ - CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ - CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ - CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ - CURLM_LAST -} CURLMcode; - -/* just to make code nicer when using curl_multi_socket() you can now check - for CURLM_CALL_MULTI_SOCKET too in the same style it works for - curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ -#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM - -typedef enum -{ - CURLMSG_NONE, /* first, not used */ - CURLMSG_DONE, /* This easy handle has completed. 'result' contains - the CURLcode of the transfer */ - CURLMSG_LAST /* last, not used */ -} CURLMSG; - -struct CURLMsg -{ - CURLMSG msg; /* what this message means */ - CURL *easy_handle; /* the handle it concerns */ - union - { - void *whatever; /* message-specific data */ - CURLcode result; /* return code for transfer */ - } data; -}; -typedef struct CURLMsg CURLMsg; - -/* - * Name: curl_multi_init() - * - * Desc: inititalize multi-style curl usage - * - * Returns: a new CURLM handle to use in all 'curl_multi' functions. - */ -CURL_EXTERN CURLM *curl_multi_init(void); - -/* - * Name: curl_multi_add_handle() - * - * Desc: add a standard curl handle to the multi stack - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, - CURL *curl_handle); - -/* - * Name: curl_multi_remove_handle() - * - * Desc: removes a curl handle from the multi stack again - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, - CURL *curl_handle); - -/* - * Name: curl_multi_fdset() - * - * Desc: Ask curl for its fd_set sets. The app can use these to select() or - * poll() on. We want curl_multi_perform() called as soon as one of - * them are ready. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, - fd_set *read_fd_set, - fd_set *write_fd_set, - fd_set *exc_fd_set, - int *max_fd); - -/* - * Name: curl_multi_perform() - * - * Desc: When the app thinks there's data available for curl it calls this - * function to read/write whatever there is right now. This returns - * as soon as the reads and writes are done. This function does not - * require that there actually is data available for reading or that - * data can be written, it can be called just in case. It returns - * the number of handles that still transfer data in the second - * argument's integer-pointer. - * - * Returns: CURLMcode type, general multi error code. *NOTE* that this only - * returns errors etc regarding the whole multi stack. There might - * still have occurred problems on invidual transfers even when this - * returns OK. - */ -CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, - int *running_handles); - -/* - * Name: curl_multi_cleanup() - * - * Desc: Cleans up and removes a whole multi stack. It does not free or - * touch any individual easy handles in any way. We need to define - * in what state those handles will be if this function is called - * in the middle of a transfer. - * - * Returns: CURLMcode type, general multi error code. - */ -CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); - -/* - * Name: curl_multi_info_read() - * - * Desc: Ask the multi handle if there's any messages/informationals from - * the individual transfers. Messages include informationals such as - * error code from the transfer or just the fact that a transfer is - * completed. More details on these should be written down as well. - * - * Repeated calls to this function will return a new struct each - * time, until a special "end of msgs" struct is returned as a signal - * that there is no more to get at this point. - * - * The data the returned pointer points to will not survive calling - * curl_multi_cleanup(). - * - * The 'CURLMsg' struct is meant to be very simple and only contain - * very basic informations. If more involved information is wanted, - * we will provide the particular "transfer handle" in that struct - * and that should/could/would be used in subsequent - * curl_easy_getinfo() calls (or similar). The point being that we - * must never expose complex structs to applications, as then we'll - * undoubtably get backwards compatibility problems in the future. - * - * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out - * of structs. It also writes the number of messages left in the - * queue (after this read) in the integer the second argument points - * to. - */ -CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, - int *msgs_in_queue); - -/* - * Name: curl_multi_strerror() - * - * Desc: The curl_multi_strerror function may be used to turn a CURLMcode - * value into the equivalent human readable error string. This is - * useful for printing meaningful error messages. - * - * Returns: A pointer to a zero-terminated error message. - */ -CURL_EXTERN const char *curl_multi_strerror(CURLMcode); - -/* - * Name: curl_multi_socket() and - * curl_multi_socket_all() - * - * Desc: An alternative version of curl_multi_perform() that allows the - * application to pass in one of the file descriptors that have been - * detected to have "action" on them and let libcurl perform. - * See man page for details. - */ -#define CURL_POLL_NONE 0 -#define CURL_POLL_IN 1 -#define CURL_POLL_OUT 2 -#define CURL_POLL_INOUT 3 -#define CURL_POLL_REMOVE 4 - -#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD - -#define CURL_CSELECT_IN 0x01 -#define CURL_CSELECT_OUT 0x02 -#define CURL_CSELECT_ERR 0x04 - -typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ - curl_socket_t s, /* socket */ - int what, /* see above */ - void *userp, /* private callback - pointer */ - void *socketp); /* private socket - pointer */ -/* - * Name: curl_multi_timer_callback - * - * Desc: Called by libcurl whenever the library detects a change in the - * maximum number of milliseconds the app is allowed to wait before - * curl_multi_socket() or curl_multi_perform() must be called - * (to allow libcurl's timed events to take place). - * - * Returns: The callback should return zero. - */ -typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ - long timeout_ms, /* see above */ - void *userp); /* private callback - pointer */ - -CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, - curl_socket_t s, - int ev_bitmask, - int *running_handles); - -CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, - int *running_handles); - -#ifndef CURL_ALLOW_OLD_MULTI_SOCKET -/* This macro below was added in 7.16.3 to push users who recompile to use - the new curl_multi_socket_action() instead of the old curl_multi_socket() -*/ -#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) -#endif - -/* - * Name: curl_multi_timeout() - * - * Desc: Returns the maximum number of milliseconds the app is allowed to - * wait before curl_multi_socket() or curl_multi_perform() must be - * called (to allow libcurl's timed events to take place). - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, - long *milliseconds); - -#undef CINIT /* re-using the same name as in curl.h */ - -#ifdef CURL_ISOCPP -#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num -#else -/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ -#define LONG CURLOPTTYPE_LONG -#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT -#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT -#define OFF_T CURLOPTTYPE_OFF_T -#define CINIT(name,type,number) CURLMOPT_/**/name = type + number -#endif - -typedef enum -{ - /* This is the socket callback function pointer */ - CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), - - /* This is the argument passed to the socket callback */ - CINIT(SOCKETDATA, OBJECTPOINT, 2), - - /* set to 1 to enable pipelining for this multi handle */ - CINIT(PIPELINING, LONG, 3), - - /* This is the timer callback function pointer */ - CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), - - /* This is the argument passed to the timer callback */ - CINIT(TIMERDATA, OBJECTPOINT, 5), - - /* maximum number of entries in the connection cache */ - CINIT(MAXCONNECTS, LONG, 6), - - CURLMOPT_LASTENTRY /* the last unused */ -} CURLMoption; - - -/* - * Name: curl_multi_setopt() - * - * Desc: Sets options for the multi handle. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, - CURLMoption option, ...); - - -/* - * Name: curl_multi_assign() - * - * Desc: This function sets an association in the multi handle between the - * given socket and a private pointer of the application. This is - * (only) useful for curl_multi_socket uses. - * - * Returns: CURLM error code. - */ -CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, - curl_socket_t sockfd, void *sockp); - -#ifdef __cplusplus -} /* end of extern "C" */ -#endif - -#endif diff --git a/service/protocol-plugin/plugins/hue/lib/curl/stdcheaders.h b/service/protocol-plugin/plugins/hue/lib/curl/stdcheaders.h deleted file mode 100644 index ad82ef6..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/stdcheaders.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __STDC_HEADERS_H -#define __STDC_HEADERS_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -#include - -size_t fread (void *, size_t, size_t, FILE *); -size_t fwrite (const void *, size_t, size_t, FILE *); - -int strcasecmp(const char *, const char *); -int strncasecmp(const char *, const char *, size_t); - -#endif /* __STDC_HEADERS_H */ diff --git a/service/protocol-plugin/plugins/hue/lib/curl/typecheck-gcc.h b/service/protocol-plugin/plugins/hue/lib/curl/typecheck-gcc.h deleted file mode 100644 index a7cc4a4..0000000 --- a/service/protocol-plugin/plugins/hue/lib/curl/typecheck-gcc.h +++ /dev/null @@ -1,590 +0,0 @@ -#ifndef __CURL_TYPECHECK_GCC_H -#define __CURL_TYPECHECK_GCC_H -/*************************************************************************** - * _ _ ____ _ - * Project ___| | | | _ \| | - * / __| | | | |_) | | - * | (__| |_| | _ <| |___ - * \___|\___/|_| \_\_____| - * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. - * - * This software is licensed as described in the file COPYING, which - * you should have received as part of this distribution. The terms - * are also available at http://curl.haxx.se/docs/copyright.html. - * - * You may opt to use, copy, modify, merge, publish, distribute and/or sell - * copies of the Software, and permit persons to whom the Software is - * furnished to do so, under the terms of the COPYING file. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ***************************************************************************/ - -/* wraps curl_easy_setopt() with typechecking */ - -/* To add a new kind of warning, add an - * if(_curl_is_sometype_option(_curl_opt)) - * if(!_curl_is_sometype(value)) - * _curl_easy_setopt_err_sometype(); - * block and define _curl_is_sometype_option, _curl_is_sometype and - * _curl_easy_setopt_err_sometype below - * - * NOTE: We use two nested 'if' statements here instead of the && operator, in - * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x - * when compiling with -Wlogical-op. - * - * To add an option that uses the same type as an existing option, you'll just - * need to extend the appropriate _curl_*_option macro - */ -#define curl_easy_setopt(handle, option, value) \ -__extension__ ({ \ - __typeof__ (option) _curl_opt = option; \ - if(__builtin_constant_p(_curl_opt)) { \ - if(_curl_is_long_option(_curl_opt)) \ - if(!_curl_is_long(value)) \ - _curl_easy_setopt_err_long(); \ - if(_curl_is_off_t_option(_curl_opt)) \ - if(!_curl_is_off_t(value)) \ - _curl_easy_setopt_err_curl_off_t(); \ - if(_curl_is_string_option(_curl_opt)) \ - if(!_curl_is_string(value)) \ - _curl_easy_setopt_err_string(); \ - if(_curl_is_write_cb_option(_curl_opt)) \ - if(!_curl_is_write_cb(value)) \ - _curl_easy_setopt_err_write_callback(); \ - if((_curl_opt) == CURLOPT_READFUNCTION) \ - if(!_curl_is_read_cb(value)) \ - _curl_easy_setopt_err_read_cb(); \ - if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ - if(!_curl_is_ioctl_cb(value)) \ - _curl_easy_setopt_err_ioctl_cb(); \ - if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ - if(!_curl_is_sockopt_cb(value)) \ - _curl_easy_setopt_err_sockopt_cb(); \ - if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ - if(!_curl_is_opensocket_cb(value)) \ - _curl_easy_setopt_err_opensocket_cb(); \ - if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ - if(!_curl_is_progress_cb(value)) \ - _curl_easy_setopt_err_progress_cb(); \ - if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ - if(!_curl_is_debug_cb(value)) \ - _curl_easy_setopt_err_debug_cb(); \ - if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ - if(!_curl_is_ssl_ctx_cb(value)) \ - _curl_easy_setopt_err_ssl_ctx_cb(); \ - if(_curl_is_conv_cb_option(_curl_opt)) \ - if(!_curl_is_conv_cb(value)) \ - _curl_easy_setopt_err_conv_cb(); \ - if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ - if(!_curl_is_seek_cb(value)) \ - _curl_easy_setopt_err_seek_cb(); \ - if(_curl_is_cb_data_option(_curl_opt)) \ - if(!_curl_is_cb_data(value)) \ - _curl_easy_setopt_err_cb_data(); \ - if((_curl_opt) == CURLOPT_ERRORBUFFER) \ - if(!_curl_is_error_buffer(value)) \ - _curl_easy_setopt_err_error_buffer(); \ - if((_curl_opt) == CURLOPT_STDERR) \ - if(!_curl_is_FILE(value)) \ - _curl_easy_setopt_err_FILE(); \ - if(_curl_is_postfields_option(_curl_opt)) \ - if(!_curl_is_postfields(value)) \ - _curl_easy_setopt_err_postfields(); \ - if((_curl_opt) == CURLOPT_HTTPPOST) \ - if(!_curl_is_arr((value), struct curl_httppost)) \ - _curl_easy_setopt_err_curl_httpost(); \ - if(_curl_is_slist_option(_curl_opt)) \ - if(!_curl_is_arr((value), struct curl_slist)) \ - _curl_easy_setopt_err_curl_slist(); \ - if((_curl_opt) == CURLOPT_SHARE) \ - if(!_curl_is_ptr((value), CURLSH)) \ - _curl_easy_setopt_err_CURLSH(); \ - } \ - curl_easy_setopt(handle, _curl_opt, value); \ -}) - -/* wraps curl_easy_getinfo() with typechecking */ -/* FIXME: don't allow const pointers */ -#define curl_easy_getinfo(handle, info, arg) \ -__extension__ ({ \ - __typeof__ (info) _curl_info = info; \ - if(__builtin_constant_p(_curl_info)) { \ - if(_curl_is_string_info(_curl_info)) \ - if(!_curl_is_arr((arg), char *)) \ - _curl_easy_getinfo_err_string(); \ - if(_curl_is_long_info(_curl_info)) \ - if(!_curl_is_arr((arg), long)) \ - _curl_easy_getinfo_err_long(); \ - if(_curl_is_double_info(_curl_info)) \ - if(!_curl_is_arr((arg), double)) \ - _curl_easy_getinfo_err_double(); \ - if(_curl_is_slist_info(_curl_info)) \ - if(!_curl_is_arr((arg), struct curl_slist *)) \ - _curl_easy_getinfo_err_curl_slist(); \ - } \ - curl_easy_getinfo(handle, _curl_info, arg); \ -}) - -/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), - * for now just make sure that the functions are called with three - * arguments - */ -#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) -#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) - - -/* the actual warnings, triggered by calling the _curl_easy_setopt_err* - * functions */ - -/* To define a new warning, use _CURL_WARNING(identifier, "message") */ -#define _CURL_WARNING(id, message) \ - static void __attribute__((warning(message))) __attribute__((unused)) \ - __attribute__((noinline)) id(void) { __asm__(""); } - -_CURL_WARNING(_curl_easy_setopt_err_long, - "curl_easy_setopt expects a long argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, - "curl_easy_setopt expects a curl_off_t argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_string, - "curl_easy_setopt expects a " - "string (char* or char[]) argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_write_callback, - "curl_easy_setopt expects a curl_write_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_read_cb, - "curl_easy_setopt expects a curl_read_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, - "curl_easy_setopt expects a curl_ioctl_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, - "curl_easy_setopt expects a curl_sockopt_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, - "curl_easy_setopt expects a " - "curl_opensocket_callback argument for this option" - ) -_CURL_WARNING(_curl_easy_setopt_err_progress_cb, - "curl_easy_setopt expects a curl_progress_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_debug_cb, - "curl_easy_setopt expects a curl_debug_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, - "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_conv_cb, - "curl_easy_setopt expects a curl_conv_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_seek_cb, - "curl_easy_setopt expects a curl_seek_callback argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_cb_data, - "curl_easy_setopt expects a " - "private data pointer as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_error_buffer, - "curl_easy_setopt expects a " - "char buffer of CURL_ERROR_SIZE as argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_FILE, - "curl_easy_setopt expects a FILE* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_postfields, - "curl_easy_setopt expects a void* or char* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, - "curl_easy_setopt expects a struct curl_httppost* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_curl_slist, - "curl_easy_setopt expects a struct curl_slist* argument for this option") -_CURL_WARNING(_curl_easy_setopt_err_CURLSH, - "curl_easy_setopt expects a CURLSH* argument for this option") - -_CURL_WARNING(_curl_easy_getinfo_err_string, - "curl_easy_getinfo expects a pointer to char * for this info") -_CURL_WARNING(_curl_easy_getinfo_err_long, - "curl_easy_getinfo expects a pointer to long for this info") -_CURL_WARNING(_curl_easy_getinfo_err_double, - "curl_easy_getinfo expects a pointer to double for this info") -_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, - "curl_easy_getinfo expects a pointer to struct curl_slist * for this info") - -/* groups of curl_easy_setops options that take the same type of argument */ - -/* To add a new option to one of the groups, just add - * (option) == CURLOPT_SOMETHING - * to the or-expression. If the option takes a long or curl_off_t, you don't - * have to do anything - */ - -/* evaluates to true if option takes a long argument */ -#define _curl_is_long_option(option) \ - (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) - -#define _curl_is_off_t_option(option) \ - ((option) > CURLOPTTYPE_OFF_T) - -/* evaluates to true if option takes a char* argument */ -#define _curl_is_string_option(option) \ - ((option) == CURLOPT_URL || \ - (option) == CURLOPT_PROXY || \ - (option) == CURLOPT_INTERFACE || \ - (option) == CURLOPT_NETRC_FILE || \ - (option) == CURLOPT_USERPWD || \ - (option) == CURLOPT_USERNAME || \ - (option) == CURLOPT_PASSWORD || \ - (option) == CURLOPT_PROXYUSERPWD || \ - (option) == CURLOPT_PROXYUSERNAME || \ - (option) == CURLOPT_PROXYPASSWORD || \ - (option) == CURLOPT_NOPROXY || \ - (option) == CURLOPT_ACCEPT_ENCODING || \ - (option) == CURLOPT_REFERER || \ - (option) == CURLOPT_USERAGENT || \ - (option) == CURLOPT_COOKIE || \ - (option) == CURLOPT_COOKIEFILE || \ - (option) == CURLOPT_COOKIEJAR || \ - (option) == CURLOPT_COOKIELIST || \ - (option) == CURLOPT_FTPPORT || \ - (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ - (option) == CURLOPT_FTP_ACCOUNT || \ - (option) == CURLOPT_RANGE || \ - (option) == CURLOPT_CUSTOMREQUEST || \ - (option) == CURLOPT_SSLCERT || \ - (option) == CURLOPT_SSLCERTTYPE || \ - (option) == CURLOPT_SSLKEY || \ - (option) == CURLOPT_SSLKEYTYPE || \ - (option) == CURLOPT_KEYPASSWD || \ - (option) == CURLOPT_SSLENGINE || \ - (option) == CURLOPT_CAINFO || \ - (option) == CURLOPT_CAPATH || \ - (option) == CURLOPT_RANDOM_FILE || \ - (option) == CURLOPT_EGDSOCKET || \ - (option) == CURLOPT_SSL_CIPHER_LIST || \ - (option) == CURLOPT_KRBLEVEL || \ - (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ - (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ - (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ - (option) == CURLOPT_CRLFILE || \ - (option) == CURLOPT_ISSUERCERT || \ - (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ - (option) == CURLOPT_SSH_KNOWNHOSTS || \ - (option) == CURLOPT_MAIL_FROM || \ - (option) == CURLOPT_RTSP_SESSION_ID || \ - (option) == CURLOPT_RTSP_STREAM_URI || \ - (option) == CURLOPT_RTSP_TRANSPORT || \ - 0) - -/* evaluates to true if option takes a curl_write_callback argument */ -#define _curl_is_write_cb_option(option) \ - ((option) == CURLOPT_HEADERFUNCTION || \ - (option) == CURLOPT_WRITEFUNCTION) - -/* evaluates to true if option takes a curl_conv_callback argument */ -#define _curl_is_conv_cb_option(option) \ - ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ - (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) - -/* evaluates to true if option takes a data argument to pass to a callback */ -#define _curl_is_cb_data_option(option) \ - ((option) == CURLOPT_WRITEDATA || \ - (option) == CURLOPT_READDATA || \ - (option) == CURLOPT_IOCTLDATA || \ - (option) == CURLOPT_SOCKOPTDATA || \ - (option) == CURLOPT_OPENSOCKETDATA || \ - (option) == CURLOPT_PROGRESSDATA || \ - (option) == CURLOPT_WRITEHEADER || \ - (option) == CURLOPT_DEBUGDATA || \ - (option) == CURLOPT_SSL_CTX_DATA || \ - (option) == CURLOPT_SEEKDATA || \ - (option) == CURLOPT_PRIVATE || \ - (option) == CURLOPT_SSH_KEYDATA || \ - (option) == CURLOPT_INTERLEAVEDATA || \ - (option) == CURLOPT_CHUNK_DATA || \ - (option) == CURLOPT_FNMATCH_DATA || \ - 0) - -/* evaluates to true if option takes a POST data argument (void* or char*) */ -#define _curl_is_postfields_option(option) \ - ((option) == CURLOPT_POSTFIELDS || \ - (option) == CURLOPT_COPYPOSTFIELDS || \ - 0) - -/* evaluates to true if option takes a struct curl_slist * argument */ -#define _curl_is_slist_option(option) \ - ((option) == CURLOPT_HTTPHEADER || \ - (option) == CURLOPT_HTTP200ALIASES || \ - (option) == CURLOPT_QUOTE || \ - (option) == CURLOPT_POSTQUOTE || \ - (option) == CURLOPT_PREQUOTE || \ - (option) == CURLOPT_TELNETOPTIONS || \ - (option) == CURLOPT_MAIL_RCPT || \ - 0) - -/* groups of curl_easy_getinfo infos that take the same type of argument */ - -/* evaluates to true if info expects a pointer to char * argument */ -#define _curl_is_string_info(info) \ - (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) - -/* evaluates to true if info expects a pointer to long argument */ -#define _curl_is_long_info(info) \ - (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) - -/* evaluates to true if info expects a pointer to double argument */ -#define _curl_is_double_info(info) \ - (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) - -/* true if info expects a pointer to struct curl_slist * argument */ -#define _curl_is_slist_info(info) \ - (CURLINFO_SLIST < (info)) - - -/* typecheck helpers -- check whether given expression has requested type*/ - -/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, - * otherwise define a new macro. Search for __builtin_types_compatible_p - * in the GCC manual. - * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is - * the actual expression passed to the curl_easy_setopt macro. This - * means that you can only apply the sizeof and __typeof__ operators, no - * == or whatsoever. - */ - -/* XXX: should evaluate to true iff expr is a pointer */ -#define _curl_is_any_ptr(expr) \ - (sizeof(expr) == sizeof(void*)) - -/* evaluates to true if expr is NULL */ -/* XXX: must not evaluate expr, so this check is not accurate */ -#define _curl_is_NULL(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) - -/* evaluates to true if expr is type*, const type* or NULL */ -#define _curl_is_ptr(expr, type) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), type *) || \ - __builtin_types_compatible_p(__typeof__(expr), const type *)) - -/* evaluates to true if expr is one of type[], type*, NULL or const type* */ -#define _curl_is_arr(expr, type) \ - (_curl_is_ptr((expr), type) || \ - __builtin_types_compatible_p(__typeof__(expr), type [])) - -/* evaluates to true if expr is a string */ -#define _curl_is_string(expr) \ - (_curl_is_arr((expr), char) || \ - _curl_is_arr((expr), signed char) || \ - _curl_is_arr((expr), unsigned char)) - -/* evaluates to true if expr is a long (no matter the signedness) - * XXX: for now, int is also accepted (and therefore short and char, which - * are promoted to int when passed to a variadic function) */ -#define _curl_is_long(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), long) || \ - __builtin_types_compatible_p(__typeof__(expr), signed long) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ - __builtin_types_compatible_p(__typeof__(expr), int) || \ - __builtin_types_compatible_p(__typeof__(expr), signed int) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ - __builtin_types_compatible_p(__typeof__(expr), short) || \ - __builtin_types_compatible_p(__typeof__(expr), signed short) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ - __builtin_types_compatible_p(__typeof__(expr), char) || \ - __builtin_types_compatible_p(__typeof__(expr), signed char) || \ - __builtin_types_compatible_p(__typeof__(expr), unsigned char)) - -/* evaluates to true if expr is of type curl_off_t */ -#define _curl_is_off_t(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) - -/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ -/* XXX: also check size of an char[] array? */ -#define _curl_is_error_buffer(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), char *) || \ - __builtin_types_compatible_p(__typeof__(expr), char[])) - -/* evaluates to true if expr is of type (const) void* or (const) FILE* */ -#if 0 -#define _curl_is_cb_data(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_ptr((expr), FILE)) -#else /* be less strict */ -#define _curl_is_cb_data(expr) \ - _curl_is_any_ptr(expr) -#endif - -/* evaluates to true if expr is of type FILE* */ -#define _curl_is_FILE(expr) \ - (__builtin_types_compatible_p(__typeof__(expr), FILE *)) - -/* evaluates to true if expr can be passed as POST data (void* or char*) */ -#define _curl_is_postfields(expr) \ - (_curl_is_ptr((expr), void) || \ - _curl_is_arr((expr), char)) - -/* FIXME: the whole callback checking is messy... - * The idea is to tolerate char vs. void and const vs. not const - * pointers in arguments at least - */ -/* helper: __builtin_types_compatible_p distinguishes between functions and - * function pointers, hide it */ -#define _curl_callback_compatible(func, type) \ - (__builtin_types_compatible_p(__typeof__(func), type) || \ - __builtin_types_compatible_p(__typeof__(func), type*)) - -/* evaluates to true if expr is of type curl_read_callback or "similar" */ -#define _curl_is_read_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fread)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_read_callback) || \ - _curl_callback_compatible((expr), _curl_read_callback1) || \ - _curl_callback_compatible((expr), _curl_read_callback2) || \ - _curl_callback_compatible((expr), _curl_read_callback3) || \ - _curl_callback_compatible((expr), _curl_read_callback4) || \ - _curl_callback_compatible((expr), _curl_read_callback5) || \ - _curl_callback_compatible((expr), _curl_read_callback6)) -typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void *); -typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void *); -typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE *); -typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void *); -typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void *); -typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_write_callback or "similar" */ -#define _curl_is_write_cb(expr) \ - (_curl_is_read_cb(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), __typeof__(fwrite)) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_write_callback) || \ - _curl_callback_compatible((expr), _curl_write_callback1) || \ - _curl_callback_compatible((expr), _curl_write_callback2) || \ - _curl_callback_compatible((expr), _curl_write_callback3) || \ - _curl_callback_compatible((expr), _curl_write_callback4) || \ - _curl_callback_compatible((expr), _curl_write_callback5) || \ - _curl_callback_compatible((expr), _curl_write_callback6)) -typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void *); -typedef size_t (_curl_write_callback2)(const char *, size_t, size_t, - const void *); -typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE *); -typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void *); -typedef size_t (_curl_write_callback5)(const void *, size_t, size_t, - const void *); -typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE *); - -/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ -#define _curl_is_ioctl_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ioctl_callback) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ - _curl_callback_compatible((expr), _curl_ioctl_callback4)) -typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void *); -typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void *); -typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void *); -typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void *); - -/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ -#define _curl_is_sockopt_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_sockopt_callback) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ - _curl_callback_compatible((expr), _curl_sockopt_callback2)) -typedef int (_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); -typedef int (_curl_sockopt_callback2)(const void *, curl_socket_t, - curlsocktype); - -/* evaluates to true if expr is of type curl_opensocket_callback or - "similar" */ -#define _curl_is_opensocket_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_opensocket_callback) ||\ - _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ - _curl_callback_compatible((expr), _curl_opensocket_callback4)) -typedef curl_socket_t (_curl_opensocket_callback1) -(void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback2) -(void *, curlsocktype, const struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback3) -(const void *, curlsocktype, struct curl_sockaddr *); -typedef curl_socket_t (_curl_opensocket_callback4) -(const void *, curlsocktype, const struct curl_sockaddr *); - -/* evaluates to true if expr is of type curl_progress_callback or "similar" */ -#define _curl_is_progress_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_progress_callback) || \ - _curl_callback_compatible((expr), _curl_progress_callback1) || \ - _curl_callback_compatible((expr), _curl_progress_callback2)) -typedef int (_curl_progress_callback1)(void *, - double, double, double, double); -typedef int (_curl_progress_callback2)(const void *, - double, double, double, double); - -/* evaluates to true if expr is of type curl_debug_callback or "similar" */ -#define _curl_is_debug_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_debug_callback) || \ - _curl_callback_compatible((expr), _curl_debug_callback1) || \ - _curl_callback_compatible((expr), _curl_debug_callback2) || \ - _curl_callback_compatible((expr), _curl_debug_callback3) || \ - _curl_callback_compatible((expr), _curl_debug_callback4)) -typedef int (_curl_debug_callback1) (CURL *, - curl_infotype, char *, size_t, void *); -typedef int (_curl_debug_callback2) (CURL *, - curl_infotype, char *, size_t, const void *); -typedef int (_curl_debug_callback3) (CURL *, - curl_infotype, const char *, size_t, void *); -typedef int (_curl_debug_callback4) (CURL *, - curl_infotype, const char *, size_t, const void *); - -/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ -/* this is getting even messier... */ -#define _curl_is_ssl_ctx_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_ssl_ctx_callback) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ - _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) -typedef CURLcode (_curl_ssl_ctx_callback1)(CURL *, void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback2)(CURL *, void *, const void *); -typedef CURLcode (_curl_ssl_ctx_callback3)(CURL *, const void *, void *); -typedef CURLcode (_curl_ssl_ctx_callback4)(CURL *, const void *, const void *); -#ifdef HEADER_SSL_H -/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX - * this will of course break if we're included before OpenSSL headers... - */ -typedef CURLcode (_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); -typedef CURLcode (_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); -typedef CURLcode (_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, - const void *); -#else -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; -typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; -#endif - -/* evaluates to true if expr is of type curl_conv_callback or "similar" */ -#define _curl_is_conv_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_conv_callback) || \ - _curl_callback_compatible((expr), _curl_conv_callback1) || \ - _curl_callback_compatible((expr), _curl_conv_callback2) || \ - _curl_callback_compatible((expr), _curl_conv_callback3) || \ - _curl_callback_compatible((expr), _curl_conv_callback4)) -typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); -typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); -typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); -typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); - -/* evaluates to true if expr is of type curl_seek_callback or "similar" */ -#define _curl_is_seek_cb(expr) \ - (_curl_is_NULL(expr) || \ - __builtin_types_compatible_p(__typeof__(expr), curl_seek_callback) || \ - _curl_callback_compatible((expr), _curl_seek_callback1) || \ - _curl_callback_compatible((expr), _curl_seek_callback2)) -typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); -typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); - - -#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/service/protocol-plugin/plugins/hue/readme b/service/protocol-plugin/plugins/hue/readme deleted file mode 100644 index 04ccff8..0000000 --- a/service/protocol-plugin/plugins/hue/readme +++ /dev/null @@ -1,8 +0,0 @@ -1.Put the plugin library "libplugin-hue-light.so" ,xml file "plugin.xml", in a prepared folder, such as "/root/hue_plugin/" -2.Set the hue bridge user to "newdeveloper" -3.Using plugin manager tool - ./cpluff-console /root/hue_plugin run - -!!!for the hub network enviroment, you should add a route list for multicast -#route add default gw 192.168.0.1 eth0 - diff --git a/service/protocol-plugin/plugins/hue/src/HueBridge.cpp b/service/protocol-plugin/plugins/hue/src/HueBridge.cpp deleted file mode 100644 index 6ce7d30..0000000 --- a/service/protocol-plugin/plugins/hue/src/HueBridge.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "HueBridge.h" -using namespace std; - -HueBridgeConnection::HueBridgeConnection() -{ - //TODO -} - -HueBridgeConnection::~HueBridgeConnection() -{ - //TODO -} - -string HueBridgeConnection::UpnpDiscovery() -{ - struct sockaddr_in addrin, localaddr ; - struct timeval rtime ; - int newsock ; - int ret ; - char buf[1024] ; - int i = 0 ; - int yes = 1 ; - socklen_t addr_len = sizeof(struct sockaddr_in); - - rtime.tv_sec = 2 ; - rtime.tv_usec = 0 ; - - string host = "HOST: 239.255.255.250:1900\r\n"; - string st = "ST: upnp:rootdevice\r\n"; -// string st = "ST: ssdp:all\r\n"; - string mx = "MX: 3\r\n"; - string man = "MAN: ssdp:discover\r\n"; - string ssdp_msg = "M-SEARCH * HTTP/1.1\r\n"; - - ssdp_msg.append(host).append(man).append(mx).append(st); - - bzero(&addrin, sizeof(addrin)); - addrin.sin_family = AF_INET; - addrin.sin_addr.s_addr = inet_addr("239.255.255.250"); //htonl(INADDR_ANY) -// addrin.sin_addr.s_addr = htonl(INADDR_ANY); - addrin.sin_port = htons(1900); - - bzero(&localaddr, sizeof(localaddr)); - localaddr.sin_family = AF_INET; - localaddr.sin_addr.s_addr = htonl(INADDR_ANY); - localaddr.sin_port = htons(1901); - - newsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if ( newsock < 0) {return "";} - - ret = setsockopt( newsock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&rtime, sizeof(struct timeval)); - if (ret == -1) - { - close(newsock); - return ""; - } - ret = setsockopt( newsock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) ; - if (ret == -1) - { - close(newsock); - return ""; - } - - bind(newsock, (struct sockaddr *)&localaddr, addr_len); - - string hue_bridge; - while (i < 10) - { - i++; - yes = sizeof(struct sockaddr_in); - memset(buf, 0, sizeof(buf)); - ssize_t ret_num; - ret_num = sendto(newsock, ssdp_msg.c_str(), ssdp_msg.size(), 0, (struct sockaddr *)&addrin, - addr_len); - if (ret_num == -1) - { - close(newsock); - return ""; - } - ret = recvfrom( newsock, buf, sizeof(buf), 0, (struct sockaddr *)&addrin, &addr_len); - if ( ret < 0 ) {continue;} - else - { - hue_bridge = inet_ntoa(addrin.sin_addr); - break; - } - } - close(newsock); - return hue_bridge; -} - - - -vector GetBridges() -{ - vector bridge_list; - int i = 0; - while (i < 5) - { - HueBridgeConnection *p = new HueBridgeConnection(); - string hue_bridge = p->UpnpDiscovery(); - vector::iterator findit = find(bridge_list.begin(), bridge_list.end(), hue_bridge); - if (findit == bridge_list.end()) - bridge_list.push_back(hue_bridge); - delete p; - i++; - } - return bridge_list; -} - diff --git a/service/protocol-plugin/plugins/hue/src/HueBridge.h b/service/protocol-plugin/plugins/hue/src/HueBridge.h deleted file mode 100644 index 8bbf991..0000000 --- a/service/protocol-plugin/plugins/hue/src/HueBridge.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __HUE_BRIDGE_H__ -#define __HUE_BRIDGE_H__ -#include -#include -using namespace std; - -class HueBridgeConnection -{ - public: - HueBridgeConnection(); - virtual ~HueBridgeConnection(); - string UpnpDiscovery(); -}; - -extern "C" { - vector GetBridges(); -} -#endif //__HUE_BRIDGE_H__ diff --git a/service/protocol-plugin/plugins/hue/src/HueLightHandler.cpp b/service/protocol-plugin/plugins/hue/src/HueLightHandler.cpp deleted file mode 100644 index a9f7160..0000000 --- a/service/protocol-plugin/plugins/hue/src/HueLightHandler.cpp +++ /dev/null @@ -1,209 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 Intel Corporation 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -/// -/// This sample provides steps to define an interface for a resource -/// (properties and methods) and host this resource on the server. -/// - -#include "HueLightHandler.h" - -namespace OIC -{ - - void resourceHandler(std::shared_ptr resource); - - - /// This class represents a single resource named 'lightResource'. This resource has - /// two simple properties named 'state' - - LightResource::LightResource(string &resUrl, string &resType, string &resInterface, - string e_url): m_state(false), m_color(0), m_bright(0) - { - std::cout << "create LightResource ......." << std::endl; - resourceURL = resUrl; - resourceTypeName = resType; - resourceInterface = resInterface; - ext_url = e_url; - std::cout << "ResUrl = " << resourceURL << std::endl; - std::cout << "resType = " << resType << std::endl; - std::cout << "resInterface = " << resInterface << std::endl; - std::cout << "m_state = " << m_state << std::endl; - std::cout << "m_color = " << m_color << std::endl; - std::cout << "m_bright = " << m_bright << std::endl; - std::cout << "ext_url = " << ext_url << std::endl; - m_resourceHandle = NULL; - - resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; - } - - LightResource::~LightResource() {std::cout << "Leave LightResource" << std::endl;} - - /* To find if the resource instance is in the platform */ - - OCStackResult LightResource::findResource(OC::OCPlatform &platform) - { - string host = ""; - std::cout << "ResUrl = " << resourceURL << std::endl; - OCStackResult result = platform.findResource(host, resourceURL, &resourceHandler); - if (OC_STACK_OK != result) - { - cout << "findResource unsuccessful\n"; - } - else { cout << "findResource successful\n"; } - return result; - } - - - OCStackResult LightResource::addType(const OC::OCPlatform &platform, const std::string &type) - { - OCStackResult result = platform.bindTypeToResource(m_resourceHandle, type); - if (OC_STACK_OK != result) - { - cout << "Binding TypeName to Resource was unsuccessful\n"; - } - return result; - } - - OCStackResult LightResource::addInterface(const OC::OCPlatform &platform, - const std::string &interface) - { - OCStackResult result = platform.bindInterfaceToResource(m_resourceHandle, interface); - if (OC_STACK_OK != result) - { - cout << "Binding Interface to Resource was unsuccessful\n"; - } - return result; - } - -// /* This function internally calls intel registerResource API to unregister a leaved resource*/ -// void LightResource::unregisterResource(OC::OCPlatform& platform) -// { -// OC::OCStackResult result = platform.unregisterResource( -// m_resourceHandle, resourceURL, resourceTypeName, -// resourceInterface, &entityHandler, resourceProperty); -// if (OC::OC_STACK_OK != result) -// { -// cout << "Resource destory was unsuccessful\n"; -// } -// } -// -///* - OCResourceHandle LightResource::getHandle() - { - return m_resourceHandle; - } - - - void LightResource::setRepresentation(OC::OCRepresentation &light) - { - OC::AttributeMap attributeMap = light.getAttributeMap(); - std::cout << "Enter setRepresentation" << std::endl; - cout << "\t\t\t" << "Received representation: " << endl; - cout << "\t\t\t\t" << "state: " << attributeMap["state"][0] << endl; - cout << "\t\t\t\t" << "color: " << attributeMap["color"][0] << endl; - cout << "\t\t\t\t" << "bright: " << attributeMap["bright"][0] << endl; - - m_state = attributeMap["state"][0].compare("true") == 0; - m_color = std::stoi(attributeMap["color"][0]); - m_bright = std::stoi(attributeMap["bright"][0]); - } - - OC::OCRepresentation LightResource::getRepresentation() - { - OC::OCRepresentation light; - light.setUri(resourceURL); - - std::cout << "Enter getRepresentation" << std::endl; - - std::vector interfaces; - light.setResourceInterfaces(interfaces); - - std::vector types; - //types.push_back(m_lightType); - light.setResourceTypes(types); - - OC::AttributeMap attributeMap; - OC::AttributeValues stateVal; - if (m_state) - { - stateVal.push_back("true"); - } - else - { - stateVal.push_back("false"); - } - OC::AttributeValues colorVal; - colorVal.push_back(to_string(m_color)); - - OC::AttributeValues brightVal; - brightVal.push_back(to_string(m_bright)); - - attributeMap["state"] = stateVal; - attributeMap["color"] = colorVal; - attributeMap["bright"] = brightVal; - light.setAttributeMap(attributeMap); - - return light; - } - - - void resourceHandler(std::shared_ptr resource) - { - std::cout << "Enter resourceHandler" << std::endl; - } - - - /* This function internally calls intel registerResource API to register a new joined resource */ - OCStackResult LightResource::registerResource(OC::OCPlatform &platform, - std::function - entityHandler) - { - OCStackResult result = platform.registerResource( - m_resourceHandle, resourceURL, resourceTypeName, - resourceInterface, entityHandler, resourceProperty); - if (OC_STACK_OK != result) - { - cout << "Resource register was unsuccessful\n"; - } - else { cout << "RegisterResource successful\n"; } - return result; - } - - LightContainer::LightContainer(string &resUrl, string &resType, - string &resInterface): LightResource(resUrl, resType, resInterface, "") - { - std::cout << "Enter Constructor Container" << std::endl; - } - LightContainer::~LightContainer() - { - std::cout << "Enter Disonstructor Container" << std::endl; - if (m_container.empty()) std::cout << "Empty---- No need disconnstrator" << std::endl; - else m_container.clear(); - std::cout << "LightContainer disconstrator end ...." << std::endl; - } -} - - - - -// Entity handler can be implemented in several ways by the manufacturer - - diff --git a/service/protocol-plugin/plugins/hue/src/HueLightHandler.h b/service/protocol-plugin/plugins/hue/src/HueLightHandler.h deleted file mode 100644 index c8a6472..0000000 --- a/service/protocol-plugin/plugins/hue/src/HueLightHandler.h +++ /dev/null @@ -1,59 +0,0 @@ -#include - -#include - -#include "OCPlatform.h" -#include "OCApi.h" - - -namespace OIC -{ - void resourceHandler(std::shared_ptr resource); - class LightResource - { - public: - bool m_state; - int m_color; - int m_bright; - OCResourceHandle m_resourceHandle; - - std::string resourceURL; // URI of the resource - std::string resourceTypeName; // resource type name. In this case, it is light - std::string resourceInterface; // resource interface. - std::string ext_url; - - // OCResourceProperty is defined ocstack.h - uint8_t resourceProperty; - - public: - /// Constructor - LightResource(string &resUrl, string &resType, string &resInterface, string e_url); - LightResource(); - virtual ~LightResource(); - - /* Note that this does not need to be a member function: for classes you do not have - access to, you can accomplish this with a free function: */ - - // This function internally calls registerResource API. - OCStackResult findResource(OC::OCPlatform &platform); - OCStackResult registerResource(OC::OCPlatform &platform, - std::function - entityHandler); -// void unregisterResource(OC::OCPlatform& platform); -// - OCResourceHandle getHandle(); - void setRepresentation(OC::OCRepresentation &light); - OC::OCRepresentation getRepresentation(); - OCStackResult addType(const OC::OCPlatform &platform, const std::string &type); - OCStackResult addInterface(const OC::OCPlatform &platform, const std::string &interface); - }; - - class LightContainer: public LightResource - { - public: - vector m_container; - LightContainer(string &resUrl, string &resType, string &resInterface); - virtual ~LightContainer(); - }; - -} diff --git a/service/protocol-plugin/plugins/hue/src/HuePlugin.cpp b/service/protocol-plugin/plugins/hue/src/HuePlugin.cpp deleted file mode 100644 index ae05a16..0000000 --- a/service/protocol-plugin/plugins/hue/src/HuePlugin.cpp +++ /dev/null @@ -1,395 +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 HuePlugin.cpp - -/// @brief - - -#include -#include "curl/curl.h" -#include -#include -#include -#include -#include -#include -#include -#include "HueBridge.h" - -#include "HuePlugin.h" -#include "json_parse.h" -#include "simple_parse.h" - - -using namespace std; -using namespace boost::property_tree; -using namespace boost; - -using namespace OIC; - - -/** - * Response Data for curl handler to hue bridge - * @return Return the number of response data - * - */ -static size_t OnWriteData(void *buffer, size_t size, size_t nmemb, void *lpVoid) -{ - std::string *str = dynamic_cast((std::string *)lpVoid); - if ( NULL == str || NULL == buffer ) - { - return -1; - } - char *pData = (char *)buffer; - str->append(pData, size * nmemb); - return nmemb; -} - - -HuePlugin::HuePlugin() {cout << "HuePlugin::HuePlugin()" << endl;} -HuePlugin::~HuePlugin() { cout << "HuePlugin::~HuePlugin()" << endl;} - - -/** - * convert received json object to our defined resource info - * - */ -void HuePlugin::ConvertOcRes(string &hueRes, map &dictmap) -{ - stringstream stream; - ptree pt; - cout << "ConvertOcRes --" << hueRes.c_str() << endl; - if (hueRes.size()) - { - - replace_all(hueRes, "u\'", "\""); - replace_all(hueRes, "\'", "\""); - - stream << hueRes; - read_json(stream, pt); - string lig_id, lig_name; - for (ptree::iterator it = pt.begin(); it != pt.end(); ++it) - { - lig_id = it->first; - lig_name = it->second.get("name"); //first为空 - dictmap.insert(make_pair(lig_id, lig_name)); - } - } -} - - -/** - * Found the changed hue resources - * - * @param oldR the vector for the last search result - * @param newR the vector for the current search result - * @param comm the vector for both oldR and newR contain - * @return the map for changed resrouces - */ - -map HuePlugin::ResourcesChange(vector &oldR, vector &newR, - vector &comm) -{ - vectortempR; - vector::iterator iter = oldR.begin(); - vector::iterator tempiter; - while (iter != oldR.end()) - { - tempiter = find(newR.begin(), newR.end(), iter->c_str()); - if (tempiter != newR.end()) - { - comm.push_back(tempiter->c_str()); - } - iter++; - } - iter = comm.begin(); - while (iter != comm.end()) - { - tempiter = find(oldR.begin(), oldR.end(), iter->c_str()); - if (tempiter != oldR.end()) - { - oldR.erase(tempiter); - } - tempiter = find(newR.begin(), newR.end(), iter->c_str()); - if (tempiter != newR.end()) - { - newR.erase(tempiter); - } - iter++; - } - mapres_changed; // return the changed resource info - for (iter = oldR.begin(); iter != oldR.end(); iter++) - res_changed.insert(make_pair(*iter, "leave")); - for (iter = newR.begin(); iter != newR.end(); iter++) - res_changed.insert(make_pair(*iter, "join")); - - return res_changed; -} - - -/** - * create a local xml file to mark the resources information - * - */ - -//void HuePlugin::CreateResourcesFile(vector& resources, string& template_file) -//{ -// OCResourceDescManager* pi = new OCResourceDescManager(); -// if(resources.size()) -// pi->CreateResourcesXMl(resources, template_file); -// cout<<"After create xml file"< HuePlugin::SearchDeviceResources(vector &pool) -{ - cout << "HuePlugin::SearchDeviceResources()" << endl; - - res_pool = pool; - - - vectordev_url; - vectornew_res_pool; - - vector change_resources; - vector template_resources; - - vector bridge_list; - bridge_list = GetBridges(); - if (bridge_list.empty()) - { - cout << "No hue bridge found" << endl; - return change_resources; - } - vector::iterator it; - cout << "the result: " << endl; - for (it = bridge_list.begin(); it != bridge_list.end(); it++) - { - cout << *it << "," << endl; - string hue_bridge_url; - hue_bridge_url.append("http://").append(*it).append("/api/newdeveloper/lights"); - cout << "total url ---" << hue_bridge_url << endl; - dev_url.push_back(hue_bridge_url); - } - - vector::iterator url_iter; - vector tids; - for (url_iter = dev_url.begin(); url_iter != dev_url.end(); url_iter++) - { - string strUrl = *url_iter; - string strResponse; - cout << "ready to get_all_lights: " << strUrl << endl; - - CURLcode res; - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: application/json"); - - cout << "ready to curl" << endl; - CURL *curl = curl_easy_init(); - if (NULL == curl) - { - cout << "error" << endl; - } - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); - res = curl_easy_perform(curl); - - curl_easy_cleanup(curl); - curl_slist_free_all(headers); - - cout << "response " << strResponse.c_str() << endl; - - map dictmap; - HuePlugin::ConvertOcRes((string &) strResponse, dictmap); - map::iterator it; - for (it = dictmap.begin(); it != dictmap.end(); it++) - { - string res_url = strUrl; - res_url.append("/").append(it->first).append("/state"); - new_res_pool.push_back(res_url); - } - - } - - vector res_comm_pool; - - pool = new_res_pool; - map res_changed = ResourcesChange(res_pool, new_res_pool, res_comm_pool); - - for (map::iterator m_it = res_changed.begin(); m_it != res_changed.end(); m_it++) - { - string resUrl = m_it->first; - cout << "Changed resource: " << resUrl << endl; - size_t l_pos, r_pos; - l_pos = resUrl.find("//"); - r_pos = resUrl.find("/", l_pos + 2); - string br_ip = resUrl.substr(l_pos + 2, r_pos - l_pos - 2); - size_t index = resUrl.find_last_of("/"); - string add_res = resUrl.substr(index); - string res_id = br_ip.append(add_res); - - string res_state = m_it->second; - string res_type = "light"; - - OCResourceDesc r(res_id, res_type, resUrl, res_state); - change_resources.push_back(r); - template_resources.push_back(r); - } - - for (vector::iterator iter = res_comm_pool.begin(); iter != res_comm_pool.end(); iter++) - { - string resUrl = *iter; - size_t l_pos, r_pos; - l_pos = resUrl.find("//"); - r_pos = resUrl.find("/", l_pos + 2); - string br_ip = resUrl.substr(l_pos + 2, r_pos - l_pos - 2); - size_t index = resUrl.find_last_of("/"); - string add_res = resUrl.substr(index); - string res_id = br_ip.append(add_res); - - string res_state = "keep"; - string res_type = "light"; - - OCResourceDesc r(res_id, res_type, resUrl, res_state); - template_resources.push_back(r); - } - -// cout << "ready to create Xml file"< HuePlugin::ReadConfig(const char* filepath) -//{ -// string filename(filepath); -// vector devUrl; -// -// if(filename.find(".json") != string::npos){ -// cout<<"json file !"<(filename, pt); -// p1 = pt.get_child("bridges"); -// hue_res = pt.get("resource"); -// hue_ext = pt.get("extra"); -// -// for (ptree::iterator it = p1.begin(); it != p1.end(); ++it) -// { -// p2 = it->second; //first为空 -// hue_ip = p2.get("ip"); -// hue_user = p2.get("username"); -// -// string hue_url; -// -// hue_url.append("http://"); -// hue_url.append(hue_ip); -//// hue_url.append(":8080/"); -// hue_url.append("/"); -// hue_url.append(hue_ext); -// hue_url.append("/"); -// hue_url.append(hue_user); -// hue_url.append("/"); -// hue_url.append(hue_res); -// cout<<"Hue Url --- "< ip_vc; -// ip_vc = NormalizedOut((string&)ip_lst); -// -// key="username"; -// readConfigFile(filepath,(const string&)key, (string&)uname_lst); -// vector uname_vc; -// uname_vc = NormalizedOut((string&)uname_lst); -// -// vector::iterator iter1, iter2; -// map dictmap; -// for(iter1 = ip_vc.begin(), iter2 = uname_vc.begin(); iter1 != ip_vc.end(), iter2 != uname_vc.end(); iter1++,iter2++) -// { -//// dictmap.insert(make_pair(*iter1, *iter2)); -// dictmap.insert(make_pair(*iter2, *iter1)); -// } -// -// key = "extra"; -// readConfigFile(filepath,(const string&)key, (string&)ext); -// -// key = "resource"; -// readConfigFile(filepath,(const string&)key, (string&)res); -// -// map::iterator it; -// for (it=dictmap.begin();it!=dictmap.end();it++) -// { -// string hue_url; -// -// hue_url.append("http://"); -//// hue_url.append(it->first); -// hue_url.append(it->second); -//// hue_url.append(":8080/"); -// hue_url.append("/"); -// hue_url.append(ext); -// hue_url.append("/"); -//// hue_url.append(it->second); -// hue_url.append(it->first); -// hue_url.append("/"); -// hue_url.append(res); -// cout<<"Hue Url --- "< -#include -#include -#include -#include "OCResourceDesc.h" - -namespace OIC -{ - class HuePlugin - { - public: - HuePlugin(); - virtual ~HuePlugin(); - - /** - * Search Resources by philips hue protocol. - * - *@return Return a vector, which members are ResourceDesc type - * - */ - std::vector SearchDeviceResources(std::vector &pool); - - /** - * Read config file to fetch the Hue bridge search info - * - *@return Return a vector, which members are hue url type - * - */ -// std::vector ReadConfig(const char* filepath); - - /** - * convert received json object to we defined resource info struct - */ - void ConvertOcRes(string &hueRes, std::map &dictmap); - - /** - * create a local xml file to mark the resources information - *@resources Resources info - *@template_file the xml file - * - */ - void CreateResourcesFile(std::vector &resources, string &template_file); - - /** - * fetch Resources change information - *@param oldR the vector for the last search result - @param newR the vector for the current search result - @param comm the vector for both oldR and newR contain - @return the map for changed resrouces - */ - std::map ResourcesChange(std::vector &oldR, std::vector &newR, - std::vector &comm); - private: - std::vector res_pool; - }; -} -#endif //__HUEPlUGIN_H__ diff --git a/service/protocol-plugin/plugins/hue/src/OCResourceDesc.cpp b/service/protocol-plugin/plugins/hue/src/OCResourceDesc.cpp deleted file mode 100644 index 0ce999f..0000000 --- a/service/protocol-plugin/plugins/hue/src/OCResourceDesc.cpp +++ /dev/null @@ -1,165 +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 OCResourceDesc.cpp - -/// @brief - -#include "OCResourceDesc.h" - - -OCResourceDesc::OCResourceDesc() -{ - // TODO -} -OCResourceDesc::~OCResourceDesc() -{ - // TODO -} -OCResourceDesc::OCResourceDesc(string t_res_id, string t_type, string t_res_url, string t_res_state) -{ - resource_id = t_res_id; - type = t_type; - resource_url = t_res_url; - resource_state = t_res_state; -} -void OCResourceDesc::SetResource_id(string id) -{ - this->resource_id = id; -} -void OCResourceDesc::SetType(string type) -{ - this->type = type; -} -void OCResourceDesc::SetResource_url(string url) -{ - this->resource_url = url; -} -void OCResourceDesc::SetResource_state(string state) -{ - this->resource_state = state; -} -string OCResourceDesc::GetResource_id() -{ - return this->resource_id; -}; -string OCResourceDesc::GetType() -{ - return this->type; -} -string OCResourceDesc::GetResource_url() -{ - return this->resource_url; -} -string OCResourceDesc::GetResource_state() -{ - return this->resource_state; -} - - -//OCResourceDescManager::OCResourceDescManager(){ -// //todo -//} -//OCResourceDescManager::~OCResourceDescManager(){ -// //todo -//} -//void OCResourceDescManager::setresources(vector& resources){ -// this->ocResources=resources; -//}; -//vector OCResourceDescManager::GetResources(){ -// return this->ocResources; -//} -// -//vector* OCResourceDescManager::InitResources(string filename){ -// vector* resources=new vector(); -// TiXmlDocument *resourcesDoc = new TiXmlDocument(); -// resourcesDoc->LoadFile(filename.c_str()); -// TiXmlElement *RootElement = resourcesDoc->RootElement(); -// TiXmlElement *Resource = RootElement->FirstChildElement(); -// while(Resource){ -// OCResourceDesc* ocResource=new OCResourceDesc(); -// ocResource->SetResource_id(Resource->Attribute("id")); -// TiXmlElement *ResourceChild=Resource->FirstChildElement(); -// while(ResourceChild){ -// if (strcmp( ResourceChild->Value(), "type")==0){ -// ocResource->SetType(ResourceChild->FirstChild()->Value()); -// }else if (strcmp(ResourceChild->Value(), "resource_url") == 0) { -// ocResource->SetResource_url(ResourceChild->FirstChild()->Value()); -// }else if (strcmp(ResourceChild->Value(), "resource_state") == 0) { -// ocResource->SetResource_state(ResourceChild->FirstChild()->Value()); -// } else{ -// cout<<"error xml"; -// } -// ResourceChild=ResourceChild->NextSiblingElement(); -// } -// //cout<GetDrive_name()<push_back(*ocResource); -// Resource=Resource->NextSiblingElement(); -// } -// delete resourcesDoc; -// return resources; -//} -// -//TiXmlElement* OCResourceDescManager::CreateResource(OCResourceDesc& resource) { -// TiXmlElement *Resource = new TiXmlElement("resource"); -// Resource->SetAttribute("id", resource.GetResource_id().c_str()); -// TiXmlElement *type = new TiXmlElement("type"); -// TiXmlElement *url = new TiXmlElement("resource_url"); -// TiXmlElement *state = new TiXmlElement("resource_state"); -// -// TiXmlText *typeContent = new TiXmlText(resource.GetType().c_str()); -// TiXmlText *urlContent = new TiXmlText(resource.GetResource_url().c_str()); -// TiXmlText *stateContent = new TiXmlText(resource.GetResource_state().c_str()); -// -// type->LinkEndChild(typeContent); -// url->LinkEndChild(urlContent); -// state->LinkEndChild(stateContent); -// -// Resource->LinkEndChild(type); -// Resource->LinkEndChild(url); -// Resource->LinkEndChild(state); -// if (NULL != Resource) { -// return Resource; -// } else { -// return NULL; -// } -// return NULL; -//} -// -//void OCResourceDescManager::CreateResourcesXMl(vector& resources,string filename){ -// TiXmlDocument *resourcesDoc = new TiXmlDocument(); -// resourcesDoc->LoadFile(); -// TiXmlDeclaration *pDeclaration = new TiXmlDeclaration(("1.0"), (""),("")); -// TiXmlElement* resourcesElement = new TiXmlElement("resources"); -// vector::iterator iter; -// iter = resources.begin(); -// TiXmlElement* element; -// while (iter != resources.end()) { -// element=this->CreateResource(*iter); -// //cout<Attribute("id"); -// resourcesElement->LinkEndChild(element); -// *iter++; -// } -// resourcesDoc->LinkEndChild(pDeclaration); -// resourcesDoc->LinkEndChild(resourcesElement); -// resourcesDoc->SaveFile(filename.c_str()); -// delete element; -// delete pDeclaration; -//} diff --git a/service/protocol-plugin/plugins/hue/src/OCResourceDesc.h b/service/protocol-plugin/plugins/hue/src/OCResourceDesc.h deleted file mode 100644 index 9129191..0000000 --- a/service/protocol-plugin/plugins/hue/src/OCResourceDesc.h +++ /dev/null @@ -1,71 +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 OCResourceDesc.h - -/// @brief - -#ifndef __OCRESOURCEDESC_H__ -#define __OCRESOURCEDESC_H__ -#include -#include -#include -#include -using namespace std; - -class OCResourceDesc -{ - private: - string resource_id, type, resource_url, resource_state; - - public: - OCResourceDesc(); - virtual ~OCResourceDesc(); - OCResourceDesc(string, string, string, string); - void SetResource_id(string); - void SetType(string); - void SetResource_url(string); - void SetResource_state(string); - string GetResource_id(); - string GetType(); - string GetResource_url(); - string GetResource_state(); -}; - -//class OCResourceDescManager{ -//private: -// vector ocResources; -//private: -// TiXmlElement* CreateResource(OCResourceDesc&); -//public: -// -// void setresources(vector&); -// vector GetResources(); -// OCResourceDescManager(); -// -// vector* InitResources(string); -// -// void CreateResourcesXMl(vector&,string); -// -// -// ~OCResourceDescManager(); -//}; - -#endif //__OCRESOURCEDESC_H__ diff --git a/service/protocol-plugin/plugins/hue/src/PluginProvider.h b/service/protocol-plugin/plugins/hue/src/PluginProvider.h deleted file mode 100644 index 6e537d2..0000000 --- a/service/protocol-plugin/plugins/hue/src/PluginProvider.h +++ /dev/null @@ -1,53 +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 PluginProvider.h - -/// @brief - -#ifndef __PLUGIN_PROVIDER_H__ -#define __PLUGIN_PROVIDER_H__ -#include -#include -#include -#include "cpluff.h" -#include - - - -/** - * Creates a new plug-in instance. We use classifier instance as plug-in - * instance because it includes all the data our plug-in instance needs. - */ -static void *create(cp_context_t *ctx); - -/** - * Initializes and starts the plug-in. - */ -static int start(void *d); - -/** - * Destroys a plug-in instance. - */ -static void destroy(void *d); - - -#endif //__PLUGIN_PROVIDER_H__ - diff --git a/service/protocol-plugin/plugins/hue/src/http_curl.cpp b/service/protocol-plugin/plugins/hue/src/http_curl.cpp deleted file mode 100644 index 1e06233..0000000 --- a/service/protocol-plugin/plugins/hue/src/http_curl.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include "http_curl.h" -#include -#include -using namespace std; - -CHttpClient::CHttpClient(void): m_bDebug(false) -{ - -} - -CHttpClient::~CHttpClient(void) -{ - -} - -static int OnDebug(CURL *, curl_infotype itype, char *pData, size_t size, void *) -{ - if (itype == CURLINFO_TEXT) - { - //printf("[TEXT]%s\n", pData); - } - else if (itype == CURLINFO_HEADER_IN) - { - printf("[HEADER_IN]%s\n", pData); - } - else if (itype == CURLINFO_HEADER_OUT) - { - printf("[HEADER_OUT]%s\n", pData); - } - else if (itype == CURLINFO_DATA_IN) - { - printf("[DATA_IN]%s\n", pData); - } - else if (itype == CURLINFO_DATA_OUT) - { - printf("[DATA_OUT]%s\n", pData); - } - return 0; -} - -static size_t OnWriteData(void *buffer, size_t size, size_t nmemb, void *lpVoid) -{ - std::string *str = dynamic_cast((std::string *)lpVoid); - if ( NULL == str || NULL == buffer ) - { - return -1; - } - - char *pData = (char *)buffer; - str->append(pData, size * nmemb); - return nmemb; -} - -int CHttpClient::Post(const std::string &strUrl, const std::string &strPost, - std::string &strResponse) -{ - CURLcode res; - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: application/json"); - - CURL *curl = curl_easy_init(); - if (NULL == curl) - { - return CURLE_FAILED_INIT; - } - if (m_bDebug) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); - } - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); - curl_easy_setopt(curl, CURLOPT_POST, 1); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPost.c_str()); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - return res; -} - -int CHttpClient::Get(const std::string &strUrl, std::string &strResponse) -{ - CURLcode res; - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: application/json"); - - CURL *curl = curl_easy_init(); - if (NULL == curl) - { - return CURLE_FAILED_INIT; - } - if (m_bDebug) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); - } - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); - /** - * 当多个线程都使用超时处理的时候,同时主线程中有sleep或是wait等操作。 - * 如果不设置这个选项,libcurl将会发信号打断这个wait从而导致程序退出。 - */ - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - return res; -} - -int CHttpClient::Put(const std::string &strUrl, const std::string &strPut, std::string &strResponse) -{ - CURLcode res; - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: application/json"); - - CURL *curl = curl_easy_init(); - if (NULL == curl) - { - return CURLE_FAILED_INIT; - } - if (m_bDebug) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); - } - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT"); - curl_easy_setopt(curl, CURLOPT_POSTFIELDS, strPut.c_str()); - curl_easy_setopt(curl, CURLOPT_READFUNCTION, NULL); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - return res; -} - - -int CHttpClient::Delete(const std::string &strUrl, std::string &strResponse) -{ - CURLcode res; - struct curl_slist *headers = NULL; - headers = curl_slist_append(headers, "Content-Type: application/json"); - - CURL *curl = curl_easy_init(); - if (NULL == curl) - { - return CURLE_FAILED_INIT; - } - if (m_bDebug) - { - curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); - curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, OnDebug); - } - - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - curl_easy_setopt(curl, CURLOPT_URL, strUrl.c_str()); - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE"); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, OnWriteData); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&strResponse); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3); - curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3); - res = curl_easy_perform(curl); - curl_easy_cleanup(curl); - return res; -} - - -void CHttpClient::SetDebug(bool bDebug) -{ - m_bDebug = bDebug; -} diff --git a/service/protocol-plugin/plugins/hue/src/http_curl.h b/service/protocol-plugin/plugins/hue/src/http_curl.h deleted file mode 100644 index 55a95b2..0000000 --- a/service/protocol-plugin/plugins/hue/src/http_curl.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __HTTP_CURL_H__ -#define __HTTP_CURL_H__ - -#include -#include -using namespace std; - -class CHttpClient -{ - public: - CHttpClient(void); - ~CHttpClient(void); - - public: - - int Post(const std::string &strUrl, const std::string &strPost, std::string &strResponse); - - - int Get(const std::string &strUrl, std::string &strResponse); - - int Put(const std::string &strUrl, const std::string &strPost, std::string &strResponse); - - int Delete(const std::string &strUrl, std::string &strResponse); - - public: - void SetDebug(bool bDebug); - - private: - bool m_bDebug; -}; - -#endif diff --git a/service/protocol-plugin/plugins/hue/src/hue_light_sample.cpp b/service/protocol-plugin/plugins/hue/src/hue_light_sample.cpp deleted file mode 100644 index 4d974fe..0000000 --- a/service/protocol-plugin/plugins/hue/src/hue_light_sample.cpp +++ /dev/null @@ -1,526 +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 hue_light_sample.cpp - -/// @brief - - -#include -#include - -#include "PluginProvider.h" -#include "HuePlugin.h" -#include "HueLightHandler.h" -#include "json_parse.h" -#include "http_curl.h" - - - -/** - * If you set ENV variable "CONF_PATH", then it will be the default path of configure file, otherwise you can set the default path here - * - */ - -using namespace OIC; -using namespace boost::property_tree; -using namespace boost; -using namespace std; -using namespace OC; - - -pthread_t tid ; - -typedef struct classifier_t classifier_t; -struct classifier_t -{ - /** Classifier specific runtime data */ - cp_context_t *data; - - /** The classifying args */ - char *path; -}; - - - -/** -*handler of pluginmanager as a resource -*handle find resource or plugin managerment operations -*it would be trigger by Iotivity core -**/ - -int gObservation = 0; -void entityHandler(std::shared_ptr request, - std::shared_ptr response); - - -void *ChangeLightRepresentation (void *param) -{ - std::cout << "Enter ChangeLightRepresentation" << std::endl; - return NULL; -} - -std::string light_url; - - -string c_light_url = "/a/container"; -string c_resType = "core.container"; -string c_resInterface = OC::DEFAULT_INTERFACE; - -//LightContainer myLightContainer(c_light_url,c_resType,c_resInterface); -LightContainer *myLightContainer = new LightContainer(c_light_url, c_resType, c_resInterface); -OC::OCPlatform *platform_s; - - -void entityHandler(std::shared_ptr request, - std::shared_ptr response) -{ - std::cout << "\tIn Server CPP entity handler:\n"; - if (request) - { - // Get the request type and request flag - std::string requestType = request->getRequestType(); - OC::RequestHandlerFlag requestFlag = request->getRequestHandlerFlag(); - if (requestFlag == OC::RequestHandlerFlag::InitFlag) - { - std::cout << "\t\trequestFlag : Init\n"; - - // entity handler to perform resource initialization operations - } - else if (requestFlag == OC::RequestHandlerFlag::RequestFlag) - { - std::cout << "\t\trequestFlag : Request\n"; - - CHttpClient *client = new CHttpClient(); -// std::shared_ptr client; - std::string resp; - - // If the request type is GET - if (requestType == "GET") - { - std::cout << "\t\t\trequestType : GET\n"; - - // Check for query params (if any) - OC::QueryParamsMap queryParamsMap = request->getQueryParameters(); - cout << "\t\t\tquery params: \n"; - for (OC::QueryParamsMap::iterator it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) - { - cout << "\t\t\t\t" << it->first << ":" << it->second << endl; - } - - // Process query params and do required operations .. - - // Get the representation of this resource at this point and send it as response - // ShortCut need all resource in the same state !!! - OC::OCRepresentation rep; - rep = myLightContainer->getRepresentation(); - - OC::AttributeMap attributeMap; - std::cout << "..... container has " << myLightContainer->m_container.size() << std::endl; - if (myLightContainer->m_container.empty()) - { - cout << "no lights to get" << endl; - delete client; - return; - } - vector::iterator iter; - iter = myLightContainer->m_container.begin(); - light_url = iter->ext_url; - size_t index = light_url.find_last_of("/"); - string light_get_url = light_url.substr(0, index); - - if (response) - { - response->setErrorCode(200); - //TODO restful with hue light - - std::cout << "ready to send rest api to light" << std::endl; - OC::AttributeValues stateVal; - OC::AttributeValues colorVal; - OC::AttributeValues brightVal; - - std::cout << "ready to connect url ---- light_get_url " << light_get_url << std::endl; - client->Get((string &)light_get_url, (string &)resp); -// std::cout<<"<<<<<<<<(stream, pt); - string lig_status = pt.get("state.on"); - int lig_color = pt.get("state.hue"); - int lig_bri = pt.get("state.bri"); - - if (lig_status == "true") stateVal.push_back("true"); - else stateVal.push_back("false"); - colorVal.push_back(to_string(lig_color)); - brightVal.push_back(to_string(lig_bri)); - } - attributeMap["state"] = stateVal; - attributeMap["color"] = colorVal; - attributeMap["bright"] = brightVal; - - rep.setAttributeMap(attributeMap); -// std::cout<<"<<<<<<<<setResourceRepresentation(rep, findRes->second); - } - else - { -// std::cout<<"<<<<<<<<setResourceRepresentation(rep, DEFAULT_INTERFACE); - } - } - } - else if (requestType == "PUT") - { - std::cout << "\t\t\trequestType : PUT\n"; - std::cout << "..... container has " << myLightContainer->m_container.size() << std::endl; - if (myLightContainer->m_container.empty()) - { - cout << "no lights to put" << endl; - delete client; - return; - } - - // Check for query params (if any) - OC::QueryParamsMap queryParamsMap = request->getQueryParameters(); - cout << "\t\t\tquery params: \n"; - for (auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) - { - cout << "\t\t\t\t" << it->first << ":" << it->second << endl; - } - - // Check queryParamsMap and do required operations .. - - // Get the representation from the request - OC::OCRepresentation rep = request->getResourceRepresentation(); - OC::AttributeMap attributeMap = rep.getAttributeMap(); - - vector::iterator iter; - for (iter = myLightContainer->m_container.begin(); iter != myLightContainer->m_container.end(); - iter++) - { - iter->setRepresentation(rep); - light_url = iter->ext_url; - // Do related operations related to PUT request - //TODO restful with hue light - std::cout << "ready to send rest api to light" << std::endl; - bool m_state; - int m_color; - int m_bright; - - m_state = attributeMap["state"][0].compare("true") == 0; - m_color = std::stoi(attributeMap["color"][0]); - m_bright = std::stoi(attributeMap["bright"][0]); - - if (m_state) - { - string putbody = "{\"hue\": " + to_string(m_color) + ", \"on\": true, \"bri\": " + to_string( - m_bright) + "}"; - client->Put((string &)light_url, (string &)putbody, (string &)resp); - } - else - { - string putbody = "{\"hue\": 0, \"on\": false, \"bri\": 0}"; - client->Put((string &)light_url, (string &)putbody, (string &)resp); - } - rep = iter->getRepresentation(); - } - - if (response) - { - response->setErrorCode(200); - auto findRes = queryParamsMap.find("if"); - - if (findRes != queryParamsMap.end()) - { - response->setResourceRepresentation(rep, findRes->second); - } - else - { - std::cout << - "<<<<<<<<setResourceRepresentation(rep, DEFAULT_INTERFACE); - } - //TODO restful with hue light - } - } - else if (requestType == "POST") - { - // POST request operations - } - else if (requestType == "DELETE") - { - // DELETE request operations - } - delete client; - } - else if (requestFlag == OC::RequestHandlerFlag::ObserverFlag) - { - pthread_t threadId; - - std::cout << "\t\trequestFlag : Observer\n"; - gObservation = 1; - - static int startedThread = 0; - - // Observation happens on a different thread in ChangeLightRepresentation function. - // If we have not created the thread already, we will create one here. - if (!startedThread) - { - pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL); - startedThread = 1; - } - - } - } - else - { - std::cout << "Request invalid" << std::endl; - } -} - - - -/** - * Handler for hue light resources to intel core: - * - * register new resource and unregister lost resource - * - */ - -void *hue_light_handler(void *args) -{ - cout << "Enter the new hue_light_handler thread" << endl; - HuePlugin *device = new HuePlugin(); - vector res_pool; - - /* OC::PlatformConfig cfg; -// cfg.ipAddress = "134.134.161.33"; - cfg.ipAddress = "192.168.27.124"; - cfg.port = 56832; - cfg.mode = OC::ModeType::Server; - cfg.serviceType = OC::ServiceType::InProc;*/ - - PlatformConfig cfg { - OC::ServiceType::InProc, - OC::ModeType::Server, - "192.168.2.5", - 56832, - OC::QualityOfService::NonConfirmable - }; - - - platform_s = new OC::OCPlatform(cfg); - cout << "Create OCPlatform OK" << endl; - myLightContainer->registerResource(*platform_s, &entityHandler); - - string resURL = "/a/light"; //should /**/**/ type - while (1) - { - - vector ret = device->SearchDeviceResources(res_pool); - cout << "Search resources OK" << endl; - vector::iterator iter; - - if (ret.empty()) - { - cout << "Not found new lights" << endl; - sleep(10); - continue; - } - else - { - cout << "ready to get all lights info" << endl; - - // TO CONTROL ALL Lights - for (iter = ret.begin(); iter != ret.end(); iter++) - { - std::string res_id = iter->GetResource_id(); - std::string url = iter->GetResource_url(); - std::string state = iter->GetResource_state(); - - cout << "res_id = " << res_id << endl; - cout << "url = " << url << endl; - cout << "status = " << state << endl; - - //TO do register and unregister with Intel API - // adding new resource - if (state == "join") - { - light_url = url; - string resType = "core.light"; - string resInterface = OC::DEFAULT_INTERFACE; - LightResource *myLightResource = new LightResource(resURL, resType, resInterface, light_url); - - int abc; - do - { -// abc = myLightResource->registerResource(platform_s, &entityHandler); - abc = myLightResource->registerResource(*platform_s, NULL); -// myLightResource->addType(platform_s, "core.brightlight"); -// myLightResource->addInterface(platform_s, "oc.mi.ll"); - std::cout << "register result = " << abc << std::endl; - sleep(2); - } - while (abc != 0); - cout << "Notifying observers with resource handle: " << myLightResource->getHandle() << endl; - - myLightContainer->m_container.push_back(*myLightResource); - // modify the next light url - char *data; - int len = resURL.length(); - data = (char *)malloc((len + 1) * sizeof(char)); - if (!data) - { - delete myLightResource; - break; - } - resURL.copy(data, len, 0); - data[1]++; - resURL = data; - free(data); - delete myLightResource; - } - // remove leaving resource - else if (state == "leave") - { - light_url = url; - vector::iterator l_iter; - for (l_iter = myLightContainer->m_container.begin(); l_iter != myLightContainer->m_container.end();) - { - if (l_iter->ext_url == light_url) - { - myLightContainer->m_container.erase(l_iter); - break; - } - else l_iter++; - } - } - } - } - sleep(10); - } - delete device; -} - - - -/* ------------------------------------------------------------------------ - * Exported classifier information - * ----------------------------------------------------------------------*/ - -/** - * Plug-in runtime information for the framework. The name of this symbol - * is stored in the plug-in descriptor. - */ -static void *mycreate(cp_context_t *ctx) -{ - cout << "Test create!" << endl; - classifier_t *cl; - cl = (classifier_t *)malloc(sizeof(classifier_t)); - if (cl != NULL) - { - cl->data = ctx; - } - else - { - printf("Insufficient memory for plug-in data.\n"); - } - return cl; -} - -static int mystart(void *d) -{ - classifier_t *cl = (classifier_t *)d; - cp_context_t *data = cl->data; - cout << "Test started!" << endl; - - - int ret; - ret = pthread_create(&tid, NULL, hue_light_handler, NULL); - if (ret != 0) - { - cout << "Create Hue Light Handler Thread failed!" << endl; - return -1; - } - cout << "after create a thread....." << endl; - return 0; -} - -static void mydestroy(void *d) -{ -} - - -static void mystop(void *d) -{ -// int kill_ret = pthread_kill(tid, SIGKILL); - std::cout<<"test"<data != NULL) - { - free(cl->data); - } -} - - -CP_EXPORT cp_plugin_runtime_t hue_light = -{ - mycreate, - mystart, - mystop, - mydestroy -}; - - -/* -int main(int argc, char* argv[]) -{ - std::cout<<"hello"< -#include -#include -#include - -#include -#include -#include diff --git a/service/protocol-plugin/plugins/hue/src/search.cpp b/service/protocol-plugin/plugins/hue/src/search.cpp deleted file mode 100644 index e1340c2..0000000 --- a/service/protocol-plugin/plugins/hue/src/search.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include "curl/curl.h" -#include -#include -#include -#include -#include -#include -#include -#include "HueBridge.h" - -#include "HuePlugin.h" - - -int main() -{ - vector bridge_list; - bridge_list = GetBridges(); - if (bridge_list.empty()) - { - cout << "No hue bridge found" << endl; - } - vector::iterator it; - cout << "the result: " << endl; - for (it = bridge_list.begin(); it != bridge_list.end(); it++) - { - cout << *it << "," << endl; - string hue_bridge_url; - hue_bridge_url.append("http://").append(*it).append("/api/newdeveloper/lights"); - cout << "total url ---" << hue_bridge_url << endl; - } -} diff --git a/service/protocol-plugin/plugins/hue/src/simple_parse.cpp b/service/protocol-plugin/plugins/hue/src/simple_parse.cpp deleted file mode 100644 index 8c5703c..0000000 --- a/service/protocol-plugin/plugins/hue/src/simple_parse.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "simple_parse.h" - -using namespace std; -using namespace boost; - - - -bool readConfigFile(const char *cfgfilepath, const string &key, string &value) -{ - fstream cfgFile; - cfgFile.open(cfgfilepath); - if ( ! cfgFile.is_open()) - { - cout << "can not open cfg file!" << endl; - return false; - } - char tmp[1000]; - while (!cfgFile.eof()) - { - cfgFile.getline(tmp, 1000); - string line(tmp); - size_t pos; - if ((pos = line.find('#')) != -1) - { - if (0 == pos) continue; - } - pos = line.find('='); - if (pos == string::npos) continue; - string tmpKey = line.substr(0, pos); - trim(tmpKey); - - if (key == tmpKey) - { - size_t lscrap, rscrap; - if (((lscrap = line.find('[')) != string::npos) && ((rscrap = line.find(']')) != string::npos)) - { - value = line.substr(lscrap + 1, rscrap - lscrap - 1); - } - else value = line.substr(pos + 1); - trim(value); - return true; - } - } - return false; -} - - -vector NormalizedOut(string &input) -{ - char *outer_ptr = NULL; - char *p[20]; - int in = 0; - vector vecStr; - char *buf = (char *)input.c_str(); - - while ((p[in] = strtok_r(buf, ",", &outer_ptr)) != NULL) - { - string out = p[in]; - trim(out); - vecStr.push_back(out); - in++; - buf = NULL; - } - return vecStr; -} diff --git a/service/protocol-plugin/plugins/hue/src/simple_parse.h b/service/protocol-plugin/plugins/hue/src/simple_parse.h deleted file mode 100644 index fe3c255..0000000 --- a/service/protocol-plugin/plugins/hue/src/simple_parse.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _SIMPLE_PARSE_H_ -#define _SIMPLE_PARSE_H_ - -#include -#include -#include -#include -#include - -using namespace std; - -bool readConfigFile(const char *cfgfilepath, const string &key, string &value); -vector NormalizedOut(string &input); - -#endif - - diff --git a/service/protocol-plugin/plugins/hue/src/test/client_test.cpp b/service/protocol-plugin/plugins/hue/src/test/client_test.cpp deleted file mode 100644 index 33aae36..0000000 --- a/service/protocol-plugin/plugins/hue/src/test/client_test.cpp +++ /dev/null @@ -1,354 +0,0 @@ -/****************************************************************** -* -* Copyright 2014 Samsung Electronics All Rights Reserved. -* : Initialization Part has been referenced from OCClient.cpp file of Intel copyright. -* -* 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. -* -*******************************************************************/ - -// Client_test.cpp : Defines the entry point for the console application. -// -#include -#include -#include -#include "OCPlatform.h" -#include "OCApi.h" - -using namespace OC; - -const int SUCCESS_RESPONSE = 0; -std::shared_ptr curResource; -static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe; -int color; -int bri; - - -int observe_count() -{ - static int oc = 0; - return ++oc; -} - -void onObserve(const OCRepresentation &rep, const int &eCode, const int &sequenceNumber) -{ - if (eCode == SUCCESS_RESPONSE) - { - AttributeMap attributeMap = rep.getAttributeMap(); - std::cout << "OBSERVE RESULT:" << std::endl; - std::cout << "\tSequenceNumber: " << sequenceNumber << endl; - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - - std::cout << std::endl; - } - - if (observe_count() > 3) - { - std::cout << "Cancelling Observe..." << std::endl; - OCStackResult result = curResource->cancelObserve(); - - std::cout << "Cancel result: " << result << std::endl; - sleep(10); - std::cout << "DONE" << std::endl; - std::exit(0); - } - } - else - { - std::cout << "onObserve Response error: " << eCode << std::endl; - std::exit(-1); - } -} - -// callback handler on PUT request -void onPut(const OCRepresentation &rep, const int eCode) -{ - if (eCode == SUCCESS_RESPONSE) - { - std::cout << "PUT request was successful" << std::endl; - - AttributeMap attributeMap = rep.getAttributeMap(); - - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - - std::cout << std::endl; - } - std::vector children = rep.getChildren(); - - for (auto oit = children.begin(); oit != children.end(); ++oit) - { - attributeMap = oit->getAttributeMap(); - - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - - std::cout << std::endl; - } - } - if (OBSERVE_TYPE_TO_USE == ObserveType::Observe) - std::cout << endl << "Observe is used." << endl << endl; - else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll) - std::cout << endl << "ObserveAll is used." << endl << endl; - -// QueryParamsMap test; -// curResource->observe(OBSERVE_TYPE_TO_USE, test,&onObserve); - } - else - { - std::cout << "onPut Response error: " << eCode << std::endl; - std::exit(-1); - } -} - -// Local function to put a different state for this resource -void putLightRepresentation(std::shared_ptr resource, char *action, int color, - int bright) -{ - if (resource) - { - OCRepresentation rep; - std::cout << "Putting light representation..." << std::endl; - // Create AttributeMap - AttributeMap attributeMap; - // Add the attribute name and values in the attribute map - AttributeValues stateVal; - AttributeValues colorVal; - AttributeValues brightVal; - stateVal.push_back(action); - colorVal.push_back(to_string(color)); - brightVal.push_back(to_string(bright)); - - attributeMap["state"] = stateVal; - attributeMap["color"] = colorVal; - attributeMap["bright"] = brightVal; - - // Create QueryParameters Map and add query params (if any) - QueryParamsMap queryParamsMap; - rep.setAttributeMap(attributeMap); - - // Invoke resource's pit API with attribute map, query map and the callback parameter - resource->put(rep, queryParamsMap, &onPut); - } -} - -// callback handler on GET request -void onGet(const OCRepresentation &rep, const int eCode) -{ - if (eCode == SUCCESS_RESPONSE) - { - std::cout << "GET Succeeded:" << std::endl; - AttributeMap attributeMap = rep.getAttributeMap(); - std::cout << "Resource URI: " << rep.getUri() << std::endl; - - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - - std::cout << std::endl; - } - std::vector children = rep.getChildren(); - - for (auto oit = children.begin(); oit != children.end(); ++oit) - { - std::cout << "Child Resource URI: " << oit->getUri() << std::endl; - - attributeMap = oit->getAttributeMap(); - - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - - std::cout << std::endl; - } - } - -// putLightRepresentation(curResource); - } - else - { - std::cout << "onGet Response error: " << eCode << std::endl; - std::exit(-1); - } -} -// Local function to get representation of light resource -void getLightRepresentation(std::shared_ptr resource) -{ - if (resource) - { - std::cout << "Getting Light Representation..." << std::endl; - // Invoke resource's get API with the callback parameter - QueryParamsMap test; - resource->get(test, &onGet); - } -} - -// Callback to found resources -void foundResource(std::shared_ptr resource) -{ - if (curResource) - { - std::cout << "Found another resource, ignoring" << std::endl; - exit(-1); - } - - std::string resourceURI; - std::string hostAddress; - try - { - // Do some operations with resource object. - if (resource) - { - std::cout << "DISCOVERED Resource:" << std::endl; - // Get the resource URI - resourceURI = resource->uri(); - std::cout << "\tURI of the resource: " << resourceURI << std::endl; - - // Get the resource host address - hostAddress = resource->host(); - std::cout << "\tHost address of the resource: " << hostAddress << std::endl; - - // Get the resource types - std::cout << "\tList of resource types: " << std::endl; - for (auto &resourceTypes : resource->getResourceTypes()) - { - std::cout << "\t\t" << resourceTypes << std::endl; - } - - // Get the resource interfaces - std::cout << "\tList of resource interfaces: " << std::endl; - for (auto &resourceInterfaces : resource->getResourceInterfaces()) - { - std::cout << "\t\t" << resourceInterfaces << std::endl; - } - - if (!resourceURI.empty()) - { - curResource = resource; - // Call a local function which will internally invoke get API on the resource pointer - getLightRepresentation(resource); - } - } - else - { - // Resource is invalid - std::cout << "Resource is invalid" << std::endl; - } - - } - catch (std::exception &e) - { - //log(e.what()); - } -} - - -void UpResource(std::shared_ptr resource) -{ - foundResource(resource); - putLightRepresentation(resource, "true", color, bri); -} - - -void DownResource(std::shared_ptr resource) -{ - foundResource(resource); - putLightRepresentation(resource, "false", 0, 0); -} - - -int main(int argc, char *argv[]) -{ - // Create PlatformConfig object -/* - PlatformConfig cfg; - cfg.ipAddress = "192.168.1.10"; - cfg.port = 5683; - cfg.mode = ModeType::Client; - cfg.serviceType = ServiceType::InProc; -*/ - PlatformConfig cfg { - OC::ServiceType::InProc, - OC::ModeType::Client, - "192.168.2.5", - 56832, - OC::QualityOfService::NonConfirmable - }; - // Create a OCPlatform instance. - // Note: Platform creation is synchronous call. - try - { - OCPlatform platform(cfg); - if (argc == 1) - { - std::cout << "Created Platform..." << std::endl; - // Find all resources - platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.container", &foundResource); - std::cout << "Finding Resource... " << std::endl; - } - else if ((argc == 2) && strcmp(argv[1], "off") == 0) - { - std::cout << "Created Platform..." << std::endl; - // Find all resources - platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.container", &DownResource); - std::cout << "Finding Resource and Down... " << std::endl; - } - else if ((argc == 4) && strcmp(argv[1], "on") == 0) - { - std::cout << "Created Platform..." << std::endl; - // Find all resources - color = atoi(argv[2]); - bri = atoi(argv[3]); - platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.container", &UpResource); - std::cout << "Finding Resource Up and Set color and bright... " << std::endl; - } - else - { - std::cout << - "Usage: oic-light-client off \n oic-light-client on 20000 200 [color:0~65535, bri:0~255]" << - std::endl; - } - sleep(5); - } - catch (OCException e) - { - //log(e.what()); - } - - return 0; -} - diff --git a/service/protocol-plugin/plugins/hue/src/test/hue_web.py b/service/protocol-plugin/plugins/hue/src/test/hue_web.py deleted file mode 100644 index c47d0f7..0000000 --- a/service/protocol-plugin/plugins/hue/src/test/hue_web.py +++ /dev/null @@ -1,114 +0,0 @@ -import web -import sys -import json - -render = web.template.render('templates/') -urls = ( r'/api/newdeveloper/lights/1(.*)', 'LightIndex1', - r'/api/newdeveloper/lights', 'LightIndex2', - r'/api/zmc/lights', 'LightIndex3', - r'/api/zmc2/lights', 'LightIndex4', -) - - -ret_status = """{ - "state": { - "hue": 50000, - "on": true, - "effect": "none", - "alert": "none", - "bri": 200, - "sat": 200, - "ct": 500, - "xy": [0.5, 0.5], - "reachable": true, - "colormode": "hs" - }, - "type": "Living Colors", - "name": "LC 1", - "modelid": "LC0015", - "swversion": "1.0.3", - "pointsymbol": { - "1": "none", - "2": "none", - "3": "none", - "4": "none", - "5": "none", - "6": "none", - "7": "none", - "8": "none" - } -}""" -ret_status = json.loads(ret_status) - - -class LightIndex1: - def GET(self, name=None): - return ret_status - - - def POST(self, name=None): - print "Post ......" - data = web.data() - print data - return data - - def PUT(self, name=None): - print "Put ......" - data= web.data() - print data - r_data = json.loads(data) - ret_status["state"]["on"] = r_data["on"] - return data - - def DELETE(self, name=None): - print "DELETE ......" - return render.index(name) - -class LightIndex2: - def GET(self, name=None): - lights = """{ - "1": { - "name": "Bedroom" - }, - "2": { - "name": "Kitchen" - } - }""" - lights = json.loads(lights) - print type(lights) - return lights - -class LightIndex3: - def GET(self, name=None): - lights = """{ - "3": { - "name": "Whitehouse" - }, - "4": { - "name": "Desktop" - } - }""" - lights = json.loads(lights) - print type(lights) - return lights - - -class LightIndex4: - def GET(self, name=None): - lights = """{ - "5": { - "name": "test1" - }, - "6": { - "name": "test2" - } - }""" - lights = json.loads(lights) - print type(lights) - return lights - - -if __name__ =="__main__": - sys.argv.append("80") - app = web.application(urls, globals()) - app.run() diff --git a/service/protocol-plugin/plugins/hue/src/test/server_test.cpp b/service/protocol-plugin/plugins/hue/src/test/server_test.cpp deleted file mode 100644 index d3bbe32..0000000 --- a/service/protocol-plugin/plugins/hue/src/test/server_test.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/****************************************************************** -* -* Copyright 2014 Samsung Electronics All Rights Reserved. -* : Initialization Part has been referenced from OCClient.cpp file of Intel copyright. -* -* 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. -* -*******************************************************************/ - -/// -/// This sample provides steps to define an interface for a resource -/// (properties and methods) and host this resource on the server. -/// - -#include - -#include - -#include "OCPlatform.h" -#include "OCApi.h" - -using namespace OC; -using namespace std; - -int gObservation = 0; - -// Forward declaring the entityHandler -void entityHandler(std::shared_ptr request, - std::shared_ptr response); - -/// This class represents a single resource named 'lightResource'. This resource has -/// two simple properties named 'state' - -class LightResource -{ - public: - /// Access this property from a TB client - bool m_state; - int m_color; - int m_bright; - std::string m_lightUri; - OCResourceHandle m_resourceHandle; - - public: - /// Constructor - LightResource(): m_state(false), m_color(0), m_bright(0) {m_resourceHandle = NULL;} - - /* Note that this does not need to be a member function: for classes you do not have - access to, you can accomplish this with a free function: */ - - /// This function internally calls registerResource API. - void createResource(OC::OCPlatform &platform, string url, string res_type, - std::function Handler) - { - std::string resourceURI = url; // URI of the resource - std::string resourceTypeName = res_type; // resource type name. In this case, it is light - std::string resourceInterface = DEFAULT_INTERFACE; // resource interface. - - // OCResourceProperty is defined ocstack.h - uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; - - // This will internally create and register the resource. - OCStackResult result = platform.registerResource( - m_resourceHandle, resourceURI, resourceTypeName, - resourceInterface, Handler, resourceProperty); - - if (OC_STACK_OK != result) - { - cout << "Resource creation was unsuccessful\n"; - } - } - - OCResourceHandle getHandle() - { - return m_resourceHandle; - } - - void setRepresentation(OCRepresentation &light) - { - AttributeMap attributeMap = light.getAttributeMap(); - cout << "\t\t\t" << "Received representation: " << endl; - cout << "\t\t\t\t" << "state: " << attributeMap["state"][0] << endl; - cout << "\t\t\t\t" << "color: " << attributeMap["color"][0] << endl; - cout << "\t\t\t\t" << "bright: " << attributeMap["bright"][0] << endl; - - m_state = attributeMap["state"][0].compare("true") == 0; - m_color = std::stoi(attributeMap["color"][0]); - m_bright = std::stoi(attributeMap["bright"][0]); - } - - OCRepresentation getRepresentation() - { - OCRepresentation light; - light.setUri(m_lightUri); - std::vector interfaces; - //interfaces.push_back(m_lightInterface); - - light.setResourceInterfaces(interfaces); - - std::vector types; - //types.push_back(m_lightType); - - light.setResourceTypes(types); - - AttributeMap attributeMap; - AttributeValues stateVal; - if (m_state) - { - stateVal.push_back("true"); - } - else - { - stateVal.push_back("false"); - } - AttributeValues colorVal; - colorVal.push_back(to_string(m_color)); - AttributeValues brightVal; - brightVal.push_back(to_string(m_bright)); - - attributeMap["state"] = stateVal; - attributeMap["color"] = colorVal; - attributeMap["bright"] = brightVal; - - light.setAttributeMap(attributeMap); - return light; - } - - void addType(const OC::OCPlatform &platform, const std::string &type) const - { - OCStackResult result = platform.bindTypeToResource(m_resourceHandle, type); - if (OC_STACK_OK != result) - { - cout << "Binding TypeName to Resource was unsuccessful\n"; - } - } - - void addInterface(const OC::OCPlatform &platform, const std::string &interface) const - { - OCStackResult result = platform.bindInterfaceToResource(m_resourceHandle, interface); - if (OC_STACK_OK != result) - { - cout << "Binding TypeName to Resource was unsuccessful\n"; - } - } -}; - - - -// Create the instance of the resource class (in this case instance of class 'LightResource'). -LightResource myLightResource; -LightResource otherLightResource; - -// ChangeLightRepresentaion is an observation function, -// which notifies any changes to the resource to stack -// via notifyObservers -void *ChangeLightRepresentation (void *param) -{ - // This function continuously monitors for the changes - while (1) - { - sleep (5); - - if (gObservation) - { - // If under observation if there are any changes to the light resource - // we call notifyObservors - // - // For demostration we are changing the power value and notifying. - myLightResource.m_color += 10; - cout << "\nState updated to : " << myLightResource.m_color << endl; - cout << "Notifying observers with resource handle: " << myLightResource.getHandle() << endl; - - OCStackResult result = OCPlatform::notifyObservers(myLightResource.getHandle()); - - if (OC_STACK_NO_OBSERVERS == result) - { - cout << "No More observers, stopping notifications" << endl; - gObservation = 0; - } - } - } - return NULL; -} - - -// This is just a sample implementation of entity handler. -// Entity handler can be implemented in several ways by the manufacturer -void entityHandler(std::shared_ptr request, - std::shared_ptr response) -{ - cout << "\tIn Server CPP entity handler:\n"; - - if (request) - { - // Get the request type and request flag - std::string requestType = request->getRequestType(); - RequestHandlerFlag requestFlag = request->getRequestHandlerFlag(); - - if (requestFlag == RequestHandlerFlag::InitFlag) - { - cout << "\t\trequestFlag : Init\n"; - - // entity handler to perform resource initialization operations - } - else if (requestFlag == RequestHandlerFlag::RequestFlag) - { - cout << "\t\trequestFlag : Request\n"; - - // If the request type is GET - if (requestType == "GET") - { - cout << "\t\t\trequestType : GET\n"; - - // Check for query params (if any) - QueryParamsMap queryParamsMap = request->getQueryParameters(); - - cout << "\t\t\tquery params: \n"; - for (QueryParamsMap::iterator it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) - { - cout << "\t\t\t\t" << it->first << ":" << it->second << endl; - } - - - // Process query params and do required operations .. - - // Get the representation of this resource at this point and send it as response - OCRepresentation rep; - rep = myLightResource.getRepresentation(); - AttributeMap attributeMap; - - if (response) - { - // TODO Error Code - response->setErrorCode(200); - auto findRes = queryParamsMap.find("if"); - if (findRes != queryParamsMap.end()) - { - cout << "<<<<<<< found if....." << endl; - response->setResourceRepresentation(rep, findRes->second); - } - else - { - cout << "<<<<<<< not found if using default....." << endl; - response->setResourceRepresentation(rep, DEFAULT_INTERFACE); - } - } - } - else if (requestType == "PUT") - { - cout << "\t\t\trequestType : PUT\n"; - - // Check for query params (if any) - QueryParamsMap queryParamsMap = request->getQueryParameters(); - cout << "\t\t\tquery params: \n"; - for (auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) - { - cout << "\t\t\t\t" << it->first << ":" << it->second << endl; - } - - // Check queryParamsMap and do required operations .. - - // Get the representation from the request - OCRepresentation rep = request->getResourceRepresentation(); - myLightResource.setRepresentation(rep); - - rep = myLightResource.getRepresentation(); - - // Do related operations related to PUT request - - if (response) - { - response->setErrorCode(200); - response->setResourceRepresentation(rep, LINK_INTERFACE); - } - } - else if (requestType == "POST") - { - // POST request operations - } - else if (requestType == "DELETE") - { - // DELETE request operations - } - } - else if (requestFlag == RequestHandlerFlag::ObserverFlag) - { - pthread_t threadId; - - cout << "\t\trequestFlag : Observer\n"; - gObservation = 1; - - static int startedThread = 0; - - // Observation happens on a different thread in ChangeLightRepresentation function. - // If we have not created the thread already, we will create one here. - if (!startedThread) - { - pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)NULL); - startedThread = 1; - } - - } - } - else - { - std::cout << "Request invalid" << std::endl; - } -} - -int main() -{ - // Create PlatformConfig object - - /*PlatformConfig cfg; - cfg.ipAddress = "192.168.1.10"; - cfg.port = 56832; - cfg.mode = ModeType::Server; - cfg.serviceType = ServiceType::InProc; -*/ - PlatformConfig cfg { - OC::ServiceType::InProc, - OC::ModeType::Server, - "192.168.2.5", - 56832, - OC::QualityOfService::NonConfirmable - }; - - // Create a OCPlatform instance. - // Note: Platform creation is synchronous call. - try - { - OCPlatform platform(cfg); - - // Invoke createResource function of class light. - - string abc = "/a/light"; - - myLightResource.createResource(platform, abc, "core.light", &entityHandler); -// myLightResource.addType(platform, std::string("core.brightlight")); -// myLightResource.addInterface(platform, std::string("oc.mi.ll")); - - - // Perform app tasks - while (true) - { - // some tasks - } - } - catch (OCException e) - { - std::cout << e.what() << std::endl; - } - - - // No explicit call to stop the platform. - // When OCPlatform destructor is invoked, internally we do platform cleanup -} diff --git a/service/protocol-plugin/plugins/mqtt/build/linux/Makefile b/service/protocol-plugin/plugins/mqtt-fan/build/linux/Makefile similarity index 77% rename from service/protocol-plugin/plugins/mqtt/build/linux/Makefile rename to service/protocol-plugin/plugins/mqtt-fan/build/linux/Makefile index 91aa1e2..bf4db27 100644 --- a/service/protocol-plugin/plugins/mqtt/build/linux/Makefile +++ b/service/protocol-plugin/plugins/mqtt-fan/build/linux/Makefile @@ -9,6 +9,7 @@ LIB_DIR = ../../../../../../resource SRC_DIR = ../../src CXX_INC := -I$(LIB_DIR)/include/ +CXX_INC += -I$(LIB_DIR)/oc_logger/include/ CXX_INC += -I$(LIB_DIR)/csdk/stack/include/ CXX_INC += -I$(LIB_DIR)/csdk/ocsocket/include/ CXX_INC += -I$(LIB_DIR)/csdk/ocrandom/include/ @@ -17,6 +18,9 @@ CXX_INC += -I$(BOOST_DIR) CXX_INC += -I../../lib CXX_INC += -I../../../../lib/cpluff/libcpluff +LIB_OC_LOGGER := $(LIB_DIR)/oc_logger/lib/oc_logger.a +CXX_LIBS := $(LIB_DIR)/release/obj/liboc.a $(LIB_DIR)/csdk/linux/release/liboctbstack.a $(LIB_OC_LOGGER) ../../../../lib/cpluff/libcpluff/.libs/libcpluff.a + .PHONY: lib release_build ./release/fanserver_mqtt_plugin.so all: .PHONY @@ -30,7 +34,7 @@ release_build: cp plugin.xml release ./release/fanserver_mqtt_plugin.so: ./release/obj/fanserver_mqtt_plugin.o ./release/obj/fanserver.o - $(CXX) -shared -o ./release/fanserver_mqtt_plugin.so ./release/obj/fanserver_mqtt_plugin.o ./release/obj/fanserver.o $(LIB_DIR)/build/linux/release/obj/liboc.a $(LIB_DIR)/csdk/build/linux/release/liboctbstack.a ../../../../lib/cpluff/libcpluff/.libs/libcpluff.a -L../../lib -lmosquitto -lssl -lrt + $(CXX) -shared -o ./release/fanserver_mqtt_plugin.so ./release/obj/fanserver_mqtt_plugin.o ./release/obj/fanserver.o $(CXX_LIBS) -L../../lib -lmosquitto -lssl -lrt ./release/obj/fanserver_mqtt_plugin.o: $(SRC_DIR)/fanserver_mqtt_plugin.cpp $(CXX) $(CXX_INC) -fPIC -o ./release/obj/fanserver_mqtt_plugin.o -c $(SRC_DIR)/fanserver_mqtt_plugin.cpp diff --git a/service/protocol-plugin/plugins/mqtt/build/linux/plugin.xml b/service/protocol-plugin/plugins/mqtt-fan/build/linux/plugin.xml similarity index 100% rename from service/protocol-plugin/plugins/mqtt/build/linux/plugin.xml rename to service/protocol-plugin/plugins/mqtt-fan/build/linux/plugin.xml diff --git a/service/protocol-plugin/plugins/mqtt/lib/CMakeLists.txt b/service/protocol-plugin/plugins/mqtt-fan/lib/CMakeLists.txt similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/CMakeLists.txt rename to service/protocol-plugin/plugins/mqtt-fan/lib/CMakeLists.txt diff --git a/service/protocol-plugin/plugins/mqtt/lib/Makefile b/service/protocol-plugin/plugins/mqtt-fan/lib/Makefile similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/Makefile rename to service/protocol-plugin/plugins/mqtt-fan/lib/Makefile diff --git a/service/protocol-plugin/plugins/mqtt/lib/config.h b/service/protocol-plugin/plugins/mqtt-fan/lib/config.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/config.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/config.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/config.mk b/service/protocol-plugin/plugins/mqtt-fan/lib/config.mk similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/config.mk rename to service/protocol-plugin/plugins/mqtt-fan/lib/config.mk diff --git a/service/protocol-plugin/plugins/mqtt/lib/cpp/CMakeLists.txt b/service/protocol-plugin/plugins/mqtt-fan/lib/cpp/CMakeLists.txt similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/cpp/CMakeLists.txt rename to service/protocol-plugin/plugins/mqtt-fan/lib/cpp/CMakeLists.txt diff --git a/service/protocol-plugin/plugins/mqtt/lib/cpp/Makefile b/service/protocol-plugin/plugins/mqtt-fan/lib/cpp/Makefile similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/cpp/Makefile rename to service/protocol-plugin/plugins/mqtt-fan/lib/cpp/Makefile diff --git a/service/protocol-plugin/plugins/mqtt/lib/cpp/mosquittopp.cpp b/service/protocol-plugin/plugins/mqtt-fan/lib/cpp/mosquittopp.cpp similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/cpp/mosquittopp.cpp rename to service/protocol-plugin/plugins/mqtt-fan/lib/cpp/mosquittopp.cpp diff --git a/service/protocol-plugin/plugins/mqtt/lib/cpp/mosquittopp.h b/service/protocol-plugin/plugins/mqtt-fan/lib/cpp/mosquittopp.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/cpp/mosquittopp.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/cpp/mosquittopp.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/cpp/test.txt b/service/protocol-plugin/plugins/mqtt-fan/lib/cpp/test.txt similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/cpp/test.txt rename to service/protocol-plugin/plugins/mqtt-fan/lib/cpp/test.txt diff --git a/service/protocol-plugin/plugins/mqtt/lib/dummypthread.h b/service/protocol-plugin/plugins/mqtt-fan/lib/dummypthread.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/dummypthread.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/dummypthread.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/jsws/mosquitto.js b/service/protocol-plugin/plugins/mqtt-fan/lib/jsws/mosquitto.js similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/jsws/mosquitto.js rename to service/protocol-plugin/plugins/mqtt-fan/lib/jsws/mosquitto.js diff --git a/service/protocol-plugin/plugins/mqtt/lib/linker.version b/service/protocol-plugin/plugins/mqtt-fan/lib/linker.version similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/linker.version rename to service/protocol-plugin/plugins/mqtt-fan/lib/linker.version diff --git a/service/protocol-plugin/plugins/mqtt/lib/logging_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/logging_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/logging_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/logging_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/logging_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/logging_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/logging_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/logging_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/memory_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/memory_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/memory_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/memory_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/memory_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/memory_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/memory_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/memory_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/messages_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/messages_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/messages_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/messages_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/messages_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/messages_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/messages_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/messages_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/mosquitto.c b/service/protocol-plugin/plugins/mqtt-fan/lib/mosquitto.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/mosquitto.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/mosquitto.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/mosquitto.h b/service/protocol-plugin/plugins/mqtt-fan/lib/mosquitto.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/mosquitto.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/mosquitto.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/mosquitto_internal.h b/service/protocol-plugin/plugins/mqtt-fan/lib/mosquitto_internal.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/mosquitto_internal.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/mosquitto_internal.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/mqtt3_protocol.h b/service/protocol-plugin/plugins/mqtt-fan/lib/mqtt3_protocol.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/mqtt3_protocol.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/mqtt3_protocol.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/net_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/net_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/net_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/net_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/net_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/net_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/net_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/net_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/python/Makefile b/service/protocol-plugin/plugins/mqtt-fan/lib/python/Makefile similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/python/Makefile rename to service/protocol-plugin/plugins/mqtt-fan/lib/python/Makefile diff --git a/service/protocol-plugin/plugins/mqtt/lib/python/mosquitto.py b/service/protocol-plugin/plugins/mqtt-fan/lib/python/mosquitto.py similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/python/mosquitto.py rename to service/protocol-plugin/plugins/mqtt-fan/lib/python/mosquitto.py diff --git a/service/protocol-plugin/plugins/mqtt/lib/python/setup.py b/service/protocol-plugin/plugins/mqtt-fan/lib/python/setup.py similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/python/setup.py rename to service/protocol-plugin/plugins/mqtt-fan/lib/python/setup.py diff --git a/service/protocol-plugin/plugins/mqtt/lib/python/sub.py b/service/protocol-plugin/plugins/mqtt-fan/lib/python/sub.py similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/python/sub.py rename to service/protocol-plugin/plugins/mqtt-fan/lib/python/sub.py diff --git a/service/protocol-plugin/plugins/mqtt/lib/read_handle.c b/service/protocol-plugin/plugins/mqtt-fan/lib/read_handle.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/read_handle.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/read_handle.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/read_handle.h b/service/protocol-plugin/plugins/mqtt-fan/lib/read_handle.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/read_handle.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/read_handle.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/read_handle_client.c b/service/protocol-plugin/plugins/mqtt-fan/lib/read_handle_client.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/read_handle_client.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/read_handle_client.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/read_handle_shared.c b/service/protocol-plugin/plugins/mqtt-fan/lib/read_handle_shared.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/read_handle_shared.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/read_handle_shared.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/send_client_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/send_client_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/send_client_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/send_client_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/send_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/send_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/send_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/send_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/send_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/send_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/send_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/send_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/srv_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/srv_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/srv_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/srv_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/thread_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/thread_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/thread_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/thread_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/time_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/time_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/time_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/time_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/time_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/time_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/time_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/time_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/tls_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/tls_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/tls_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/tls_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/tls_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/tls_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/tls_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/tls_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/util_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/util_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/util_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/util_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/util_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/util_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/util_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/util_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt/lib/will_mosq.c b/service/protocol-plugin/plugins/mqtt-fan/lib/will_mosq.c similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/will_mosq.c rename to service/protocol-plugin/plugins/mqtt-fan/lib/will_mosq.c diff --git a/service/protocol-plugin/plugins/mqtt/lib/will_mosq.h b/service/protocol-plugin/plugins/mqtt-fan/lib/will_mosq.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/will_mosq.h rename to service/protocol-plugin/plugins/mqtt-fan/lib/will_mosq.h diff --git a/service/protocol-plugin/plugins/mqtt-fan/src/fanserver.cpp b/service/protocol-plugin/plugins/mqtt-fan/src/fanserver.cpp new file mode 100644 index 0000000..544679a --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-fan/src/fanserver.cpp @@ -0,0 +1,525 @@ +//****************************************************************** +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample provides steps to define an interface for a resource +/// (properties and methods) and host this resource on the server. +/// + +#include +#include +#include + +#include "OCPlatform.h" +#include "OCApi.h" +#include "../lib/mosquitto.h" +#include "fanserver.h" + +#include + + +using namespace OC; +using namespace std; +namespace PH = std::placeholders; + +time_t timer; // Define the timer +struct tm *tblock; // Define a structure for time block + + +int gObservation = 0; +void *ChangeFanRepresentation (void *param); + +// Specifies where to notify all observers or list of observers +// 0 - notifies all observers +// 1 - notifies list of observers +int isListOfObservers = 0; + +// Forward declaring the entityHandler + +/// This class represents a single resource named 'fanResource'. This resource has +/// two simple properties named 'state' and 'power' + + + +// Forward declaring the entityHandler +// void entityHandler(std::shared_ptr request, +// std::shared_ptr response); + +/// This class represents a single resource named 'fanResource'. This resource has +/// two simple properties named 'state' and 'power' +typedef struct plugin_data_t plugin_data_t; + +struct plugin_data_t +{ + cp_context_t *ctx; + pthread_t m_thread; // 2 + void *str; + bool flag; +}; + + +class FanResource +{ + public: + /// Access this property from a TB client + std::string m_name; + bool m_state; + int m_power; + int m_health; + std::string m_fanUri; + OCResourceHandle m_resourceHandle; + OCRepresentation m_fanRep; + ObservationIds m_interestedObservers; + + public: + /// Constructor + FanResource(): m_name("John's fan"), m_state(false), m_power(0), m_fanUri("/a/fan") + { + // Initialize representation + m_fanRep.setUri(m_fanUri); + + m_fanRep.setValue("state", m_state); + m_fanRep.setValue("power", m_power); + m_fanRep.setValue("name", m_name); + } + + + /* Note that this does not need to be a member function: for classes you do not have + access to, you can accomplish this with a free function: */ + + /// This function internally calls registerResource API. + void createResource() + { + std::string resourceURI = m_fanUri; // URI of the resource + std::string resourceTypeName = "core.fan"; // resource type name. In this case, it is fan + std::string resourceInterface = DEFAULT_INTERFACE; // resource interface. + + // OCResourceProperty is defined ocstack.h + uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; + + EntityHandler cb = std::bind(&FanResource::entityHandler, this, PH::_1, PH::_2); + + // This will internally create and register the resource. + OCStackResult result = OCPlatform::registerResource( + m_resourceHandle, resourceURI, resourceTypeName, + resourceInterface, cb, resourceProperty); + + if (OC_STACK_OK != result) + { + cout << "Resource creation was unsuccessful\n"; + } + } + + OCStackResult createResource1() + { + std::string resourceURI = "/a/fan1"; // URI of the resource + std::string resourceTypeName = "core.fan"; // resource type name. In this case, it is fan + std::string resourceInterface = DEFAULT_INTERFACE; // resource interface. + + // OCResourceProperty is defined ocstack.h + uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; + + EntityHandler cb = std::bind(&FanResource::entityHandler, this, PH::_1, PH::_2); + + OCResourceHandle resHandle; + + // This will internally create and register the resource. + OCStackResult result = OCPlatform::registerResource( + resHandle, resourceURI, resourceTypeName, + resourceInterface, cb, resourceProperty); + + if (OC_STACK_OK != result) + { + cout << "Resource creation was unsuccessful\n"; + } + + return result; + } + + OCResourceHandle getHandle() + { + return m_resourceHandle; + } + + // Puts representation. + // Gets values from the representation and + // updates the internal state + void put(OCRepresentation &rep) + { + try + { + if (rep.getValue("state", m_state)) + { + cout << "\t\t\t\t" << "state: " << m_state << endl; + } + else + { + cout << "\t\t\t\t" << "state not found in the representation" << endl; + } + + if (rep.getValue("power", m_power)) + { + cout << "\t\t\t\t" << "power: " << m_power << endl; + } + else + { + cout << "\t\t\t\t" << "power not found in the representation" << endl; + } + } + catch (exception &e) + { + cout << e.what() << endl; + } + + } + + // Post representation. + // Post can create new resource or simply act like put. + // Gets values from the representation and + // updates the internal state + OCRepresentation post(OCRepresentation &rep) + { + static int first = 1; + + // for the first time it tries to create a resource + if (first) + { + first = 0; + + if (OC_STACK_OK == createResource1()) + { + OCRepresentation rep1; + rep1.setValue("createduri", std::string("/a/fan1")); + + return rep1; + } + } + + // from second time onwards it just puts + put(rep); + return get(); + } + + + // gets the updated representation. + // Updates the representation with latest internal state before + // sending out. + OCRepresentation get() + { + m_fanRep.setValue("state", m_state); + m_fanRep.setValue("power", m_power); + + return m_fanRep; + } + + + void addType(const std::string &type) const + { + OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type); + if (OC_STACK_OK != result) + { + cout << "Binding TypeName to Resource was unsuccessful\n"; + } + } + + void addInterface(const std::string &interface) const + { + OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, interface); + if (OC_STACK_OK != result) + { + cout << "Binding TypeName to Resource was unsuccessful\n"; + } + } + + private: + // This is just a sample implementation of entity handler. + // Entity handler can be implemented in several ways by the manufacturer + OCEntityHandlerResult entityHandler(std::shared_ptr request, + std::shared_ptr response) + { + OCEntityHandlerResult result = OC_EH_OK; + + cout << "\tIn Server CPP entity handler:\n"; + + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag & RequestHandlerFlag::InitFlag) + { + cout << "\t\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + if (requestFlag & RequestHandlerFlag::RequestFlag) + { + cout << "\t\trequestFlag : Request === Handle by FanServer\n"; + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\t\trequestType : GET\n"; + + if (response) + { + // TODO Error Code + response->setErrorCode(200); + + response->setResourceRepresentation(get()); + } + } + else if (requestType == "PUT") + { + cout << "\t\t\trequestType : PUT\n"; + + OCRepresentation rep = request->getResourceRepresentation(); + + // Do related operations related to PUT request + + // Update the fanResource + put(rep); + + if (response) + { + // TODO Error Code + response->setErrorCode(200); + + response->setResourceRepresentation(get()); + } + + } + else if (requestType == "POST") + { + cout << "\t\t\trequestType : POST\n"; + + OCRepresentation rep = request->getResourceRepresentation(); + + // Do related operations related to POST request + + OCRepresentation rep_post = post(rep); + + if (response) + { + // TODO Error Code + response->setErrorCode(200); + + response->setResourceRepresentation(rep_post); + + if (rep_post.hasAttribute("createduri")) + { + result = OC_EH_RESOURCE_CREATED; + + response->setNewResourceUri(rep_post.getValue("createduri")); + } + + } + + // POST request operations + } + else if (requestType == "DELETE") + { + // DELETE request operations + } + } + + if (requestFlag & RequestHandlerFlag::ObserverFlag) + { + ObservationInfo observationInfo = request->getObservationInfo(); + if (ObserveAction::ObserveRegister == observationInfo.action) + { + m_interestedObservers.push_back(observationInfo.obsId); + } + else if (ObserveAction::ObserveUnregister == observationInfo.action) + { + m_interestedObservers.erase(std::remove( + m_interestedObservers.begin(), + m_interestedObservers.end(), + observationInfo.obsId), + m_interestedObservers.end()); + } + + pthread_t threadId; + + cout << "\t\trequestFlag : Observer\n"; + gObservation = 1; + static int startedThread = 0; + + // Observation happens on a different thread in ChangeFanRepresentation function. + // If we have not created the thread already, we will create one here. + if (!startedThread) + { + pthread_create (&threadId, NULL, ChangeFanRepresentation, (void *)this); + startedThread = 1; + } + } + } + else + { + std::cout << "Request invalid" << std::endl; + } + + return result; + } +}; + +// Create the instance of the resource class (in this case instance of class 'FanResource'). +struct mosquitto *myMosquitto; + +// ChangeFanRepresentaion is an observation function, +// which notifies any changes to the resource to stack +// via notifyObservers +void *ChangeFanRepresentation (void *param) +{ + FanResource *fanPtr = (FanResource *) param; + + // This function continuously monitors for the changes + while (1) + { + sleep (5); + + if (gObservation) + { + // If under observation if there are any changes to the fan resource + // we call notifyObservors + // + // For demostration we are changing the power value and notifying. + fanPtr->m_power += 10; + + cout << "\nPower updated to : " << fanPtr->m_power << endl; + cout << "Notifying observers with resource handle: " << fanPtr->getHandle() << endl; + + OCStackResult result = OC_STACK_OK; + + if (isListOfObservers) + { + std::shared_ptr resourceResponse(new OCResourceResponse()); + + resourceResponse->setErrorCode(200); + resourceResponse->setResourceRepresentation(fanPtr->get(), DEFAULT_INTERFACE); + + result = OCPlatform::notifyListOfObservers( fanPtr->getHandle(), + fanPtr->m_interestedObservers, + resourceResponse); + } + else + { + result = OCPlatform::notifyAllObservers(fanPtr->getHandle()); + } + + if (OC_STACK_NO_OBSERVERS == result) + { + cout << "No More observers, stopping notifications" << endl; + gObservation = 0; + } + } + } + + return NULL; +} + + +//int start_fanserver(void*) // 1 +void *start_fanserver(void *d) // 2 +{ + /*PlatformConfig cfg; + cfg.ipAddress = "192.168.2.5"; + cfg.port = 56832; + cfg.mode = ModeType::Server; + cfg.serviceType = ServiceType::InProc;*/ + // PlatformConfig cfg + // { + // OC::ServiceType::InProc, + // OC::ModeType::Server, + // "192.168.2.5", + // 56832, + // OC::QualityOfService::NonConfirmable + // }; + + // Create PlatformConfig object + + // Create a OCPlatform instance. + // Note: Platform creation is synchronous call. + + // Create PlatformConfig object + PlatformConfig cfg + { + OC::ServiceType::InProc, + OC::ModeType::Server, + "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces + 0, // Uses randomly available port + OC::QualityOfService::LowQos + }; + + OCPlatform::Configure(cfg); + + printf("start_fanserver [mosquitto] Null\n"); + try + { + FanResource myFanResource; + mosquitto_lib_init(); + myMosquitto = mosquitto_new("MQTT plug-in", true, NULL); + if (!myMosquitto) + { + printf("[mosquitto] Null\n"); + printf("You need to install mqtt broker\n"); + } + else + { + printf("Mosquitto is working\n"); + } + + //plugin_data_t *data = (plugin_data_t *)d; + //OCPlatform *platform = (OCPlatform*)data->str; + //myFanResource.m_platform = (OCPlatform*)data->str; + //OCPlatform platform(cfg); + // Invoke createResource function of class fan. + + //mosquitto_connect(myMosquitto, "192.168.2.5", 1883, 60); + mosquitto_connect(myMosquitto, "127.0.0.1", 1883, 60); + printf("Mosquitto Connection is done\n"); + myFanResource.createResource(); + //myFanResource.addType(std::string("core.fan")); + //myFanResource.addInterface(std::string("oc.mi.ll")); + // Get time of day + timer = time(NULL); + // Converts date/time to a structure + tblock = localtime(&timer); + // Output ASCII data/time + printf("FanReousrce reigishter time is: %s", asctime(tblock)); + // Perform app tasks + while (true) + { + // some tasks + } + } + catch (OCException e) + { + //log(e.what()); + } + // No explicit call to stop the platform. + // When OCPlatform destructor is invoked, internally we do platform cleanup + mosquitto_destroy(myMosquitto); + + mosquitto_lib_cleanup(); + printf("start_fanserver finish\n"); + pthread_exit((void *)0); +} diff --git a/service/protocol-plugin/plugins/mqtt/src/fanserver.h b/service/protocol-plugin/plugins/mqtt-fan/src/fanserver.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/src/fanserver.h rename to service/protocol-plugin/plugins/mqtt-fan/src/fanserver.h diff --git a/service/protocol-plugin/plugins/mqtt/src/fanserver_mqtt_plugin.cpp b/service/protocol-plugin/plugins/mqtt-fan/src/fanserver_mqtt_plugin.cpp similarity index 96% rename from service/protocol-plugin/plugins/mqtt/src/fanserver_mqtt_plugin.cpp rename to service/protocol-plugin/plugins/mqtt-fan/src/fanserver_mqtt_plugin.cpp index f8fe07d..f93be96 100644 --- a/service/protocol-plugin/plugins/mqtt/src/fanserver_mqtt_plugin.cpp +++ b/service/protocol-plugin/plugins/mqtt-fan/src/fanserver_mqtt_plugin.cpp @@ -24,8 +24,6 @@ extern "C" static void *create(cp_context_t *ctx) { - printf("function_create\n"); - plugin_data_t *data = (plugin_data_t *)malloc(sizeof(plugin_data_t)); if (data != NULL) @@ -43,7 +41,6 @@ static void *create(cp_context_t *ctx) static int start(void *d) { - printf("function_start\n"); plugin_data_t *data = (plugin_data_t *)d; data->str = (void *)cp_resolve_symbol(data->ctx, "fanserver_mqtt_plugin", "START_ARGUMENT", NULL); diff --git a/service/protocol-plugin/plugins/mqtt/src/fanserver_mqtt_plugin.h b/service/protocol-plugin/plugins/mqtt-fan/src/fanserver_mqtt_plugin.h similarity index 100% rename from service/protocol-plugin/plugins/mqtt/src/fanserver_mqtt_plugin.h rename to service/protocol-plugin/plugins/mqtt-fan/src/fanserver_mqtt_plugin.h diff --git a/service/protocol-plugin/plugins/mqtt-light/build/linux/Makefile b/service/protocol-plugin/plugins/mqtt-light/build/linux/Makefile new file mode 100644 index 0000000..9b2aca2 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/build/linux/Makefile @@ -0,0 +1,48 @@ +include ../../../../config.mk + +CXX = g++ + +CXX_FLAGS = -std=c++0x -Wall -pthread + +LIB_DIR = ../../../../../../resource + +SRC_DIR = ../../src + +CXX_INC := -I$(LIB_DIR)/include/ +CXX_INC += -I$(LIB_DIR)/oc_logger/include/ +CXX_INC += -I$(LIB_DIR)/csdk/stack/include/ +CXX_INC += -I$(LIB_DIR)/csdk/ocsocket/include/ +CXX_INC += -I$(LIB_DIR)/csdk/ocrandom/include/ +CXX_INC += -I$(LIB_DIR)/csdk/logger/include/ +CXX_INC += -I$(BOOST_DIR) +CXX_INC += -I../../lib +CXX_INC += -I../../../../lib/cpluff/libcpluff + +LIB_OC_LOGGER := $(LIB_DIR)/oc_logger/lib/oc_logger.a +CXX_LIBS := $(LIB_DIR)/release/obj/liboc.a $(LIB_DIR)/csdk/linux/release/liboctbstack.a $(LIB_OC_LOGGER) ../../../../lib/cpluff/libcpluff/.libs/libcpluff.a + +.PHONY: lib release_build ./release/lightserver_mqtt_plugin.so + +all: .PHONY + +lib: + cd ../../lib && $(MAKE) + +release_build: + -mkdir release + -mkdir release/obj + cp plugin.xml release + +./release/lightserver_mqtt_plugin.so: ./release/obj/lightserver_mqtt_plugin.o ./release/obj/lightserver.o + $(CXX) -shared -o ./release/lightserver_mqtt_plugin.so ./release/obj/lightserver_mqtt_plugin.o ./release/obj/lightserver.o $(CXX_LIBS) -L../../lib -lmosquitto -lssl -lrt + +./release/obj/lightserver_mqtt_plugin.o: $(SRC_DIR)/lightserver_mqtt_plugin.cpp + $(CXX) $(CXX_INC) -fPIC -o ./release/obj/lightserver_mqtt_plugin.o -c $(SRC_DIR)/lightserver_mqtt_plugin.cpp + +./release/obj/lightserver.o: $(SRC_DIR)/lightserver.cpp + $(CXX) $(CXX_FLAGS) -fPIC -o ./release/obj/lightserver.o -c $(SRC_DIR)/lightserver.cpp $(CXX_INC) + +clean: + cd ../../lib && $(MAKE) clean + rm -rf ./release/obj + cd ./release && rm -f *.so diff --git a/service/protocol-plugin/plugins/mqtt-light/build/linux/plugin.xml b/service/protocol-plugin/plugins/mqtt-light/build/linux/plugin.xml new file mode 100644 index 0000000..15ea179 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/build/linux/plugin.xml @@ -0,0 +1,7 @@ + + + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/CMakeLists.txt b/service/protocol-plugin/plugins/mqtt-light/lib/CMakeLists.txt new file mode 100644 index 0000000..2ae6f6a --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/CMakeLists.txt @@ -0,0 +1,71 @@ +add_subdirectory(cpp) + +option(WITH_THREADING "Include client library threading support?" ON) +if (${WITH_THREADING} STREQUAL ON) + add_definitions("-DWITH_THREADING") + if (WIN32) + set (PTHREAD_LIBRARIES C:\\pthreads\\Pre-built.2\\lib\\x86\\pthreadVC2.lib) + set (PTHREAD_INCLUDE_DIR C:\\pthreads\\Pre-built.2\\include) + else (WIN32) + set (PTHREAD_LIBRARIES pthread) + set (PTHREAD_INCLUDE_DIR "") + endif (WIN32) +else (${WITH_THREADING} STREQUAL ON) + set (PTHREAD_LIBRARIES "") + set (PTHREAD_INCLUDE_DIR "") +endif (${WITH_THREADING} STREQUAL ON) + +include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/lib + ${STDBOOL_H_PATH} ${STDINT_H_PATH} + ${OPENSSL_INCLUDE_DIR} ${PTHREAD_INCLUDE_DIR}) +link_directories(${mosquitto_SOURCE_DIR}/lib) + +add_library(libmosquitto SHARED + logging_mosq.c logging_mosq.h + memory_mosq.c memory_mosq.h + messages_mosq.c messages_mosq.h + mosquitto.c mosquitto.h + mosquitto_internal.h + mqtt3_protocol.h + net_mosq.c net_mosq.h + read_handle.c read_handle.h + read_handle_client.c + read_handle_shared.c + send_client_mosq.c + send_mosq.c send_mosq.h + srv_mosq.c + thread_mosq.c + time_mosq.c + tls_mosq.c + util_mosq.c util_mosq.h + will_mosq.c will_mosq.h) + +set (LIBRARIES ${OPENSSL_LIBRARIES} ${PTHREAD_LIBRARIES}) + +if (UNIX AND NOT APPLE) + set (LIBRARIES ${LIBRARIES} rt) +endif (UNIX AND NOT APPLE) + +if (WIN32) + set (LIBRARIES ${LIBRARIES} ws2_32) +endif (WIN32) + +option(WITH_SRV "Include SRV lookup support?" ON) +if (${WITH_SRV} STREQUAL ON) + set (LIBRARIES ${LIBRARIES} cares) +endif (${WITH_SRV} STREQUAL ON) + +target_link_libraries(libmosquitto ${LIBRARIES}) + +set_target_properties(libmosquitto PROPERTIES + OUTPUT_NAME mosquitto + VERSION ${VERSION} + SOVERSION 1 +) + +install(TARGETS libmosquitto RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR}) +install(FILES mosquitto.h DESTINATION ${INCLUDEDIR}) + +if (UNIX) + install(CODE "EXEC_PROGRAM(/sbin/ldconfig)") +endif (UNIX) diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/Makefile b/service/protocol-plugin/plugins/mqtt-light/lib/Makefile new file mode 100644 index 0000000..64329d3 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/Makefile @@ -0,0 +1,99 @@ +include config.mk + +.PHONY : really clean install + +MOSQ_OBJS=mosquitto.o \ + logging_mosq.o \ + memory_mosq.o \ + messages_mosq.o \ + net_mosq.o \ + read_handle.o \ + read_handle_client.o \ + read_handle_shared.o \ + send_mosq.o \ + send_client_mosq.o \ + srv_mosq.o \ + thread_mosq.o \ + time_mosq.o \ + tls_mosq.o \ + util_mosq.o \ + will_mosq.o + +all : libmosquitto.so.${SOVERSION} libmosquitto.a + $(MAKE) -C cpp + $(MAKE) -C python + +install : all + $(INSTALL) -d ${DESTDIR}$(prefix)/lib${LIB_SUFFIX}/ + $(INSTALL) -s libmosquitto.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so.${SOVERSION} + ln -sf libmosquitto.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so + $(INSTALL) -d ${DESTDIR}${prefix}/include/ + $(INSTALL) mosquitto.h ${DESTDIR}${prefix}/include/mosquitto.h + $(MAKE) -C cpp install + $(MAKE) -C python install + +uninstall : + -rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so.${SOVERSION} + -rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquitto.so + -rm -f ${DESTDIR}${prefix}/include/mosquitto.h + +reallyclean : clean + +clean : + -rm -f *.o libmosquitto.so.${SOVERSION} libmosquitto.so libmosquitto.a + $(MAKE) -C cpp clean + $(MAKE) -C python clean + +libmosquitto.so.${SOVERSION} : ${MOSQ_OBJS} + $(CC) -shared $(LIB_LDFLAGS) $^ -o $@ ${LIB_LIBS} + +libmosquitto.a : ${MOSQ_OBJS} + $(AR) cr $@ $^ +mosquitto.o : mosquitto.c mosquitto.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +logging_mosq.o : logging_mosq.c logging_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +messages_mosq.o : messages_mosq.c messages_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +memory_mosq.o : memory_mosq.c memory_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +net_mosq.o : net_mosq.c net_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +read_handle.o : read_handle.c read_handle.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +read_handle_client.o : read_handle_client.c read_handle.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +read_handle_shared.o : read_handle_shared.c read_handle.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +send_mosq.o : send_mosq.c send_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +send_client_mosq.o : send_client_mosq.c send_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +srv_mosq.o : srv_mosq.c + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +thread_mosq.o : thread_mosq.c + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +time_mosq.o : time_mosq.c + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +tls_mosq.o : tls_mosq.c + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +util_mosq.o : util_mosq.c util_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + +will_mosq.o : will_mosq.c will_mosq.h + $(CC) $(LIB_CFLAGS) -c $< -o $@ + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/config.h b/service/protocol-plugin/plugins/mqtt-light/lib/config.h new file mode 100644 index 0000000..cdc6249 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/config.h @@ -0,0 +1,19 @@ +/* ============================================================ + * Control compile time options. + * ============================================================ + * + * Compile time options have moved to config.mk. + */ + + +/* ============================================================ + * Compatibility defines + * + * Generally for Windows native support. + * ============================================================ */ +#ifdef WIN32 +#define snprintf sprintf_s +#define strcasecmp strcmpi +#define strtok_r strtok_s +#define strerror_r(e, b, l) strerror_s(b, l, e) +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/config.mk b/service/protocol-plugin/plugins/mqtt-light/lib/config.mk new file mode 100644 index 0000000..b199d20 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/config.mk @@ -0,0 +1,218 @@ +# ============================================================================= +# User configuration section. +# +# Largely, these are options that are designed to make mosquitto run more +# easily in restrictive environments by removing features. +# +# Modify the variable below to enable/disable features. +# +# Can also be overriden at the command line, e.g.: +# +# make WITH_TLS=no +# ============================================================================= + +# Uncomment to compile the broker with tcpd/libwrap support. +#WITH_WRAP:=yes + +# Comment out to disable SSL/TLS support in the broker and client. +# Disabling this will also mean that passwords must be stored in plain text. It +# is strongly recommended that you only disable WITH_TLS if you are not using +# password authentication at all. +WITH_TLS:=yes + +# Comment out to disable TLS/PSK support in the broker and client. Requires +# WITH_TLS=yes. +# This must be disabled if using openssl < 1.0. +WITH_TLS_PSK:=yes + +# Comment out to disable client client threading support. +WITH_THREADING:=yes + +# Uncomment to compile the broker with strict protocol support. This means that +# both the client library and the broker will be very strict about protocol +# compliance on incoming data. Neither of them will return an error on +# incorrect "remaining length" values if this is commented out. The old +# behaviour (prior to 0.12) is equivalent to compiling with +# WITH_STRICT_PROTOCOL defined and means that clients will be immediately +# disconnected from the broker on non-compliance. +#WITH_STRICT_PROTOCOL:=yes + +# Comment out to remove bridge support from the broker. This allow the broker +# to connect to other brokers and subscribe/publish to topics. You probably +# want to leave this included unless you want to save a very small amount of +# memory size and CPU time. +WITH_BRIDGE:=yes + +# Comment out to remove persistent database support from the broker. This +# allows the broker to store retained messages and durable subscriptions to a +# file periodically and on shutdown. This is usually desirable (and is +# suggested by the MQTT spec), but it can be disabled if required. +WITH_PERSISTENCE:=yes + +# Comment out to remove memory tracking support from the broker. If disabled, +# mosquitto won't track heap memory usage nor export '$SYS/broker/heap/current +# size', but will use slightly less memory and CPU time. +WITH_MEMORY_TRACKING:=yes + +# Compile with database upgrading support? If disabled, mosquitto won't +# automatically upgrade old database versions. +# Not currently supported. +#WITH_DB_UPGRADE:=yes + +# Comment out to remove publishing of the $SYS topic hierarchy containing +# information about the broker state. +WITH_SYS_TREE:=yes + +# Build with Python module. Comment out if Python is not installed, or required +# Python modules are not available. +WITH_PYTHON:=yes + +# Build with SRV lookup support. +WITH_SRV:=no + +# ============================================================================= +# End of user configuration +# ============================================================================= + + +# Also bump lib/mosquitto.h, lib/python/setup.py, CMakeLists.txt, +# installer/mosquitto.nsi, installer/mosquitto-cygwin.nsi +VERSION=1.3.1 +TIMESTAMP:=$(shell date "+%F %T%z") + +# Client library SO version. Bump if incompatible API/ABI changes are made. +SOVERSION=1 + +# Man page generation requires xsltproc and docbook-xsl +XSLTPROC=xsltproc +# For html generation +DB_HTML_XSL=man/html.xsl + +#MANCOUNTRIES=en_GB + +UNAME:=$(shell uname -s) +ifeq ($(UNAME),SunOS) + ifeq ($(CC),cc) + CFLAGS?=-O + else + CFLAGS?=-Wall -ggdb -O2 + endif +else + CFLAGS?=-Wall -ggdb -O2 +endif + +LIB_CFLAGS:=${CFLAGS} ${CPPFLAGS} -I. -I.. -I./lib +LIB_CXXFLAGS:=$(LIB_CFLAGS) ${CPPFLAGS} +LIB_LDFLAGS:=${LDFLAGS} + +BROKER_CFLAGS:=${LIB_CFLAGS} ${CPPFLAGS} -DVERSION="\"${VERSION}\"" -DTIMESTAMP="\"${TIMESTAMP}\"" -DWITH_BROKER +CLIENT_CFLAGS:=${CFLAGS} ${CPPFLAGS} -I./lib -DVERSION="\"${VERSION}\"" + +ifeq ($(UNAME),FreeBSD) + BROKER_LIBS:=-lm +else + BROKER_LIBS:=-ldl -lm +endif +LIB_LIBS:= +PASSWD_LIBS:= + +ifeq ($(UNAME),Linux) + BROKER_LIBS:=$(BROKER_LIBS) -lrt + LIB_LIBS:=$(LIB_LIBS) -lrt +endif + +CLIENT_LDFLAGS:=$(LDFLAGS) -L./lib ./lib/libmosquitto.so.${SOVERSION} + +ifeq ($(UNAME),SunOS) + ifeq ($(CC),cc) + LIB_CFLAGS:=$(LIB_CFLAGS) -xc99 -KPIC + else + LIB_CFLAGS:=$(LIB_CFLAGS) -fPIC + endif + + ifeq ($(CXX),CC) + LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -KPIC + else + LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -fPIC + endif +else + LIB_CFLAGS:=$(LIB_CFLAGS) -fPIC + LIB_CXXFLAGS:=$(LIB_CXXFLAGS) -fPIC +endif + +ifneq ($(UNAME),SunOS) + LIB_LDFLAGS:=$(LIB_LDFLAGS) -Wl,-soname,libmosquitto.so.$(SOVERSION) +endif + +ifeq ($(UNAME),QNX) + BROKER_LIBS:=$(BROKER_LIBS) -lsocket + LIB_LIBS:=$(LIB_LIBS) -lsocket +endif + +ifeq ($(WITH_WRAP),yes) + BROKER_LIBS:=$(BROKER_LIBS) -lwrap + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_WRAP +endif + +ifeq ($(WITH_TLS),yes) + BROKER_LIBS:=$(BROKER_LIBS) -lssl -lcrypto + LIB_LIBS:=$(LIB_LIBS) -lssl -lcrypto + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_TLS + LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_TLS + PASSWD_LIBS:=-lcrypto + CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -DWITH_TLS + + ifeq ($(WITH_TLS_PSK),yes) + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_TLS_PSK + LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_TLS_PSK + CLIENT_CFLAGS:=$(CLIENT_CFLAGS) -DWITH_TLS_PSK + endif +endif + +ifeq ($(WITH_THREADING),yes) + LIB_LIBS:=$(LIB_LIBS) -lpthread + LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_THREADING +endif + +ifeq ($(WITH_STRICT_PROTOCOL),yes) + LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_STRICT_PROTOCOL + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_STRICT_PROTOCOL +endif + +ifeq ($(WITH_BRIDGE),yes) + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_BRIDGE +endif + +ifeq ($(WITH_PERSISTENCE),yes) + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_PERSISTENCE +endif + +ifeq ($(WITH_MEMORY_TRACKING),yes) + ifneq ($(UNAME),SunOS) + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_MEMORY_TRACKING + endif +endif + +#ifeq ($(WITH_DB_UPGRADE),yes) +# BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_DB_UPGRADE +#endif + +ifeq ($(WITH_SYS_TREE),yes) + BROKER_CFLAGS:=$(BROKER_CFLAGS) -DWITH_SYS_TREE +endif + +ifeq ($(WITH_SRV),yes) + LIB_CFLAGS:=$(LIB_CFLAGS) -DWITH_SRV + LIB_LIBS:=$(LIB_LIBS) -lcares +endif + +ifeq ($(UNAME),SunOS) + BROKER_LIBS:=$(BROKER_LIBS) -lsocket -lnsl + LIB_LIBS:=$(LIB_LIBS) -lsocket -lnsl +endif + + +INSTALL?=install +prefix=/usr/local +mandir=${prefix}/share/man +localedir=${prefix}/share/locale diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/cpp/CMakeLists.txt b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/CMakeLists.txt new file mode 100644 index 0000000..0a9fd91 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/CMakeLists.txt @@ -0,0 +1,18 @@ +include_directories(${mosquitto_SOURCE_DIR}/lib ${mosquitto_SOURCE_DIR}/lib/cpp + ${STDBOOL_H_PATH} ${STDINT_H_PATH}) +link_directories(${mosquitto_BINARY_DIR}/lib) + +add_library(mosquittopp SHARED + mosquittopp.cpp mosquittopp.h) + +target_link_libraries(mosquittopp libmosquitto) +set_target_properties(mosquittopp PROPERTIES + VERSION ${VERSION} + SOVERSION 1 +) +install(TARGETS mosquittopp RUNTIME DESTINATION ${BINDIR} LIBRARY DESTINATION ${LIBDIR}) +install(FILES mosquittopp.h DESTINATION ${INCLUDEDIR}) + +if (UNIX) + install(CODE "EXEC_PROGRAM(/sbin/ldconfig)") +endif (UNIX) diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/cpp/Makefile b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/Makefile new file mode 100644 index 0000000..8e04b6c --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/Makefile @@ -0,0 +1,31 @@ +include ../config.mk + +ifneq ($(UNAME),SunOS) + LIB_LDFLAGS:=$(LDFLAGS) -Wl,-soname,libmosquittopp.so.${SOVERSION} +endif + +.PHONY : clean install + +all : libmosquittopp.so.${SOVERSION} + +install : all + $(INSTALL) -d ${DESTDIR}$(prefix)/lib${LIB_SUFFIX}/ + $(INSTALL) -s libmosquittopp.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so.${SOVERSION} + ln -sf libmosquittopp.so.${SOVERSION} ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so + $(INSTALL) -d ${DESTDIR}${prefix}/include/ + $(INSTALL) mosquittopp.h ${DESTDIR}${prefix}/include/mosquittopp.h + +uninstall : + -rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so.${SOVERSION} + -rm -f ${DESTDIR}${prefix}/lib${LIB_SUFFIX}/libmosquittopp.so + -rm -f ${DESTDIR}${prefix}/include/mosquittopp.h + +clean : + -rm -f *.o libmosquittopp.so.${SOVERSION} + +libmosquittopp.so.${SOVERSION} : mosquittopp.o + $(CXX) -shared $(LIB_LDFLAGS) $< -o $@ ../libmosquitto.so.${SOVERSION} + +mosquittopp.o : mosquittopp.cpp mosquittopp.h + $(CXX) $(LIB_CXXFLAGS) -c $< -o $@ + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.cpp b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.cpp new file mode 100644 index 0000000..fa4e436 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.cpp @@ -0,0 +1,305 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +namespace mosqpp { + +static void on_connect_wrapper(struct mosquitto *mosq, void *userdata, int rc) +{ + class mosquittopp *m = (class mosquittopp *)userdata; + m->on_connect(rc); +} + +static void on_disconnect_wrapper(struct mosquitto *mosq, void *userdata, int rc) +{ + class mosquittopp *m = (class mosquittopp *)userdata; + m->on_disconnect(rc); +} + +static void on_publish_wrapper(struct mosquitto *mosq, void *userdata, int mid) +{ + class mosquittopp *m = (class mosquittopp *)userdata; + m->on_publish(mid); +} + +static void on_message_wrapper(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message) +{ + class mosquittopp *m = (class mosquittopp *)userdata; + m->on_message(message); +} + +static void on_subscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid, int qos_count, const int *granted_qos) +{ + class mosquittopp *m = (class mosquittopp *)userdata; + m->on_subscribe(mid, qos_count, granted_qos); +} + +static void on_unsubscribe_wrapper(struct mosquitto *mosq, void *userdata, int mid) +{ + class mosquittopp *m = (class mosquittopp *)userdata; + m->on_unsubscribe(mid); +} + + +static void on_log_wrapper(struct mosquitto *mosq, void *userdata, int level, const char *str) +{ + class mosquittopp *m = (class mosquittopp *)userdata; + m->on_log(level, str); +} + +int lib_version(int *major, int *minor, int *revision) +{ + if(major) *major = LIBMOSQUITTO_MAJOR; + if(minor) *minor = LIBMOSQUITTO_MINOR; + if(revision) *revision = LIBMOSQUITTO_REVISION; + return LIBMOSQUITTO_VERSION_NUMBER; +} + +int lib_init() +{ + return mosquitto_lib_init(); +} + +int lib_cleanup() +{ + return mosquitto_lib_cleanup(); +} + +const char* strerror(int mosq_errno) +{ + return mosquitto_strerror(mosq_errno); +} + +const char* connack_string(int connack_code) +{ + return mosquitto_connack_string(connack_code); +} + +int sub_topic_tokenise(const char *subtopic, char ***topics, int *count) +{ + return mosquitto_sub_topic_tokenise(subtopic, topics, count); +} + +int sub_topic_tokens_free(char ***topics, int count) +{ + return mosquitto_sub_topic_tokens_free(topics, count); +} + +int topic_matches_sub(const char *sub, const char *topic, bool *result) +{ + return mosquitto_topic_matches_sub(sub, topic, result); +} + +mosquittopp::mosquittopp(const char *id, bool clean_session) +{ + m_mosq = mosquitto_new(id, clean_session, this); + mosquitto_connect_callback_set(m_mosq, on_connect_wrapper); + mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper); + mosquitto_publish_callback_set(m_mosq, on_publish_wrapper); + mosquitto_message_callback_set(m_mosq, on_message_wrapper); + mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper); + mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper); + mosquitto_log_callback_set(m_mosq, on_log_wrapper); +} + +mosquittopp::~mosquittopp() +{ + mosquitto_destroy(m_mosq); +} + +int mosquittopp::reinitialise(const char *id, bool clean_session) +{ + int rc; + rc = mosquitto_reinitialise(m_mosq, id, clean_session, this); + if(rc == MOSQ_ERR_SUCCESS){ + mosquitto_connect_callback_set(m_mosq, on_connect_wrapper); + mosquitto_disconnect_callback_set(m_mosq, on_disconnect_wrapper); + mosquitto_publish_callback_set(m_mosq, on_publish_wrapper); + mosquitto_message_callback_set(m_mosq, on_message_wrapper); + mosquitto_subscribe_callback_set(m_mosq, on_subscribe_wrapper); + mosquitto_unsubscribe_callback_set(m_mosq, on_unsubscribe_wrapper); + mosquitto_log_callback_set(m_mosq, on_log_wrapper); + } + return rc; +} + +int mosquittopp::connect(const char *host, int port, int keepalive) +{ + return mosquitto_connect(m_mosq, host, port, keepalive); +} + +int mosquittopp::connect(const char *host, int port, int keepalive, const char *bind_address) +{ + return mosquitto_connect_bind(m_mosq, host, port, keepalive, bind_address); +} + +int mosquittopp::connect_async(const char *host, int port, int keepalive) +{ + return mosquitto_connect_async(m_mosq, host, port, keepalive); +} + +int mosquittopp::connect_async(const char *host, int port, int keepalive, const char *bind_address) +{ + return mosquitto_connect_bind_async(m_mosq, host, port, keepalive, bind_address); +} + +int mosquittopp::reconnect() +{ + return mosquitto_reconnect(m_mosq); +} + +int mosquittopp::reconnect_async() +{ + return mosquitto_reconnect_async(m_mosq); +} + +int mosquittopp::disconnect() +{ + return mosquitto_disconnect(m_mosq); +} + +int mosquittopp::socket() +{ + return mosquitto_socket(m_mosq); +} + +int mosquittopp::will_set(const char *topic, int payloadlen, const void *payload, int qos, bool retain) +{ + return mosquitto_will_set(m_mosq, topic, payloadlen, payload, qos, retain); +} + +int mosquittopp::will_clear() +{ + return mosquitto_will_clear(m_mosq); +} + +int mosquittopp::username_pw_set(const char *username, const char *password) +{ + return mosquitto_username_pw_set(m_mosq, username, password); +} + +int mosquittopp::publish(int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain) +{ + return mosquitto_publish(m_mosq, mid, topic, payloadlen, payload, qos, retain); +} + +void mosquittopp::reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff) +{ + mosquitto_reconnect_delay_set(m_mosq, reconnect_delay, reconnect_delay_max, reconnect_exponential_backoff); +} + +int mosquittopp::max_inflight_messages_set(unsigned int max_inflight_messages) +{ + return mosquitto_max_inflight_messages_set(m_mosq, max_inflight_messages); +} + +void mosquittopp::message_retry_set(unsigned int message_retry) +{ + mosquitto_message_retry_set(m_mosq, message_retry); +} + +int mosquittopp::subscribe(int *mid, const char *sub, int qos) +{ + return mosquitto_subscribe(m_mosq, mid, sub, qos); +} + +int mosquittopp::unsubscribe(int *mid, const char *sub) +{ + return mosquitto_unsubscribe(m_mosq, mid, sub); +} + +int mosquittopp::loop(int timeout, int max_packets) +{ + return mosquitto_loop(m_mosq, timeout, max_packets); +} + +int mosquittopp::loop_misc() +{ + return mosquitto_loop_misc(m_mosq); +} + +int mosquittopp::loop_read(int max_packets) +{ + return mosquitto_loop_read(m_mosq, max_packets); +} + +int mosquittopp::loop_write(int max_packets) +{ + return mosquitto_loop_write(m_mosq, max_packets); +} + +int mosquittopp::loop_forever(int timeout, int max_packets) +{ + return mosquitto_loop_forever(m_mosq, timeout, max_packets); +} + +int mosquittopp::loop_start() +{ + return mosquitto_loop_start(m_mosq); +} + +int mosquittopp::loop_stop(bool force) +{ + return mosquitto_loop_stop(m_mosq, force); +} + +bool mosquittopp::want_write() +{ + return mosquitto_want_write(m_mosq); +} + +void mosquittopp::user_data_set(void *userdata) +{ + mosquitto_user_data_set(m_mosq, userdata); +} + +int mosquittopp::tls_set(const char *cafile, const char *capath, const char *certfile, const char *keyfile, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)) +{ + return mosquitto_tls_set(m_mosq, cafile, capath, certfile, keyfile, pw_callback); +} + +int mosquittopp::tls_opts_set(int cert_reqs, const char *tls_version, const char *ciphers) +{ + return mosquitto_tls_opts_set(m_mosq, cert_reqs, tls_version, ciphers); +} + +int mosquittopp::tls_insecure_set(bool value) +{ + return mosquitto_tls_insecure_set(m_mosq, value); +} + +int mosquittopp::tls_psk_set(const char *psk, const char *identity, const char *ciphers) +{ + return mosquitto_tls_psk_set(m_mosq, psk, identity, ciphers); +} + +} diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.h b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.h new file mode 100644 index 0000000..41537b6 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/mosquittopp.h @@ -0,0 +1,122 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit. (http://www.openssl.org/) +This product includes cryptographic software written by Eric Young +(eay@cryptsoft.com) +This product includes software written by Tim Hudson (tjh@cryptsoft.com) +*/ + +#ifndef _MOSQUITTOPP_H_ +#define _MOSQUITTOPP_H_ + +#ifdef _WIN32 +# ifdef mosquittopp_EXPORTS +# define mosqpp_EXPORT __declspec(dllexport) +# else +# define mosqpp_EXPORT __declspec(dllimport) +# endif +#else +# define mosqpp_EXPORT +#endif + +#include +#include +#include "../mosquitto.h" + +namespace mosqpp { + +mosqpp_EXPORT const char *strerror(int mosq_errno); +mosqpp_EXPORT const char *connack_string(int connack_code); +mosqpp_EXPORT int sub_topic_tokenise(const char *subtopic, char ***topics, int *count); +mosqpp_EXPORT int sub_topic_tokens_free(char ***topics, int count); +mosqpp_EXPORT int lib_version(int *major, int *minor, int *revision); +mosqpp_EXPORT int lib_init(); +mosqpp_EXPORT int lib_cleanup(); +mosqpp_EXPORT int topic_matches_sub(const char *sub, const char *topic, bool *result); + +/* + * Class: mosquittopp + * + * A mosquitto client class. This is a C++ wrapper class for the mosquitto C + * library. Please see mosquitto.h for details of the functions. + */ +class mosqpp_EXPORT mosquittopp { + private: + struct mosquitto *m_mosq; + public: + mosquittopp(const char *id=NULL, bool clean_session=true); + ~mosquittopp(); + + int reinitialise(const char *id, bool clean_session); + int socket(); + int will_set(const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int will_clear(); + int username_pw_set(const char *username, const char *password=NULL); + int connect(const char *host, int port=1883, int keepalive=60); + int connect_async(const char *host, int port=1883, int keepalive=60); + int connect(const char *host, int port, int keepalive, const char *bind_address); + int connect_async(const char *host, int port, int keepalive, const char *bind_address); + int reconnect(); + int reconnect_async(); + int disconnect(); + int publish(int *mid, const char *topic, int payloadlen=0, const void *payload=NULL, int qos=0, bool retain=false); + int subscribe(int *mid, const char *sub, int qos=0); + int unsubscribe(int *mid, const char *sub); + void reconnect_delay_set(unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + int max_inflight_messages_set(unsigned int max_inflight_messages); + void message_retry_set(unsigned int message_retry); + void user_data_set(void *userdata); + int tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); + int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); + int tls_insecure_set(bool value); + int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); + + int loop(int timeout=-1, int max_packets=1); + int loop_misc(); + int loop_read(int max_packets=1); + int loop_write(int max_packets=1); + int loop_forever(int timeout=-1, int max_packets=1); + int loop_start(); + int loop_stop(bool force=false); + bool want_write(); + + virtual void on_connect(int rc) {return;}; + virtual void on_disconnect(int rc) {return;}; + virtual void on_publish(int mid) {return;}; + virtual void on_message(const struct mosquitto_message *message) {return;}; + virtual void on_subscribe(int mid, int qos_count, const int *granted_qos) {return;}; + virtual void on_unsubscribe(int mid) {return;}; + virtual void on_log(int level, const char *str) {return;}; + virtual void on_error() {return;}; +}; + +} +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/cpp/test.txt b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/test.txt new file mode 100644 index 0000000..c6ba667 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/cpp/test.txt @@ -0,0 +1,883 @@ +/usr/lib/i386-linux-gnu/mesa-egl: + libOpenVG.so.1 -> libOpenVG.so.1.0.0 + libwayland-egl.so.1 -> libwayland-egl.so.1.0.0 + libEGL.so.1 -> libEGL.so.1.0.0 +/usr/lib/i386-linux-gnu/mesa: + libGL.so.1 -> libGL.so.1.2.0 +/lib/i386-linux-gnu: + libblkid.so.1 -> libblkid.so.1.1.0 + libnss_dns.so.2 -> libnss_dns-2.15.so + libnss_compat.so.2 -> libnss_compat-2.15.so + libwrap.so.0 -> libwrap.so.0.7.6 + libpcsclite.so.1 -> libpcsclite.so.1.0.0 + libkeyutils.so.1 -> libkeyutils.so.1.4 + libntfs-3g.so.831 -> libntfs-3g.so.831.0.0 + libpcprofile.so -> libpcprofile.so + libext2fs.so.2 -> libext2fs.so.2.4 + libslang.so.2 -> libslang.so.2.2.4 + libpci.so.3 -> libpci.so.3.1.8 + libparted.so.0 -> libparted.so.0.0.1 + libdl.so.2 -> libdl-2.15.so + libutil.so.1 -> libutil-2.15.so + libgcc_s.so.1 -> libgcc_s.so.1 + libnss_nisplus.so.2 -> libnss_nisplus-2.15.so + libbsd.so.0 -> libbsd.so.0.3.0 + libpng12.so.0 -> libpng12.so.0.46.0 + librt.so.1 -> librt-2.15.so + ld-linux.so.2 -> ld-2.15.so + libncurses.so.5 -> libncurses.so.5.9 + libcrypto.so.1.0.0 -> libcrypto.so.1.0.0 + libacl.so.1 -> libacl.so.1.1.0 + libgcrypt.so.11 -> libgcrypt.so.11.7.0 + libnsl.so.1 -> libnsl-2.15.so + libpam.so.0 -> libpam.so.0.83.0 + libmount.so.1 -> libmount.so.1.1.0 + libselinux.so.1 -> libselinux.so.1 + libpcre.so.3 -> libpcre.so.3.12.1 + libdbus-1.so.3 -> libdbus-1.so.3.5.8 + libuuid.so.1 -> libuuid.so.1.3.0 + libexpat.so.1 -> libexpat.so.1.5.2 + libnss_files.so.2 -> libnss_files-2.15.so + libcom_err.so.2 -> libcom_err.so.2.1 + libnss_nis.so.2 -> libnss_nis-2.15.so + libatasmart.so.4 -> libatasmart.so.4.0.4 + libssl.so.1.0.0 -> libssl.so.1.0.0 + libthread_db.so.1 -> libthread_db-1.0.so + libncursesw.so.5 -> libncursesw.so.5.9 + libgpg-error.so.0 -> libgpg-error.so.0.8.0 + libe2p.so.2 -> libe2p.so.2.3 + libss.so.2 -> libss.so.2.0 + libBrokenLocale.so.1 -> libBrokenLocale-2.15.so + libcidn.so.1 -> libcidn-2.15.so + libpamc.so.0 -> libpamc.so.0.82.1 + libmemusage.so -> libmemusage.so + libglib-2.0.so.0 -> libglib-2.0.so.0.3200.4 + libnss_hesiod.so.2 -> libnss_hesiod-2.15.so + libanl.so.1 -> libanl-2.15.so + libcap.so.2 -> libcap.so.2.22 + libresolv.so.2 -> libresolv-2.15.so + libattr.so.1 -> libattr.so.1.1.0 + libpthread.so.0 -> libpthread-2.15.so + libm.so.6 -> libm-2.15.so + libz.so.1 -> libz.so.1.2.3.4 + libhistory.so.6 -> libhistory.so.6.2 + libnih-dbus.so.1 -> libnih-dbus.so.1.0.0 + libSegFault.so -> libSegFault.so + libudev.so.0 -> libudev.so.0.13.0 + libreadline.so.6 -> libreadline.so.6.2 + libusb-1.0.so.0 -> libusb-1.0.so.0.1.0 + libcrypt.so.1 -> libcrypt-2.15.so + libpam_misc.so.0 -> libpam_misc.so.0.82.0 + libnih.so.1 -> libnih.so.1.0.0 + libtinfo.so.5 -> libtinfo.so.5.9 + libpopt.so.0 -> libpopt.so.0.0.0 + libbz2.so.1.0 -> libbz2.so.1.0.4 + libc.so.6 -> libc-2.15.so + libusb-0.1.so.4 -> libusb-0.1.so.4.4.4 +/usr/lib/i386-linux-gnu: + libnss3.so -> libnss3.so + libsmbclient.so.0 -> libsmbclient.so.0 + libgobject-2.0.so.0 -> libgobject-2.0.so.0.3200.4 + libpoppler-glib.so.8 -> libpoppler-glib.so.8.2.0 + libavcodec.so.53 -> libavcodec.so.53.35.0 + libwbclient.so.0 -> libwbclient.so.0 + libbonoboui-2.so.0 -> libbonoboui-2.so.0.0.0 + libjasper.so.1 -> libjasper.so.1.0.0 + libsqlite3.so.0 -> libsqlite3.so.0.8.6 + libgstbasevideo-1.0.so.0 -> libgstbasevideo-1.0.so.0.5.0 + librtmp.so.0 -> librtmp.so.0 + libframe.so.6 -> libframe.so.6.0.0 + libnspr4.so -> libnspr4.so + libportaudio.so.2 -> libportaudio.so.2.0.0 + libXdmcp.so.6 -> libXdmcp.so.6.0.0 + libcanberra-gtk3.so.0 -> libcanberra-gtk3.so.0.1.8 + libnettle.so.4 -> libnettle.so.4.3 + libcups.so.2 -> libcups.so.2 + libxcb-shape.so.0 -> libxcb-shape.so.0.0.0 + libunistring.so.0 -> libunistring.so.0.1.2 + libQtDeclarative.so.4 -> libQtDeclarative.so.4.8.1 + libdbusmenu-gtk3.so.4 -> libdbusmenu-gtk3.so.4.0.13 + libgsttag-0.10.so.0 -> libgsttag-0.10.so.0.25.0 + libwmflite-0.2.so.7 -> libwmflite-0.2.so.7.0.1 + libapt-pkg.so.4.12 -> libapt-pkg.so.4.12.0 + libQtNetwork.so.4 -> libQtNetwork.so.4.8.1 + libgnomecanvas-2.so.0 -> libgnomecanvas-2.so.0.3000.3 + libtheoradec.so.1 -> libtheoradec.so.1.1.4 + libcanberra.so.0 -> libcanberra.so.0.2.5 + libgnutls-extra.so.26 -> libgnutls-extra.so.26.21.8 + libxcb-render.so.0 -> libxcb-render.so.0.0.0 + libgpm.so.2 -> libgpm.so.2 + libxcb-util.so.0 -> libxcb-util.so.0.0.0 + libraw1394.so.11 -> libraw1394.so.11.0.1 + libpangocairo-1.0.so.0 -> libpangocairo-1.0.so.0.3000.0 + libssl3.so -> libssl3.so + libgstcontroller-0.10.so.0 -> libgstcontroller-0.10.so.0.30.0 + libcupsimage.so.2 -> libcupsimage.so.2 + liblcms2.so.2 -> liblcms2.so.2.0.2 + libgio-2.0.so.0 -> libgio-2.0.so.0.3200.4 + libtxc_dxtn_s2tc.so.0 -> libtxc_dxtn_s2tc.so.0.0.0 + libdbus-glib-1.so.2 -> libdbus-glib-1.so.2.2.2 + libgstallocators-1.0.so.0 -> libgstallocators-1.0.so.0.201.0 + libXi.so.6 -> libXi.so.6.1.0 + libsvn_ra_svn-1.so.1 -> libsvn_ra_svn-1.so.1.0.0 + liblber-2.4.so.2 -> liblber.so + libgstsignalprocessor-1.0.so.0 -> libgstsignalprocessor-1.0.so.0.5.0 + libhcrypto.so.4 -> libhcrypto.so.4.1.0 + libcanberra-gtk.so.0 -> libcanberra-gtk.so.0.1.8 + libavahi-glib.so.1 -> libavahi-glib.so.1.0.2 + libedit.so.2 -> libedit.so.2.11 + libavahi-ui-gtk3.so.0 -> libavahi-ui-gtk3.so.0.1.4 + libx264.so.120 -> libx264.so.120 + libgstsdp-1.0.so.0 -> libgstsdp-1.0.so.0.201.0 + libgstnet-0.10.so.0 -> libgstnet-0.10.so.0.30.0 + libfarstream-0.1.so.0 -> libfarstream-0.1.so.0.0.1 + libgstfft-0.10.so.0 -> libgstfft-0.10.so.0.25.0 + libgstcdda-0.10.so.0 -> libgstcdda-0.10.so.0.25.0 + libbamf3.so.0 -> libbamf3.so.0.0.0 + libgstbasecamerabinsrc-1.0.so.0 -> libgstbasecamerabinsrc-1.0.so.0.7.0 + libexempi.so.3 -> libexempi.so.3.2.2 + libXss.so.1 -> libXss.so.1.0.0 + libffi.so.6 -> libffi.so.6.0.0 + libavformat.so.53 -> libavformat.so.53.21.1 + libgstpbutils-0.10.so.0 -> libgstpbutils-0.10.so.0.25.0 + libcdda_paranoia.so.0 -> libcdda_paranoia.so.0.10.2 + libavahi-gobject.so.0 -> libavahi-gobject.so.0.0.4 + libpolkit-gobject-1.so.0 -> libpolkit-gobject-1.so.0.0.0 + libXfixes.so.3 -> libXfixes.so.3.1.0 + libp11-kit.so.0 -> libp11-kit.so.0.0.0 + libpng12.so.0 -> libpng.so + libswscale.so.2 -> libswscale.so.2.1.0 + libxkbfile.so.1 -> libxkbfile.so.1.0.2 + libcupscgi.so.1 -> libcupscgi.so.1 + libtic.so.5 -> libtic.so.5.9 + libSDL-1.2.so.0 -> libSDL-1.2.so.0.11.3 + libgettextpo.so.0 -> libgettextpo.so.0.5.1 + libgoa-1.0.so.0 -> libgoa-1.0.so.0.0.0 + libvisual-0.4.so.0 -> libvisual-0.4.so.0.0.0 + libQtXml.so.4 -> libQtXml.so.4.8.1 + libdrm_intel.so.1 -> libdrm_intel.so.1.0.0 + libltdl.so.7 -> libltdl.so.7.3.0 + libgomp.so.1 -> libgomp.so.1.0.0 + libXtst.so.6 -> libXtst.so.6.1.0 + libgtk-3.so.0 -> libgtk-3.so.0.400.2 + libogg.so.0 -> libogg.so.0.7.1 + libXaw.so.7 -> libXaw7.so.7.0.0 + libssh.so.4 -> libssh.so.4.2.2 + libtdb.so.1 -> libtdb.so.1.2.9 + libsvn_ra-1.so.1 -> libsvn_ra-1.so.1.0.0 + libiec61883.so.0 -> libiec61883.so.0.1.1 + libk5crypto.so.3 -> libk5crypto.so.3.1 + libXinerama.so.1 -> libXinerama.so.1.0.0 + libcupsfilters.so.1 -> libcupsfilters.so.1 + libfontconfig.so.1 -> libfontconfig.so.1.4.4 + libXrandr_ltss.so.2 -> libXrandr_ltss.so.2.2.0 + libcupsdriver.so.1 -> libcupsdriver.so.1 + libgstcontroller-1.0.so.0 -> libgstcontroller-1.0.so.0.201.0 + libgnutlsxx.so.27 -> libgnutlsxx.so.27.0.0 + libICE.so.6 -> libICE.so.6.3.0 + libQtGui.so.4 -> libQtGui.so.4.8.1 + libgssrpc.so.4 -> libgssrpc.so.4.1 + librsvg-2.so.2 -> librsvg-2.so.2.36.1 + libgdk-x11-2.0.so.0 -> libgdk-x11-2.0.so.0.2400.10 + libsvn_subr-1.so.1 -> libsvn_subr-1.so.1.0.0 + libgphoto2.so.2 -> libgphoto2.so.2.4.0 + libtiff.so.4 -> libtiff.so.4.3.4 + libv4l1.so.0 -> libv4l1.so.0 + libgstsdp-0.10.so.0 -> libgstsdp-0.10.so.0.25.0 + libORBitCosNaming-2.so.0 -> libORBitCosNaming-2.so.0.1.0 + libdatrie.so.1 -> libdatrie.so.1.1.0 + libplc4.so -> libplc4.so + libwacom.so.2 -> libwacom.so.2.0.0 + libsoup-gnome-2.4.so.1 -> libsoup-gnome-2.4.so.1.5.0 + libwayland_ltss-server.so.0 -> libwayland_ltss-server.so.0.0.0 + libgstpbutils-1.0.so.0 -> libgstpbutils-1.0.so.0.201.0 + libpangoxft-1.0.so.0 -> libpangoxft-1.0.so.0.3000.0 + libglibmm-2.4.so.1 -> libglibmm-2.4.so.1.3.0 + libpulse.so.0 -> libpulse.so.0.13.5 + libbonobo-activation.so.4 -> libbonobo-activation.so.4.0.0 + libpolkit-agent-1.so.0 -> libpolkit-agent-1.so.0.0.0 + libtag.so.1 -> libtag.so.1.7.0 + libGLEWmx.so.1.6 -> libGLEWmx.so.1.6.0 + libatspi.so.0 -> libatspi.so.0.0.1 + libgphoto2_port.so.0 -> libgphoto2_port.so.0.8.0 + libcurl-gnutls.so.4 -> libcurl.so + libgbm.so.1 -> libgbm.so.1.0.0 + libgstapp-0.10.so.0 -> libgstapp-0.10.so.0.25.0 + libsndfile.so.1 -> libsndfile.so.1.0.25 + libgmodule-2.0.so.0 -> libgmodule-2.0.so.0.3200.4 + libXmu.so.6 -> libXmu.so.6.2.0 + libaudiofile.so.1 -> libaudiofile.so.1.0.0 + libexif.so.12 -> libexif.so.12.3.2 + libXau.so.6 -> libXau.so.6.0.0 + libglapi.so.0 -> libglapi.so.0.0.0 + libgtksourceview-3.0.so.0 -> libgtksourceview-3.0.so.0.0.0 + liborc-0.4.so.0 -> liborc-0.4.so.0.18.0 + libnotify.so.4 -> libnotify.so.4.0.0 + libwind.so.0 -> libwind.so.0.0.0 + libldap_r-2.4.so.2 -> libldap_r.so + libpcrecpp.so.0 -> libpcrecpp.so.0.0.0 + libgstinterfaces-0.10.so.0 -> libgstinterfaces-0.10.so.0.25.0 + libelf.so.1 -> libelf-0.152.so + libdrm_nouveau.so.1 -> libdrm_nouveau1.so + libthai.so.0 -> libthai.so.0.1.6 + libgstnet-1.0.so.0 -> libgstnet-1.0.so.0.201.0 + libcares.so.2 -> libcares.so.2.0.0 + liborc-test-0.4.so.0 -> liborc-test-0.4.so.0.18.0 + libaa.so.1 -> libaa.so.1.0.4 + libsvn_ra_local-1.so.1 -> libsvn_ra_local-1.so.1.0.0 + libdrm.so.2 -> libdrm.so.2.4.0 + libLLVM-3.3.so.1 -> libLLVM-3.3.so.1 + libpcap.so.0.8 -> libpcap.so.1.1.1 + libcupsmime.so.1 -> libcupsmime.so.1 + libxcb.so.1 -> libxcb.so.1.1.0 + libSM.so.6 -> libSM.so.6.0.1 + libkms.so.1 -> libkms.so.1.0.0 + libdbusmenu-gtk.so.4 -> libdbusmenu-gtk.so.4.0.13 + libFLAC.so.8 -> libFLAC.so.8.2.0 + libxcb-xfixes.so.0 -> libxcb-xfixes.so.0.0.0 + libgstriff-1.0.so.0 -> libgstriff-1.0.so.0.201.0 + libidn.so.11 -> libidn.so.11.6.6 + libIDL-2.so.0 -> libIDL-2.so.0.0.0 + libdbusmenu-qt.so.2 -> libdbusmenu-qt.so.2.6.0 + libQtScript.so.4 -> libQtScript.so.4.8.1 + libcairo-gobject.so.2 -> libcairo-gobject.so.2.11000.2 + libluajit-5.1.so.2 -> libluajit-5.1.so.2.0.0 + libpangomm-1.4.so.1 -> libpangomm-1.4.so.1.0.30 + libXpm.so.4 -> libXpm.so.4.11.0 + libsvn_diff-1.so.1 -> libsvn_diff-1.so.1.0.0 + libdbusmenu-glib.so.4 -> libdbusmenu-glib.so.4.0.13 + liblua5.1.so.0 -> liblua5.1.so.0.0.0 + libbonobo-2.so.0 -> libbonobo-2.so.0.0.0 + libpulse-mainloop-glib.so.0 -> libpulse-mainloop-glib.so.0.0.4 + libexslt.so.0 -> libexslt.so.0.8.15 + libmp3lame.so.0 -> libmp3lame.so.0.0.0 + libpcreposix.so.3 -> libpcreposix.so.3.12.1 + libquvi.so.7 -> libquvi.so.7.0.0 + libaudio.so.2 -> libaudio.so.2.4 + libpulse-simple.so.0 -> libpulse-simple.so.0.0.3 + liboauth.so.0 -> liboauth.so.0.8.1 + libQtCore.so.4 -> libQtCore.so.4.8.1 + libwayland_ltss-client.so.0 -> libwayland_ltss-client.so.0.1.0 + libQtDBus.so.4 -> libQtDBus.so.4.8.1 + libtheoraenc.so.1 -> libtheoraenc.so.1.1.2 + libatkmm-1.6.so.1 -> libatkmm-1.6.so.1.1.0 + libgailutil-3.so.0 -> libgailutil-3.so.0.0.0 + libgsttag-1.0.so.0 -> libgsttag-1.0.so.0.201.0 + libgdk_pixbuf_xlib-2.0.so.0 -> libgdk_pixbuf_xlib-2.0.so.0.2600.1 + libkrb5.so.3 -> libkrb5.so.3.3 + libgnome-2.so.0 -> libgnome-2.so.0.3200.1 + libgallium.so.0 -> libgallium.so.0.0.0 + libXcomposite.so.1 -> libXcomposite.so.1.0.0 + libsvn_fs-1.so.1 -> libsvn_fs-1.so.1.0.0 + libgstreamer-0.10.so.0 -> libgstreamer-0.10.so.0.30.0 + libXrender.so.1 -> libXrender.so.1.3.0 + libmng.so.1 -> libmng.so.1.1.0.10 + libgdu.so.0 -> libgdu.so.0.0.0 + libxatracker.so.1 -> libxatracker.so.1.0.0 + librom1394.so.0 -> librom1394.so.0.3.0 + liblua5.1-c++.so.0 -> liblua5.1-c++.so.0.0.0 + libplds4.so -> libplds4.so + libbamf.so.0 -> libbamf.so.0.0.0 + libheimntlm.so.0 -> libheimntlm.so.0.1.0 + libarchive.so.12 -> libarchive.so.12.0.3 + libmad.so.0 -> libmad.so.0.2.1 + libgthread-2.0.so.0 -> libgthread-2.0.so.0.3200.4 + libgstaudio-1.0.so.0 -> libgstaudio-1.0.so.0.201.0 + libgudev-1.0.so.0 -> libgudev-1.0.so.0.1.1 + libvpx.so.1 -> libvpx.so.1.2.0 + libgailutil.so.18 -> libgailutil.so.18.0.1 + libsvn_client-1.so.1 -> libsvn_client-1.so.1.0.0 + libdricore9.2.1.so.1 -> libdricore9.2.1.so.1.0.0 + libQtOpenGL.so.4 -> libQtOpenGL.so.4.8.1 + libhunspell-1.3.so.0 -> libhunspell-1.3.so.0.0.0 + libcupsppdc.so.1 -> libcupsppdc.so.1 + libkdb5.so.6 -> libkdb5.so.6.0 + libpixman-1.so.0 -> libpixman-1.so.0.30.2 + libpolkit-backend-1.so.0 -> libpolkit-backend-1.so.0.0.0 + libibus-1.0.so.0 -> libibus-1.0.so.0.401.0 + libxcb-dri2.so.0 -> libxcb-dri2.so.0.0.0 + libgstcheck-0.10.so.0 -> libgstcheck-0.10.so.0.30.0 + libXp.so.6 -> libXp.so.6.2.0 + libart_lgpl_2.so.2 -> libart_lgpl_2.so.2.3.21 + libhx509.so.5 -> libhx509.so.5.0.0 + libform.so.5 -> libform.so.5.9 + libgstbase-1.0.so.0 -> libgstbase-1.0.so.0.201.0 + libX11-xcb.so.1 -> libX11-xcb.so.1.0.0 + libgstaudio-0.10.so.0 -> libgstaudio-0.10.so.0.25.0 + libjson-glib-1.0.so.0 -> libjson-glib-1.0.so.0.1400.2 + libspeex.so.1 -> libspeex.so.1.5.0 + libsvn_fs_util-1.so.1 -> libsvn_fs_util-1.so.1.0.0 + libpoppler.so.19 -> libpoppler.so.19.0.0 + libdconf.so.0 -> libdconf.so.0.0.0 + libavahi-common.so.3 -> libavahi-common.so.3.5.3 + libyajl.so.1 -> libyajl.so.1.0.12 + libvorbis.so.0 -> libvorbis.so.0.4.5 + libavc1394.so.0 -> libavc1394.so.0.3.0 + libv4l2.so.0 -> libv4l2.so.0 + libcolord.so.1 -> libcolord.so.1.0.8 + libcairo.so.2 -> libcairo.so.2.11000.2 + libGLEW.so.1.6 -> libGLEW.so.1.6.0 + libgdbm_compat.so.3 -> libgdbm_compat.so.3.0.0 + libdb-5.1.so -> libdb-5.1.so + libXt.so.6 -> libXt.so.6.0.0 + libwavpack.so.1 -> libwavpack.so.1.1.4 + libmpfr.so.4 -> libmpfr.so.4.1.0 + libpangoft2-1.0.so.0 -> libpangoft2-1.0.so.0.3000.0 + libieee1284.so.3 -> libieee1284.so.3.2.2 + libfreetype.so.6 -> libfreetype.so.6.8.0 + libdrm_nouveau.so.2 -> libdrm_nouveau.so.2.0.0 + libgssapi.so.3 -> libgssapi.so.3.0.0 + libspeexdsp.so.1 -> libspeexdsp.so.1.5.0 + libdconf-dbus-1.so.0 -> libdconf-dbus-1.so.0.0.0 + libgmp.so.10 -> libgmp.so.10.0.2 + libcaca.so.0 -> libcucul.so.0.99.17 + libcairomm-1.0.so.1 -> libcairomm-1.0.so.1.4.0 + libsvn_repos-1.so.1 -> libsvn_repos-1.so.1.0.0 + libgupnp-igd-1.0.so.4 -> libgupnp-igd-1.0.so.4.1.0 + libgstvideo-1.0.so.0 -> libgstvideo-1.0.so.0.201.0 + libXdamage.so.1 -> libXdamage.so.1.1.0 + libasn1.so.8 -> libasn1.so.8.0.0 + libsvn_fs_base-1.so.1 -> libsvn_fs_base-1.so.1.0.0 + libvorbisenc.so.2 -> libvorbisenc.so.2.0.8 + libgstapp-1.0.so.0 -> libgstapp-1.0.so.0.201.0 + libvo-amrwbenc.so.0 -> libvo-amrwbenc.so.0.0.2 + libtalloc.so.2 -> libtalloc.so.2.0.7 + libshout.so.3 -> libshout.so.3.2.0 + libnice.so.10 -> libnice.so.10.0.1 + libbluetooth.so.3 -> libbluetooth.so.3.11.5 + libgrail.so.5 -> libgrail.so.5.0.0 + libgutenprint.so.3 -> libgutenprint.so.3.0.0 + libmenuw.so.5 -> libmenuw.so.5.9 + libpanelw.so.5 -> libpanelw.so.5.9 + libkrb5.so.26 -> libkrb5.so.26.0.0 + libgdu-gtk.so.0 -> libgdu-gtk.so.0.0.0 + libgdbm.so.3 -> libgdbm.so.3.0.0 + libgnutls-openssl.so.27 -> libgnutls-openssl.so.27.0.0 + libmenu.so.5 -> libmenu.so.5.9 + libpangox-1.0.so.0 -> libpangox-1.0.so.0.3000.0 + libXft.so.2 -> libXft.so.2.2.0 + libsensors.so.4 -> libsensors.so.4.3.1 + libgstphotography-0.10.so.0 -> libgstphotography-0.10.so.0.0.0 + libstartup-notification-1.so.0 -> libstartup-notification-1.so.0.0.0 + libatk-1.0.so.0 -> libatk-1.0.so.0.20409.1 + libsvn_auth_gnome_keyring-1.so.1 -> libsvn_auth_gnome_keyring-1.so.1.0.0 + libquadmath.so.0 -> libquadmath.so.0.0.0 + libgif.so.4 -> libungif.so.4.1.6 + libstdc++.so.6 -> libstdc++.so.6.0.16 + liblzma.so.5 -> liblzma.so.5.0.0 + libass.so.4 -> libass.so.4.1.0 + libproxy.so.1 -> libproxy.so.1.0.0 + libcaca++.so.0 -> libcucul++.so.0.99.17 + libglade-2.0.so.0 -> libglade-2.0.so.0.0.7 + libavutil.so.51 -> libavutil.so.51.22.2 + libxslt.so.1 -> libxslt.so.1.1.26 + libva.so.1 -> libva.so.1.3200.0 + libsmime3.so -> libsmime3.so + libdv.so.4 -> libdv.so.4.0.3 + libavahi-client.so.3 -> libavahi-client.so.3.2.9 + libsvn_fs_fs-1.so.1 -> libsvn_fs_fs-1.so.1.0.0 + libgiomm-2.4.so.1 -> libgiomm-2.4.so.1.3.0 + libgstrtp-1.0.so.0 -> libgstrtp-1.0.so.0.201.0 + libgnutls.so.26 -> libgnutls.so.26.21.8 + libQtXmlPatterns.so.4 -> libQtXmlPatterns.so.4.8.1 + libao.so.4 -> libao.so.4.0.0 + libpulsecommon-1.1.so -> libpulsecommon-1.1.so + libQtCLucene.so.4 -> libQtCLucene.so.4.8.1 + libgstbase-0.10.so.0 -> libgstbase-0.10.so.0.30.0 + libsvn_auth_kwallet-1.so.1 -> libsvn_auth_kwallet-1.so.1.0.0 + libjpeg.so.8 -> libjpeg.so.8.0.2 + libsamplerate.so.0 -> libsamplerate.so.0.1.8 + libcurl.so.4 -> libcurl.so.4.2.0 + libpipeline.so.1 -> libpipeline.so.1.2.1 + libglamor_ltss.so.0 -> libglamor_ltss.so.0.0.0 + libpciaccess.so.0 -> libpciaccess.so.0.11.0 + libnssutil3.so -> libnssutil3.so + libgstriff-0.10.so.0 -> libgstriff-0.10.so.0.25.0 + libXcursor.so.1 -> libXcursor.so.1.0.2 + libformw.so.5 -> libformw.so.5.9 + libjson.so.0 -> libjson.so.0.0.1 + libgconf-2.so.4 -> libgconf-2.so.4.1.5 + libkrb5support.so.0 -> libkrb5support.so.0.1 + libwmf-0.2.so.7 -> libwmf-0.2.so.7.1.0 + libdiscid.so.0 -> libdiscid.so.0.2.1 + libjacknet.so.0 -> libjacknet.so.0.1.0 + libgstbasecamerabinsrc-0.10.so.0 -> libgstbasecamerabinsrc-0.10.so.0.0.0 + libgee.so.2 -> libgee.so.2.0.0 + libavahi-core.so.7 -> libavahi-core.so.7.0.2 + liblcms.so.1 -> liblcms.so.1.0.19 + liblockfile.so.1 -> liblockfile.so.1.0 + libdb-4.8.so -> libdb-4.8.so + libxcb-glx.so.0 -> libxcb-glx.so.0.0.0 + libtiffxx.so.0 -> libtiffxx.so.0.0.8 + libasyncns.so.0 -> libasyncns.so.0.3.1 + libcdda_interface.so.0 -> libcdda_interface.so.0.10.2 + libgstrtsp-0.10.so.0 -> libgstrtsp-0.10.so.0.25.0 + libtheora.so.0 -> libtheora.so.0.3.10 + libvo-aacenc.so.0 -> libvo-aacenc.so.0.0.2 + libORBit-2.so.0 -> libORBit-2.so.0.1.0 + libv4lconvert.so.0 -> libv4lconvert.so.0 + libXv.so.1 -> libXv.so.1.0.0 + libgnomeui-2.so.0 -> libgnomeui-2.so.0.2400.5 + libsvn_wc-1.so.1 -> libsvn_wc-1.so.1.0.0 + libgstphotography-1.0.so.0 -> libgstphotography-1.0.so.0.7.0 + libasound.so.2 -> libasound.so.2.0.0 + libsvn_ra_neon-1.so.1 -> libsvn_ra_neon-1.so.1.0.0 + libcroco-0.6.so.3 -> libcroco-0.6.so.3.0.1 + libopus.so.0 -> libopus.so.0.5.0 + libXext.so.6 -> libXext.so.6.4.0 + libXrandr.so.2 -> libXrandr.so.2.2.0 + libQtSql.so.4 -> libQtSql.so.4.8.1 + libsonic.so.0 -> libsonic.so.0.1.17 + libapt-inst.so.1.4 -> libapt-inst.so.1.4.0 + libgstvideo-0.10.so.0 -> libgstvideo-0.10.so.0.25.0 + libpanel.so.5 -> libpanel.so.5.9 + libSoundTouch.so.0 -> libSoundTouch.so.0.0.0 + libgd.so.2 -> libgd.so.2.0.0 + libXxf86vm.so.1 -> libXxf86vm.so.1.0.0 + libpulsedsp.so -> libpulsedsp.so + libGLU.so.1 -> libGLU.so.1.3.08004 + libmpc.so.2 -> libmpc.so.2.0.0 + libgdk_pixbuf-2.0.so.0 -> libgdk_pixbuf-2.0.so.0.2600.1 + libroken.so.18 -> libroken.so.18.1.0 + libtasn1.so.3 -> libtasn1.so.3.1.12 + libsvn_delta-1.so.1 -> libsvn_delta-1.so.1.0.0 + libgstrtp-0.10.so.0 -> libgstrtp-0.10.so.0.25.0 + libgstnetbuffer-0.10.so.0 -> libgstnetbuffer-0.10.so.0.25.0 + libgstfft-1.0.so.0 -> libgstfft-1.0.so.0.201.0 + libORBit-imodule-2.so.0 -> libORBit-imodule-2.so.0.0.0 + libkadm5srv_mit.so.8 -> libkadm5srv_mit.so.8.0 + libgssapi_krb5.so.2 -> libgssapi_krb5.so.2.2 + libdrm_radeon.so.1 -> libdrm_radeon.so.1.0.1 + libgoa-backend-1.0.so.0 -> libgoa-backend-1.0.so.0.0.0 + libXmuu.so.1 -> libXmuu.so.1.0.0 + libpango-1.0.so.0 -> libpango-1.0.so.0.3000.0 + libsigc-2.0.so.0 -> libsigc-2.0.so.0.0.0 + libsoup-2.4.so.1 -> libsoup-2.4.so.1.5.0 + libssh_threads.so.4 -> libssh_threads.so.4.2.2 + libkadm5clnt_mit.so.8 -> libkadm5clnt_mit.so.8.0 + libgstcodecparsers-1.0.so.0 -> libgstcodecparsers-1.0.so.0.5.0 + libgstrtsp-1.0.so.0 -> libgstrtsp-1.0.so.0.201.0 + libgtk-x11-2.0.so.0 -> libgtk-x11-2.0.so.0.2400.10 + libespeak.so.1 -> libespeak.so.1.1.46 + libjack.so.0 -> libjack.so.0.1.0 + libxcb-shm.so.0 -> libxcb-shm.so.0.0.0 + libQtSvg.so.4 -> libQtSvg.so.4.8.1 + libglibmm_generate_extra_defs-2.4.so.1 -> libglibmm_generate_extra_defs-2.4.so.1.3.0 + libcurl-nss.so.4 -> libcurl-nss.so.4.2.0 + libtelepathy-logger.so.2 -> libtelepathy-logger.so.2.2.1 + libX11.so.6 -> libX11.so.6.3.0 + libexpatw.so.1 -> libexpatw.so.1.5.2 + libxml2.so.2 -> libxml2.so.2.7.8 + libsane.so.1 -> libsane.so.1.0.22 + libgeis.so.1 -> libgeis.so.1.3.0 + libgnome-keyring.so.0 -> libgnome-keyring.so.0.2.0 + libgdk-3.so.0 -> libgdk-3.so.0.400.2 + libgstreamer-1.0.so.0 -> libgstreamer-1.0.so.0.201.0 + libgstcheck-1.0.so.0 -> libgstcheck-1.0.so.0.201.0 + libheimbase.so.1 -> libheimbase.so.1.0.0 + libsasl2.so.2 -> libsasl2.so.2.0.25 + liblouis.so.2 -> liblouis.so.2.2.3 + libgnomevfs-2.so.0 -> libgnomevfs-2.so.0.2400.4 + libgstdataprotocol-0.10.so.0 -> libgstdataprotocol-0.10.so.0.30.0 + libvorbisfile.so.3 -> libvorbisfile.so.3.3.4 +/usr/local/lib: + libefreet.so.1 -> libefreet.so.1.9.3 + libecore_ipc.so.1 -> libecore_ipc.so.1.9.3 + libefreet_trash.so.1 -> libefreet_trash.so.1.9.3 + libecore_evas.so.1 -> libecore_evas.so.1.9.3 + libecore.so.1 -> libecore.so.1.9.3 + libmosquittopp.so.1 -> libmosquittopp.so.1 + libeina.so.1 -> libeina.so.1.9.3 + libeet.so.1 -> libeet.so.1.9.3 + libecore_imf_evas.so.1 -> libecore_imf_evas.so.1.9.3 + libembryo.so.1 -> libembryo.so.1.9.3 + libecore_avahi.so.1 -> libecore_avahi.so.1.9.3 + libeldbus.so.1 -> libeldbus.so.1.9.3 + libethumb.so.1 -> libethumb.so.1.9.3 + libemotion.so.1 -> libemotion.so.1.9.3 + libecore_con.so.1 -> libecore_con.so.1.9.3 + libecore_imf.so.1 -> libecore_imf.so.1.9.3 + libeeze.so.1 -> libeeze.so.1.9.3 + libecore_input.so.1 -> libecore_input.so.1.9.3 + libedje.so.1 -> libedje.so.1.9.3 + libeo.so.1 -> libeo.so.1.9.3 + libethumb_client.so.1 -> libethumb_client.so.1.9.3 + libecore_file.so.1 -> libecore_file.so.1.9.3 + libeio.so.1 -> libeio.so.1.9.3 + libmosquitto.so.1 -> libmosquitto.so.1 + libelementary.so.1 -> libelementary.so.1.9.3 + libecore_audio.so.1 -> libecore_audio.so.1.9.3 + libevas.so.1 -> libevas.so.1.9.3 + libecore_input_evas.so.1 -> libecore_input_evas.so.1.9.3 + libefreet_mime.so.1 -> libefreet_mime.so.1.9.3 + libecore_x.so.1 -> libecore_x.so.1.9.3 +/lib: + libnl-genl-3.so.200 -> libnl-genl-3.so.200.3.0 + libnss_mdns6_minimal.so.2 -> libnss_mdns6_minimal.so.2 + libip6tc.so.0 -> libip6tc.so.0.0.0 + libply.so.2 -> libply.so.2.0.0 + libnss_mdns6.so.2 -> libnss_mdns6.so.2 + libipq_pic.so.0 -> libipq_pic.so.0.0.0 + liblvm2app.so.2.2 -> liblvm2app.so.2.2 + libdevmapper.so.1.02.1 -> libdevmapper.so.1.02.1 + libcryptsetup.so.4 -> libcryptsetup.so.4.0.0 + libnss_mdns.so.2 -> libnss_mdns.so.2 + libnss_mdns_minimal.so.2 -> libnss_mdns_minimal.so.2 + libfuse.so.2 -> libfuse.so.2.8.6 + libiw.so.30 -> libiw.so.30 + libdevmapper-event.so.1.02.1 -> libdevmapper-event.so.1.02.1 + libply-splash-graphics.so.2 -> libply-splash-graphics.so.2.0.0 + libply-splash-core.so.2 -> libply-splash-core.so.2.0.0 + libsysfs.so.2 -> libsysfs.so.2.0.1 + libply-boot-client.so.2 -> libply-boot-client.so.2.0.0 + libnss_mdns4.so.2 -> libnss_mdns4.so.2 + libnss_mdns4_minimal.so.2 -> libnss_mdns4_minimal.so.2 + libproc-3.2.8.so -> libproc-3.2.8.so + libbrlapi.so.0.5 -> libbrlapi.so.0.5.6 + libnewt.so.0.52 -> libnewt.so.0.52.11 + libipq.so.0 -> libipq.so.0.0.0 + libiptc.so.0 -> libiptc.so.0.0.0 + libulockmgr.so.1 -> libulockmgr.so.1.0.1 + libnl-3.so.200 -> libnl-3.so.200.3.0 + libxtables.so.7 -> libxtables.so.7.0.0 + libip4tc.so.0 -> libip4tc.so.0.0.0 + libx86.so.1 -> libx86.so.1 +/usr/lib: + liba52-0.7.4.so -> liba52-0.7.4.so + libvncserver.so.0 -> libvncserver.so.0.0.0 + libspandsp.so.2 -> libspandsp.so.2.0.0 + libflite_usenglish.so.1 -> libflite_usenglish.so.1.4 + libido3-0.1.so.0 -> libido3-0.1.so.0.0.0 + libicui18n.so.48 -> libicui18n.so.48.1.1 + libXvMC.so.1 -> libXvMC.so.1.0.0 + libdmapsharing-3.0.so.2 -> libdmapsharing-3.0.so.2.9.14 + libgmime-2.6.so.0 -> libgmime-2.6.so.0.600.7 + libefreet_trash.so.1 -> libefreet_trash.so.1.0.0 + libQtGConf.so.1 -> libQtGConf.so.1.0.0 + libbfd-2.22-system.so -> libbfd-2.22-system.so + libgs.so.9 -> libgs.so.9.05 + libedbus.so.1 -> libedbus.so.1.0.0 + libperl.so.5.14 -> libperl.so.5.14.2 + libgdkmm-3.0.so.1 -> libgdkmm-3.0.so.1.1.0 + libeconnman.so.1 -> libeconnman.so.1.0.0 + libxklavier.so.16 -> libxklavier.so.16.2.0 + libnux-2.0.so.0 -> libnux-2.0.so.0.1401.0 + libvlccore.so.5 -> libvlccore.so.5.1.1 + libopcodes-2.22-system.so -> libopcodes-2.22-system.so + libaccountsservice.so.0 -> libaccountsservice.so.0.0.0 + libnm-util.so.2 -> libnm-util.so.2.3.0 + libjavascriptcoregtk-1.0.so.0 -> libjavascriptcoregtk-1.0.so.0.13.4 + libpulsecore-1.1.so -> libpulsecore-1.1.so + libflite_cmu_us_slt.so.1 -> libflite_cmu_us_slt.so.1.4 + libkeybinder.so.0 -> libkeybinder.so.0.0.1 + libguile-srfi-srfi-1-v-3.so.3 -> libguile-srfi-srfi-1-v-3.so.3.0.2 + libindicator-messages-status-provider.so.1 -> libindicator-messages-status-provider.so.1.0.0 + libopencore-amrwb.so.0 -> libopencore-amrwb.so.0.0.2 + libfolks.so.25 -> libfolks.so.25.7.0 + libisccc.so.80 -> libisccc.so.80.0.0 + libutempter.so.0 -> libutempter.so.1.1.5 + libijs-0.35.so -> libijs-0.35.so + libefreet.so.1 -> libefreet.so.1.0.0 + libflite_cmu_us_awb.so.1 -> libflite_cmu_us_awb.so.1.4 + libwpg-0.2.so.2 -> libwpg-0.2.so.2.0.1 + libvte2_90.so.9 -> libvte2_90.so.9.3200.1 + libvncclient.so.0 -> libvncclient.so.0.0.0 + libtcl8.5.so.0 -> libtcl8.5.so.0 + libgnome-control-center.so.1 -> libgnome-control-center.so.1.0.0 + libpyglib-gi-2.0-python2.7.so.0 -> libpyglib-gi-2.0-python2.7.so.0.0.0 + libisc.so.83 -> libisc.so.83.0.1 + libenotify.so.1 -> libenotify.so.1.0.0 + libwps-0.2.so.2 -> libwps-0.2.so.2.0.4 + libschroedinger-1.0.so.0 -> libschroedinger-1.0.so.0.11.0 + libgtkmm-3.0.so.1 -> libgtkmm-3.0.so.1.1.0 + librest-0.7.so.0 -> librest-0.7.so.0.0.0 + libicalss.so.0 -> libicalss.so.0.48.0 + libgrip.so.0 -> libgrip.so.0.305.0 + libtimezonemap.so.1 -> libtimezonemap.so.1.0.0 + libecore_evas.so.1 -> libecore_evas.so.1.0.0 + libvte.so.9 -> libvte.so.9.2800.2 + libmetacity-private.so.0 -> libmetacity-private.so.0.0.0 + libXxf86dga.so.1 -> libXxf86dga.so.1.0.0 + libgck-1.so.0 -> libgck-1.so.0.0.0 + libicutu.so.48 -> libicutu.so.48.1.1 + libedje.so.1 -> libedje.so.1.0.0 + libgwibber-gtk.so.2 -> libgwibber-gtk.so.2.0.0 + libpurple-client.so.0 -> libpurple-client.so.0.10.3 + libhpip.so.0 -> libhpip.so.0.0.1 + libwnck-1.so.22 -> libwnck-1.so.22.3.31 + libfreerdp-core.so.1.0 -> libfreerdp-core.so.1.0.1 + libmhash.so.2 -> libmhash.so.2.0.1 + libindicator3.so.7 -> libindicator3.so.7.0.0 + libfreerdp-codec.so.1.0 -> libfreerdp-codec.so.1.0.1 + libflite.so.1 -> libflite.so.1.4 + libgweather-3.so.0 -> libgweather-3.so.0.0.6 + libpeas-1.0.so.0 -> libpeas-1.0.so.0.200.0 + libbind9.so.80 -> libbind9.so.80.0.3 + libgnomekbd.so.7 -> libgnomekbd.so.7.0.0 + libcrypto.so.1.0.0 -> libcrypto.so.1.0.0 + libwnck-3.so.0 -> libwnck-3.so.0.2.0 + libeina.so.1 -> libeina.so.1.0.0 + libebook-1.2.so.12 -> libebook-1.2.so.12.3.1 + libFS.so.6 -> libFS.so.6.0.0 + libnetsnmpagent.so.15 -> libnetsnmpagent.so.15.1.2 + libdaemon.so.0 -> libdaemon.so.0.5.0 + libfribidi.so.0 -> libfribidi.so.0.3.1 + libeet.so.1 -> libeet.so.1.4.0 + libunity-misc.so.4 -> libunity-misc.so.4.1.0 + libbulletml.so.0d2 -> libbulletml.so.0d2.0 + libebluez.so.1 -> libebluez.so.1.0.0 + libindicate.so.5 -> libindicate.so.5.0.7 + libicule.so.48 -> libicule.so.48.1.1 + libmtdev.so.1 -> libmtdev.so.1.0.0 + libgnome-media-profiles-3.0.so.0 -> libgnome-media-profiles-3.0.so.0.0.0 + libnetsnmpmibs.so.15 -> libnetsnmpmibs.so.15.1.2 + liboverlay-scrollbar-0.2.so.0 -> liboverlay-scrollbar-0.2.so.0.0.16 + libecore_imf_evas.so.1 -> libecore_imf_evas.so.1.0.0 + libpaper.so.1 -> libpaper.so.1.1.2 + libjte.so.1 -> libjte.so.1.0.0 + libdotconf-1.0.so.0 -> libdotconf-1.0.so.0.10.4 + libicutest.so.48 -> libicutest.so.48.1.1 + libmimic.so.0 -> libmimic.so.0.0.1 + libeukit.so.1 -> libeukit.so.1.0.0 + libtotem-plparser.so.17 -> libtotem-plparser.so.17.0.3 + libfolks-telepathy.so.25 -> libfolks-telepathy.so.25.7.0 + libgtop-2.0.so.7 -> libgtop-2.0.so.7.2.0 + libtwolame.so.0 -> libtwolame.so.0.0.0 + libgwibber.so.2 -> libgwibber.so.2.0.0 + libfreerdp-utils.so.1.0 -> libfreerdp-utils.so.1.0.1 + libgnome-menu.so.2 -> libgnome-menu.so.2.4.13 + libecore_file.so.1 -> libecore_file.so.1.0.0 + libedataserver-1.2.so.15 -> libedataserver-1.2.so.15.0.0 + librasqal.so.3 -> librasqal.so.3.0.0 + libgexiv2.so.1 -> libgexiv2.so.1.0.0 + libgettextlib-0.18.1.so -> libgettextlib.so + libmythes-1.2.so.0 -> libmythes-1.2.so.0.0.0 + libprotoc.so.7 -> libprotoc.so.7.0.0 + libfreerdp-rail.so.1.0 -> libfreerdp-rail.so.1.0.1 + libsgutils2.so.2 -> libsgutils2.so.2.0.0 + libaprutil-1.so.0 -> libaprutil-1.so.0.3.12 + libraptor2.so.0 -> libraptor2.so.0.0.0 + libgirepository-1.0.so.1 -> libgirepository-1.0.so.1.0.0 + libunity-core-5.0.so.5 -> libunity-core-5.0.so.5.0.0 + libflite_cmu_us_kal16.so.1 -> libflite_cmu_us_kal16.so.1.4 + libecore_con.so.1 -> libecore_con.so.1.0.0 + libecore_input_evas.so.1 -> libecore_input_evas.so.1.0.0 + libjbig2dec.so.0 -> libjbig2dec.so.0.0.0 + libnetsnmp.so.15 -> libnetsnmp.so.15.1.2 + libzbar.so.0 -> libzbar.so.0.2.0 + libXRes.so.1 -> libXRes.so.1.0.0 + libcdio_paranoia.so.1 -> libcdio_paranoia.so.1.0.0 + libedata-book-1.2.so.11 -> libedata-book-1.2.so.11.0.0 + libnetsnmphelpers.so.15 -> libnetsnmphelpers.so.15.1.2 + libgksu2.so.0 -> libgksu2.so.0.0.2 + libQtBamf.so.1 -> libQtBamf.so.1.0.0 + libnautilus-extension.so.1 -> libnautilus-extension.so.1.4.0 + libebackend-1.2.so.1 -> libebackend-1.2.so.1.0.0 + libI810XvMC.so.1 -> libI810XvMC.so.1.0.0 + libembryo.so.1 -> libembryo.so.1.0.0 + libmission-control-plugins.so.0 -> libmission-control-plugins.so.0.3.1 + libguilereadline-v-17.so.17 -> libguilereadline-v-17.so.17.0.3 + libsox.so.1 -> libsox.so.1.0.0 + libcdio.so.13 -> libcdio.so.13.0.0 + libsqlite.so.0 -> libsqlite.so.0.8.6 + libecore_imf.so.1 -> libecore_imf.so.1.0.0 + libevdocument3.so.4 -> libevdocument3.so.4.0.0 + libehal.so.1 -> libehal.so.1.0.0 + libt1.so.5 -> libt1.so.5.1.2 + libdconf-qt.so.0 -> libdconf-qt.so.0.0.0 + libboost_wserialization.so.1.46.1 -> libboost_wserialization.so.1.46.1 + libaspell.so.15 -> libaspell.so.15.2.0 + libusbmuxd.so.1 -> libusbmuxd.so.1.0.7 + libevent-2.0.so.5 -> libevent-2.0.so.5.1.4 + libdee-1.0.so.4 -> libdee-1.0.so.4.1.1 + libimobiledevice.so.2 -> libimobiledevice.so.2.0.1 + libtotem.so.0 -> libtotem.so.0.0.0 + libopencore-amrnb.so.0 -> libopencore-amrnb.so.0.0.2 + libgtkspell-3.so.0 -> libgtkspell-3.so.0.0.0 + libsyncdaemon-1.0.so.1 -> libsyncdaemon-1.0.so.1.0.0 + libid3tag.so.0 -> libid3tag.so.0.3.0 + libxcb-keysyms.so.1 -> libxcb-keysyms.so.1.0.0 + liblwres.so.80 -> liblwres.so.80.0.1 + libgnome-menu-3.so.0 -> libgnome-menu-3.so.0.0.1 + libgpgme-pthread.so.11 -> libgpgme-pthread.so.11.7.0 + libXvMCW.so.1 -> libXvMCW.so.1.0.0 + libenchant.so.1 -> libenchant.so.1.6.0 + libgupnp-1.0.so.4 -> libgupnp-1.0.so.4.0.0 + liblightdm-gobject-1.so.0 -> liblightdm-gobject-1.so.0.0.0 + libasprintf.so.0 -> libasprintf.so.0.0.0 + libprotobuf.so.7 -> libprotobuf.so.7.0.0 + libwebkitgtk-1.0.so.0 -> libwebkitgtk-1.0.so.0.13.4 + libmpeg2.so.0 -> libmpeg2.so.0.0.0 + libssl.so.1.0.0 -> libssl.so.1.0.0 + libfreerdp-gdi.so.1.0 -> libfreerdp-gdi.so.1.0.1 + libgpgme.so.11 -> libgpgme.so.11.7.0 + libplist.so.1 -> libplist.so.1.1.8 + libmtp.so.9 -> libmtp.so.9.0.3 + libecore_x.so.1 -> libecore_x.so.1.0.0 + libcap-ng.so.0 -> libcap-ng.so.0.0.0 + libnux-core-2.0.so.0 -> libnux-core-2.0.so.0.1401.0 + libpyglib-2.0-python2.7.so.0 -> libpyglib-2.0-python2.7.so.0.0.0 + libsidplay.so.1 -> libsidplay.so.1.0.3 + libXfont.so.1 -> libXfont.so.1.4.1 + libical.so.0 -> libical.so.0.48.0 + libdvdnav.so.4 -> libdvdnav.so.4.2.0 + libfreerdp-cache.so.1.0 -> libfreerdp-cache.so.1.0.1 + libexttextcat.so.0 -> libexttextcat.so.0.0.0 + libboost_serialization.so.1.46.1 -> libboost_serialization.so.1.46.1 + libmagic.so.1 -> libmagic.so.1.0.0 + libcamel-provider-1.2.so.29 -> libcamel-provider-1.2.so.29.0.0 + libedata-cal-1.2.so.13 -> libedata-cal-1.2.so.13.0.0 + libxcb-image.so.0 -> libxcb-image.so.0.0.0 + librpmbuild.so.2 -> librpmbuild.so.2.0.1 + libzeitgeist-1.0.so.1 -> libzeitgeist-1.0.so.1.1.4 + libmpeg2convert.so.0 -> libmpeg2convert.so.0.0.0 + libecore.so.1 -> libecore.so.1.0.0 + libwpd-0.9.so.9 -> libwpd-0.9.so.9.0.4 + libmms.so.0 -> libmms.so.0.0.2 + libstlport_gcc.so.4.6 -> libstlport_gcc.so.4.6 + libopencc.so.1 -> libopencc.so.1.0.0 + libck-connector.so.0 -> libck-connector.so.0.0.0 + libcdio_cdda.so.1 -> libcdio_cdda.so.1.0.0 + librdf.so.0 -> librdf.so.0.0.0 + libtelepathy-glib.so.0 -> libtelepathy-glib.so.0.70.2 + libGeoIPUpdate.so.0 -> libGeoIPUpdate.so.0.0.0 + libraw_r.so.5 -> libraw_r.so.5.0.0 + libwebkitgtk-3.0.so.0 -> libwebkitgtk-3.0.so.0.13.4 + libbrasero-utils3.so.1 -> libbrasero-utils3.so.1.2.3 + libgcr-3.so.1 -> libgcr-3.so.1.0.0 + libdca.so.0 -> libdca.so.0.0.0 + libcompizconfig.so.0 -> libcompizconfig.so.0.0.0 + librpmsign.so.0 -> librpmsign.so.0.0.1 + libburn.so.4 -> libburn.so.4.71.0 + libzephyr.so.4 -> libzephyr.so.4.0.0 + libcamel-1.2.so.29 -> libcamel-1.2.so.29.0.0 + libmodplug.so.1 -> libmodplug.so.1.0.0 + liblrdf.so.0 -> liblrdf.so.0.0.0 + libflite_cmu_us_kal.so.1 -> libflite_cmu_us_kal.so.1.4 + libjavascriptcoregtk-3.0.so.0 -> libjavascriptcoregtk-3.0.so.0.13.4 + libiculx.so.48 -> libiculx.so.48.1.1 + libgdata.so.13 -> libgdata.so.13.2.0 + libedataserverui-3.0.so.1 -> libedataserverui-3.0.so.1.0.0 + libecore_ipc.so.1 -> libecore_ipc.so.1.0.0 + libindicate-gtk.so.3 -> libindicate-gtk.so.3.0.3 + libexiv2.so.11 -> libexiv2.so.11.0.0 + libyelp.so.0 -> libyelp.so.0.0.0 + libxapian.so.22 -> libxapian.so.22.4.2 + libnm-glib.so.4 -> libnm-glib.so.4.3.0 + libflite_cmu_time_awb.so.1 -> libflite_cmu_time_awb.so.1.4 + libhpmud.so.0 -> libhpmud.so.0.0.6 + librarian.so.0 -> librarian.so.0.0.0 + libnetsnmptrapd.so.15 -> libnetsnmptrapd.so.15.1.2 + libGeoIP.so.1 -> libGeoIP.so.1.4.8 + libgettextsrc-0.18.1.so -> libgettextsrc.so + libpackagekit-glib2.so.14 -> libpackagekit-glib2.so.14.0.11 + libecore_fb.so.1 -> libecore_fb.so.1.0.0 + libgnome-bluetooth.so.8 -> libgnome-bluetooth.so.8.0.0 + libminiupnpc.so.8 -> libminiupnpc.so.8 + libguile-srfi-srfi-13-14-v-3.so.3 -> libguile-srfi-srfi-13-14-v-3.so.3.0.1 + libraw.so.5 -> libraw.so.5.0.0 + librhythmbox-core.so.5 -> librhythmbox-core.so.5.0.0 + libxdelta.so.2 -> libxdelta.so.2.0.0 + libgeoclue.so.0 -> libgeoclue.so.0.0.0 + libfreerdp-channels.so.1.0 -> libfreerdp-channels.so.1.0.1 + libgsm.so.1 -> libgsm.so.1.0.12 + libgme.so.0 -> libgme.so.0.5.3 + librpmio.so.2 -> librpmio.so.2.0.1 + libnetfilter_conntrack.so.3 -> libnetfilter_conntrack.so.3.1.3 + libappindicator3.so.1 -> libappindicator3.so.1.0.0 + libicudata.so.48 -> libicudata.so.48.1.1 + libnl-route-3.so.200 -> libnl-route-3.so.200.3.0 + libicuuc.so.48 -> libicuuc.so.48.1.1 + libIntelXvMC.so.1 -> libIntelXvMC.so.1.0.0 + libraptor.so.1 -> libraptor.so.1.2.0 + libgedit-private.so.0 -> libgedit-private.so.0.0.0 + libindicator.so.7 -> libindicator.so.7.0.0 + libsnmp.so.15 -> libsnmp.so.15.1.2 + libguile.so.17 -> libguile.so.17.4.0 + libcompiz_core.so.ABI-20120305 -> libcompiz_core.so.0.9.7.12 + libunique-3.0.so.0 -> libunique-3.0.so.0.0.2 + libfaad.so.2 -> libfaad.so.2.0.0 + libneon-gnutls.so.27 -> libneon-gnutls.so.27.2.6 + libpython2.7.so.1.0 -> libpython2.7.so.1.0 + libspeechd.so.2 -> libspeechd.so.2.3.0 + libecal-1.2.so.10 -> libecal-1.2.so.10.2.2 + libwpd-stream-0.9.so.9 -> libwpd-stream-0.9.so.9.0.4 + liboverlay-scrollbar3-0.2.so.0 -> liboverlay-scrollbar3-0.2.so.0.0.16 + libunity.so.9 -> libunity.so.9.0.2 + libhyphen.so.0 -> libhyphen.so.0.2.1 + libbrasero-media3.so.1 -> libbrasero-media3.so.1.2.3 + libelementary-ver-pre-svn-09.so.0 -> libelementary.so + libkpathsea.so.5 -> libkpathsea.so.5.0.0 + libvlc.so.5 -> libvlc.so.5.3.2 + libflite_cmulex.so.1 -> libflite_cmulex.so.1.4 + libopenobex.so.1 -> libopenobex.so.1.5.0 + libdns.so.81 -> libdns.so.81.3.1 + libfreerdp-kbd.so.1.0 -> libfreerdp-kbd.so.1.0.1 + libpspell.so.15 -> libpspell.so.15.2.0 + libfolks-eds.so.25 -> libfolks-eds.so.25.7.0 + libisofs.so.6 -> libisofs.so.6.54.0 + libecore_input.so.1 -> libecore_input.so.1.0.0 + libpurple.so.0 -> libpurple.so.0.10.3 + librsync.so.1 -> librsync.so.1.0.2 + librpm.so.2 -> librpm.so.2.0.1 + libmeanwhile.so.1 -> libmeanwhile.so.1.0.2 + libevas.so.1 -> libevas.so.1.0.0 + libapr-1.so.0 -> libapr-1.so.0.4.6 + liblirc_client.so.0 -> liblirc_client.so.0.2.1 + libexpect.so.5.45 -> libexpect.so.5.45 + libgucharmap_2_90.so.7 -> libgucharmap_2_90.so.7.0.0 + libicuio.so.48 -> libicuio.so.48.1.1 + libgpod.so.4 -> libgpod.so.4.3.2 + libfontenc.so.1 -> libfontenc.so.1.0.0 + libchromeXvMC.so.1 -> libchromeXvMC.so.1.0.0 + libgssdp-1.0.so.3 -> libgssdp-1.0.so.3.0.0 + libguile-srfi-srfi-4-v-3.so.3 -> libguile-srfi-srfi-4-v-3.so.3.0.1 + libflite_cmu_us_rms.so.1 -> libflite_cmu_us_rms.so.1.4 + liblaunchpad-integration-3.0.so.1 -> liblaunchpad-integration-3.0.so.1.0.0 + libdjvulibre.so.21 -> libdjvulibre.so.21.3.0 + libdecoration.so.0 -> libdecoration.so.0.0.0 + libnm-gtk.so.0 -> libnm-gtk.so.0.0.0 + libcmis-0.2.so.0 -> libcmis-0.2.so.0.0.0 + libgpgme-pth.so.11 -> libgpgme-pth.so.11.7.0 + libguile-srfi-srfi-60-v-2.so.2 -> libguile-srfi-srfi-60-v-2.so.2.0.2 + libgnome-desktop-3.so.2 -> libgnome-desktop-3.so.2.1.4 + libnfnetlink.so.0 -> libnfnetlink.so.0.2.0 + libpeas-gtk-1.0.so.0 -> libpeas-gtk-1.0.so.0.200.0 + libevview3.so.3 -> libevview3.so.3.0.0 + libappindicator.so.1 -> libappindicator.so.1.0.0 + libisccfg.so.82 -> libisccfg.so.82.0.0 + libt1x.so.5 -> libt1x.so.5.1.2 + libtotem-plparser-mini.so.17 -> libtotem-plparser-mini.so.17.0.3 + libgnomekbdui.so.7 -> libgnomekbdui.so.7.0.0 + libspectre.so.1 -> libspectre.so.1.1.6 + libnm-glib-vpn.so.1 -> libnm-glib-vpn.so.1.1.0 + libdvdread.so.4 -> libdvdread.so.4.2.0 + libQtDee.so.2 -> libQtDee.so.2.0.0 + libnux-graphics-2.0.so.0 -> libnux-graphics-2.0.so.0.1401.0 + libslp.so.1 -> libslp.so.1.0.1 + libdvdnavmini.so.4 -> libdvdnavmini.so.4.2.0 + libnux-image-2.0.so.0 -> libnux-image-2.0.so.0.1401.0 + libunity-2d-private.so.0 -> libunity-2d-private.so.0.0.0 + libtelepathy-farstream.so.2 -> libtelepathy-farstream.so.2.0.1 + libedsio.so.0 -> libedsio.so.0.0.0 + libmusicbrainz3.so.6 -> libmusicbrainz3.so.6.2.0 + libefreet_mime.so.1 -> libefreet_mime.so.1.0.0 + libenca.so.0 -> libenca.so.0.5.1 + libpth.so.20 -> libpth.so.20.0.27 + libchromeXvMCPro.so.1 -> libchromeXvMCPro.so.1.0.0 + libicalvcal.so.0 -> libicalvcal.so.0.48.0 + libbrasero-burn3.so.1 -> libbrasero-burn3.so.1.2.3 + libupower-glib.so.1 -> libupower-glib.so.1.0.1 +/usr/lib/i386-linux-gnu/sse2: (hwcap: 0x0000000004000000) + libspeex.so.1 -> libspeex.so.1.5.0 + libspeexdsp.so.1 -> libspeexdsp.so.1.5.0 +/usr/lib/i386-linux-gnu/i686: (hwcap: 0x0008000000000000) +/usr/lib/sse2: (hwcap: 0x0000000004000000) + libxapian.so.22 -> libxapian.so.22.4.2 +/usr/lib/i386-linux-gnu/i686/sse2: (hwcap: 0x0008000004000000) + libx264.so.120 -> libx264.so.120 +/usr/lib/i386-linux-gnu/i686/cmov: (hwcap: 0x0008000000008000) + libavcodec.so.53 -> libavcodec.so.53.35.0 + libavformat.so.53 -> libavformat.so.53.21.1 + libswscale.so.2 -> libswscale.so.2.1.0 + libavutil.so.51 -> libavutil.so.51.22.2 diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/dummypthread.h b/service/protocol-plugin/plugins/mqtt-light/lib/dummypthread.h new file mode 100644 index 0000000..31f3251 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/dummypthread.h @@ -0,0 +1,13 @@ +#ifndef _DUMMYPTHREAD_H_ +#define _DUMMYPTHREAD_H_ + +#define pthread_create(A, B, C, D) +#define pthread_join(A, B) +#define pthread_cancel(A) + +#define pthread_mutex_init(A, B) +#define pthread_mutex_destroy(A) +#define pthread_mutex_lock(A) +#define pthread_mutex_unlock(A) + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/jsws/mosquitto.js b/service/protocol-plugin/plugins/mqtt-light/lib/jsws/mosquitto.js new file mode 100644 index 0000000..1eb4fc8 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/jsws/mosquitto.js @@ -0,0 +1,363 @@ +/* +Copyright (c) 2012 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Mosquitto MQTT Javascript/Websocket client */ +/* Provides complete support for QoS 0. + * Will not cause an error on QoS 1/2 packets. + */ + +var CONNECT = 0x10; +var CONNACK = 0x20; +var PUBLISH = 0x30; +var PUBACK = 0x40; +var PUBREC = 0x50; +var PUBREL = 0x60; +var PUBCOMP = 0x70; +var SUBSCRIBE = 0x80; +var SUBACK = 0x90; +var UNSUBSCRIBE = 0xA0; +var UNSUBACK = 0xB0; +var PINGREQ = 0xC0; +var PINGRESP = 0xD0; +var DISCONNECT = 0xE0; + +function AB2S(buffer) { + var binary = ''; + var bytes = new Uint8Array(buffer); + var len = bytes.byteLength; + for(var i=0; i 0){ + this.send(this.m.out_queue.pop()); + } + setTimeout(function(_this){_this.mqtt_ping();}, 60000, this.m); + }, + + ws_onclose : function(evt) { + if(this.m.ondisconnect){ + this.m.ondisconnect(evt.data); + } + }, + + ws_onmessage : function(evt) { + var i8V = new Int8Array(evt.data); + buffer = evt.data; + var q=0; + while(i8V.length > 0 && q < 1000){ + q++; + switch(i8V[0] & 0xF0){ + case CONNACK: + var rl = i8V[1]; + var rc = i8V[2]; + if(this.m.onconnect){ + this.m.onconnect(rc); + } + buffer = buffer.slice(rl+2); + i8V = new Int8Array(buffer); + break; + case PUBLISH: + var i=1; + var mult = 1; + var rl = 0; + var count = 0; + var digit; + var qos = (i8V[0] & 0x06) >> 1; + var retain = (i8V[0] & 0x01); + var mid = 0; + do{ + count++; + digit = i8V[i++]; + rl += (digit & 127)*mult; + mult *= 128; + }while((digit & 128) != 0); + + var topiclen = i8V[i++]*256 + i8V[i++]; + var atopic = buffer.slice(i, i+topiclen); + i+=topiclen; + var topic = AB2S(atopic); + if(qos > 0){ + mid = i8V[i++]*256 + i8V[i++]; + } + var apayload = buffer.slice(i, rl+count+1); + var payload = AB2S(apayload); + + buffer = buffer.slice(rl+1+count); + i8V = new Int8Array(buffer); + + if(this.m.onmessage){ + this.m.onmessage(topic, payload, qos, retain); + } + break; + case PUBREC: + case PUBREL: + case PUBACK: + case PUBCOMP: + case SUBACK: + case UNSUBACK: + case PINGRESP: + var rl = i8V[1]; + buffer = buffer.slice(rl+2); + i8V = new Int8Array(buffer); + break; + } + } + }, + + get_remaining_count : function(remaining_length) + { + if(remaining_length >= 0 && remaining_length < 128){ + return 1; + }else if(remaining_length >= 128 && remaining_length < 16384){ + return 2; + }else if(remaining_length >= 16384 && remaining_length < 2097152){ + return 3; + }else if(remaining_length >= 2097152 && remaining_length < 268435456){ + return 4; + }else{ + return -1; + } + }, + + generate_mid : function() + { + var mid = this.mid; + this.mid++; + if(this.mid == 256) this.mid = 0; + return mid; + }, + + queue : function(buffer) + { + this.out_queue.push(buffer); + }, + + send_cmd_with_mid : function(cmd, mid) + { + var buffer = new ArrayBuffer(4); + var i8V = new Int8Array(buffer); + i8V[0] = cmd; + i8V[1] = 2; + i8V[2] = mid%128; + i8V[3] = mid/128; + if(this.ws.readyState == 1){ + this.ws.send(buffer); + }else{ + this.queue(buffer); + } + }, + + unsubscribe : function(topic) + { + var rl = 2+2+topic.length; + var remaining_count = this.get_remaining_count(rl); + var buffer = new ArrayBuffer(1+remaining_count+rl); + var i8V = new Int8Array(buffer); + + var i=0; + i8V[i++] = UNSUBSCRIBE | 0x02; + do{ + digit = Math.floor(rl % 128); + rl = Math.floor(rl / 128); + if(rl > 0){ + digit = digit | 0x80; + } + i8V[i++] = digit; + }while(rl > 0); + i8V[i++] = 0; + i8V[i++] = this.generate_mid(); + i8V[i++] = 0; + i8V[i++] = topic.length; + for(var j=0; j 0){ + digit = digit | 0x80; + } + i8V[i++] = digit; + }while(rl > 0); + i8V[i++] = 0; + i8V[i++] = this.generate_mid(); + i8V[i++] = 0; + i8V[i++] = topic.length; + for(var j=0; j 0){ + digit = digit | 0x80; + } + i8V[i++] = digit; + }while(rl > 0); + i8V[i++] = 0; + i8V[i++] = topic.length; + for(var j=0; j +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#include +#include +#include +#include + +#include "mosquitto_internal.h" +#include "mosquitto.h" +#include "memory_mosq.h" + +int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...) +{ + va_list va; + char *s; + int len; + + assert(mosq); + assert(fmt); + + pthread_mutex_lock(&mosq->log_callback_mutex); + if(mosq->on_log){ + len = strlen(fmt) + 500; + s = _mosquitto_malloc(len*sizeof(char)); + if(!s){ + pthread_mutex_unlock(&mosq->log_callback_mutex); + return MOSQ_ERR_NOMEM; + } + + va_start(va, fmt); + vsnprintf(s, len, fmt, va); + va_end(va); + s[len-1] = '\0'; /* Ensure string is null terminated. */ + + mosq->on_log(mosq, mosq->userdata, priority, s); + + _mosquitto_free(s); + } + pthread_mutex_unlock(&mosq->log_callback_mutex); + + return MOSQ_ERR_SUCCESS; +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/logging_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/logging_mosq.h new file mode 100644 index 0000000..5f95791 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/logging_mosq.h @@ -0,0 +1,36 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _LOGGING_MOSQ_H_ +#define _LOGGING_MOSQ_H_ + +#include "mosquitto.h" + +int _mosquitto_log_printf(struct mosquitto *mosq, int priority, const char *fmt, ...); + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.c new file mode 100644 index 0000000..199455e --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.c @@ -0,0 +1,134 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" + +#include +#include + +#include "memory_mosq.h" + +#ifdef REAL_WITH_MEMORY_TRACKING +# if defined(__APPLE__) +# include +# define malloc_usable_size malloc_size +# elif defined(__FreeBSD__) +# include +# else +# include +# endif +#endif + +#ifdef REAL_WITH_MEMORY_TRACKING +static unsigned long memcount = 0; +static unsigned long max_memcount = 0; +#endif + +void *_mosquitto_calloc(size_t nmemb, size_t size) +{ + void *mem = calloc(nmemb, size); + +#ifdef REAL_WITH_MEMORY_TRACKING + memcount += malloc_usable_size(mem); + if(memcount > max_memcount){ + max_memcount = memcount; + } +#endif + + return mem; +} + +void _mosquitto_free(void *mem) +{ +#ifdef REAL_WITH_MEMORY_TRACKING + memcount -= malloc_usable_size(mem); +#endif + free(mem); +} + +void *_mosquitto_malloc(size_t size) +{ + void *mem = malloc(size); + +#ifdef REAL_WITH_MEMORY_TRACKING + memcount += malloc_usable_size(mem); + if(memcount > max_memcount){ + max_memcount = memcount; + } +#endif + + return mem; +} + +#ifdef REAL_WITH_MEMORY_TRACKING +unsigned long _mosquitto_memory_used(void) +{ + return memcount; +} + +unsigned long _mosquitto_max_memory_used(void) +{ + return max_memcount; +} +#endif + +void *_mosquitto_realloc(void *ptr, size_t size) +{ + void *mem; +#ifdef REAL_WITH_MEMORY_TRACKING + if(ptr){ + memcount -= malloc_usable_size(ptr); + } +#endif + mem = realloc(ptr, size); + +#ifdef REAL_WITH_MEMORY_TRACKING + memcount += malloc_usable_size(mem); + if(memcount > max_memcount){ + max_memcount = memcount; + } +#endif + + return mem; +} + +char *_mosquitto_strdup(const char *s) +{ + char *str = strdup(s); + +#ifdef REAL_WITH_MEMORY_TRACKING + memcount += malloc_usable_size(str); + if(memcount > max_memcount){ + max_memcount = memcount; + } +#endif + + return str; +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.h new file mode 100644 index 0000000..9ef16f8 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/memory_mosq.h @@ -0,0 +1,50 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _MEMORY_MOSQ_H_ +#define _MEMORY_MOSQ_H_ + +#include +#include + +#if defined(WITH_MEMORY_TRACKING) && defined(WITH_BROKER) && !defined(WIN32) && !defined(__SYMBIAN32__) && !defined(__ANDROID__) +#define REAL_WITH_MEMORY_TRACKING +#endif + +void *_mosquitto_calloc(size_t nmemb, size_t size); +void _mosquitto_free(void *mem); +void *_mosquitto_malloc(size_t size); +#ifdef REAL_WITH_MEMORY_TRACKING +unsigned long _mosquitto_memory_used(void); +unsigned long _mosquitto_max_memory_used(void); +#endif +void *_mosquitto_realloc(void *ptr, size_t size); +char *_mosquitto_strdup(const char *s); + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.c new file mode 100644 index 0000000..d3fcf30 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.c @@ -0,0 +1,400 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "mosquitto_internal.h" +#include "mosquitto.h" +#include "memory_mosq.h" +#include "messages_mosq.h" +#include "send_mosq.h" +#include "time_mosq.h" + +void _mosquitto_message_cleanup(struct mosquitto_message_all **message) +{ + struct mosquitto_message_all *msg; + + if(!message || !*message) return; + + msg = *message; + + if(msg->msg.topic) _mosquitto_free(msg->msg.topic); + if(msg->msg.payload) _mosquitto_free(msg->msg.payload); + _mosquitto_free(msg); +} + +void _mosquitto_message_cleanup_all(struct mosquitto *mosq) +{ + struct mosquitto_message_all *tmp; + + assert(mosq); + + while(mosq->in_messages){ + tmp = mosq->in_messages->next; + _mosquitto_message_cleanup(&mosq->in_messages); + mosq->in_messages = tmp; + } + while(mosq->out_messages){ + tmp = mosq->out_messages->next; + _mosquitto_message_cleanup(&mosq->out_messages); + mosq->out_messages = tmp; + } +} + +int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src) +{ + if(!dst || !src) return MOSQ_ERR_INVAL; + + dst->mid = src->mid; + dst->topic = _mosquitto_strdup(src->topic); + if(!dst->topic) return MOSQ_ERR_NOMEM; + dst->qos = src->qos; + dst->retain = src->retain; + if(src->payloadlen){ + dst->payload = _mosquitto_malloc(src->payloadlen); + if(!dst->payload){ + _mosquitto_free(dst->topic); + return MOSQ_ERR_NOMEM; + } + memcpy(dst->payload, src->payload, src->payloadlen); + dst->payloadlen = src->payloadlen; + }else{ + dst->payloadlen = 0; + dst->payload = NULL; + } + return MOSQ_ERR_SUCCESS; +} + +int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir) +{ + struct mosquitto_message_all *message; + int rc; + assert(mosq); + + rc = _mosquitto_message_remove(mosq, mid, dir, &message); + if(rc == MOSQ_ERR_SUCCESS){ + _mosquitto_message_cleanup(&message); + } + return rc; +} + +void mosquitto_message_free(struct mosquitto_message **message) +{ + struct mosquitto_message *msg; + + if(!message || !*message) return; + + msg = *message; + + if(msg->topic) _mosquitto_free(msg->topic); + if(msg->payload) _mosquitto_free(msg->payload); + _mosquitto_free(msg); +} + +void _mosquitto_message_queue(struct mosquitto *mosq, struct mosquitto_message_all *message, enum mosquitto_msg_direction dir) +{ + /* mosq->*_message_mutex should be locked before entering this function */ + assert(mosq); + assert(message); + + if(dir == mosq_md_out){ + mosq->out_queue_len++; + message->next = NULL; + if(mosq->out_messages_last){ + mosq->out_messages_last->next = message; + }else{ + mosq->out_messages = message; + } + mosq->out_messages_last = message; + }else{ + mosq->in_queue_len++; + if(message->msg.qos > 0 && (mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages)){ + mosq->inflight_messages++; + } + message->next = NULL; + if(mosq->in_messages_last){ + mosq->in_messages_last->next = message; + }else{ + mosq->in_messages = message; + } + mosq->in_messages_last = message; + } +} + +void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq) +{ + struct mosquitto_message_all *message; + struct mosquitto_message_all *prev = NULL; + assert(mosq); + + pthread_mutex_lock(&mosq->in_message_mutex); + message = mosq->in_messages; + mosq->in_queue_len = 0; + while(message){ + mosq->in_queue_len++; + message->timestamp = 0; + if(message->msg.qos != 2){ + if(prev){ + prev->next = message->next; + _mosquitto_message_cleanup(&message); + message = prev; + }else{ + mosq->in_messages = message->next; + _mosquitto_message_cleanup(&message); + message = mosq->in_messages; + } + }else{ + /* Message state can be preserved here because it should match + * whatever the client has got. */ + } + prev = message; + message = message->next; + } + mosq->in_messages_last = prev; + pthread_mutex_unlock(&mosq->in_message_mutex); + + + pthread_mutex_lock(&mosq->out_message_mutex); + mosq->inflight_messages = 0; + message = mosq->out_messages; + mosq->out_queue_len = 0; + while(message){ + mosq->out_queue_len++; + message->timestamp = 0; + + if(message->msg.qos > 0){ + mosq->inflight_messages++; + } + if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){ + if(message->msg.qos == 1){ + message->state = mosq_ms_wait_for_puback; + }else if(message->msg.qos == 2){ + /* Should be able to preserve state. */ + } + }else{ + message->state = mosq_ms_invalid; + } + prev = message; + message = message->next; + } + mosq->out_messages_last = prev; + pthread_mutex_unlock(&mosq->out_message_mutex); +} + +int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message) +{ + struct mosquitto_message_all *cur, *prev = NULL; + bool found = false; + int rc; + assert(mosq); + assert(message); + + if(dir == mosq_md_out){ + pthread_mutex_lock(&mosq->out_message_mutex); + cur = mosq->out_messages; + while(cur){ + if(cur->msg.mid == mid){ + if(prev){ + prev->next = cur->next; + }else{ + mosq->out_messages = cur->next; + } + *message = cur; + mosq->out_queue_len--; + if(cur->next == NULL){ + mosq->out_messages_last = prev; + }else if(!mosq->out_messages){ + mosq->out_messages_last = NULL; + } + if(cur->msg.qos > 0){ + mosq->inflight_messages--; + } + found = true; + break; + } + prev = cur; + cur = cur->next; + } + + if(found){ + cur = mosq->out_messages; + while(cur){ + if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){ + if(cur->msg.qos > 0 && cur->state == mosq_ms_invalid){ + mosq->inflight_messages++; + if(cur->msg.qos == 1){ + cur->state = mosq_ms_wait_for_puback; + }else if(cur->msg.qos == 2){ + cur->state = mosq_ms_wait_for_pubrec; + } + rc = _mosquitto_send_publish(mosq, cur->msg.mid, cur->msg.topic, cur->msg.payloadlen, cur->msg.payload, cur->msg.qos, cur->msg.retain, cur->dup); + if(rc){ + pthread_mutex_unlock(&mosq->out_message_mutex); + return rc; + } + } + }else{ + pthread_mutex_unlock(&mosq->out_message_mutex); + return MOSQ_ERR_SUCCESS; + } + cur = cur->next; + } + pthread_mutex_unlock(&mosq->out_message_mutex); + return MOSQ_ERR_SUCCESS; + }else{ + pthread_mutex_unlock(&mosq->out_message_mutex); + return MOSQ_ERR_NOT_FOUND; + } + }else{ + pthread_mutex_lock(&mosq->in_message_mutex); + cur = mosq->in_messages; + while(cur){ + if(cur->msg.mid == mid){ + if(prev){ + prev->next = cur->next; + }else{ + mosq->in_messages = cur->next; + } + *message = cur; + mosq->in_queue_len--; + if(cur->next == NULL){ + mosq->in_messages_last = prev; + }else if(!mosq->in_messages){ + mosq->in_messages_last = NULL; + } + if(cur->msg.qos == 2){ + mosq->inflight_messages--; + } + found = true; + break; + } + prev = cur; + cur = cur->next; + } + + pthread_mutex_unlock(&mosq->in_message_mutex); + if(found){ + return MOSQ_ERR_SUCCESS; + }else{ + return MOSQ_ERR_NOT_FOUND; + } + } +} + +#ifdef WITH_THREADING +void _mosquitto_message_retry_check_actual(struct mosquitto *mosq, struct mosquitto_message_all *messages, pthread_mutex_t mutex) +#else +void _mosquitto_message_retry_check_actual(struct mosquitto *mosq, struct mosquitto_message_all *messages) +#endif +{ + time_t now = mosquitto_time(); + assert(mosq); + +#ifdef WITH_THREADING + pthread_mutex_lock(&mutex); +#endif + + while(messages){ + if(messages->timestamp + mosq->message_retry < now){ + switch(messages->state){ + case mosq_ms_wait_for_puback: + case mosq_ms_wait_for_pubrec: + messages->timestamp = now; + messages->dup = true; + _mosquitto_send_publish(mosq, messages->msg.mid, messages->msg.topic, messages->msg.payloadlen, messages->msg.payload, messages->msg.qos, messages->msg.retain, messages->dup); + break; + case mosq_ms_wait_for_pubrel: + messages->timestamp = now; + messages->dup = true; + _mosquitto_send_pubrec(mosq, messages->msg.mid); + break; + case mosq_ms_wait_for_pubcomp: + messages->timestamp = now; + messages->dup = true; + _mosquitto_send_pubrel(mosq, messages->msg.mid, true); + break; + default: + break; + } + } + messages = messages->next; + } +#ifdef WITH_THREADING + pthread_mutex_unlock(&mutex); +#endif +} + +void _mosquitto_message_retry_check(struct mosquitto *mosq) +{ +#ifdef WITH_THREADING + _mosquitto_message_retry_check_actual(mosq, mosq->out_messages, mosq->out_message_mutex); + _mosquitto_message_retry_check_actual(mosq, mosq->in_messages, mosq->in_message_mutex); +#else + _mosquitto_message_retry_check_actual(mosq, mosq->out_messages); + _mosquitto_message_retry_check_actual(mosq, mosq->in_messages); +#endif +} + +void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry) +{ + assert(mosq); + if(mosq) mosq->message_retry = message_retry; +} + +int _mosquitto_message_out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state) +{ + struct mosquitto_message_all *message; + assert(mosq); + + pthread_mutex_lock(&mosq->out_message_mutex); + message = mosq->out_messages; + while(message){ + if(message->msg.mid == mid){ + message->state = state; + message->timestamp = mosquitto_time(); + pthread_mutex_unlock(&mosq->out_message_mutex); + return MOSQ_ERR_SUCCESS; + } + message = message->next; + } + pthread_mutex_unlock(&mosq->out_message_mutex); + return MOSQ_ERR_NOT_FOUND; +} + +int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages) +{ + if(!mosq) return MOSQ_ERR_INVAL; + + mosq->max_inflight_messages = max_inflight_messages; + + return MOSQ_ERR_SUCCESS; +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.h new file mode 100644 index 0000000..b9d0c8e --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/messages_mosq.h @@ -0,0 +1,44 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _MESSAGES_MOSQ_H_ +#define _MESSAGES_MOSQ_H_ + +#include "mosquitto_internal.h" +#include "mosquitto.h" + +void _mosquitto_message_cleanup_all(struct mosquitto *mosq); +void _mosquitto_message_cleanup(struct mosquitto_message_all **message); +int _mosquitto_message_delete(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir); +void _mosquitto_message_queue(struct mosquitto *mosq, struct mosquitto_message_all *message, enum mosquitto_msg_direction dir); +void _mosquitto_messages_reconnect_reset(struct mosquitto *mosq); +int _mosquitto_message_remove(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_direction dir, struct mosquitto_message_all **message); +void _mosquitto_message_retry_check(struct mosquitto *mosq); +int _mosquitto_message_out_update(struct mosquitto *mosq, uint16_t mid, enum mosquitto_msg_state state); + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/mosquitto.c b/service/protocol-plugin/plugins/mqtt-light/lib/mosquitto.c new file mode 100644 index 0000000..7f94dea --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/mosquitto.c @@ -0,0 +1,1306 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#include +#else +#include +#include +typedef int ssize_t; +#endif + +#include "mosquitto.h" +#include "mosquitto_internal.h" +#include "logging_mosq.h" +#include "messages_mosq.h" +#include "memory_mosq.h" +#include "mqtt3_protocol.h" +#include "net_mosq.h" +#include "read_handle.h" +#include "send_mosq.h" +#include "time_mosq.h" +#include "tls_mosq.h" +#include "util_mosq.h" +#include "will_mosq.h" + +#if !defined(WIN32) && !defined(__SYMBIAN32__) +#define HAVE_PSELECT +#endif + +void _mosquitto_destroy(struct mosquitto *mosq); +static int _mosquitto_reconnect(struct mosquitto *mosq, bool blocking); +static int _mosquitto_connect_init(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +int mosquitto_lib_version(int *major, int *minor, int *revision) +{ + if(major) *major = LIBMOSQUITTO_MAJOR; + if(minor) *minor = LIBMOSQUITTO_MINOR; + if(revision) *revision = LIBMOSQUITTO_REVISION; + return LIBMOSQUITTO_VERSION_NUMBER; +} + +int mosquitto_lib_init(void) +{ +#ifdef WIN32 + srand(GetTickCount()); +#else + struct timeval tv; + + gettimeofday(&tv, NULL); + srand(tv.tv_sec*1000 + tv.tv_usec/1000); +#endif + + _mosquitto_net_init(); + + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_lib_cleanup(void) +{ + _mosquitto_net_cleanup(); + + return MOSQ_ERR_SUCCESS; +} + +struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *userdata) +{ + struct mosquitto *mosq = NULL; + int rc; + + if(clean_session == false && id == NULL){ + errno = EINVAL; + return NULL; + } + +#ifndef WIN32 + signal(SIGPIPE, SIG_IGN); +#endif + + mosq = (struct mosquitto *)_mosquitto_calloc(1, sizeof(struct mosquitto)); + if(mosq){ + mosq->sock = INVALID_SOCKET; + mosq->sockpairR = INVALID_SOCKET; + mosq->sockpairW = INVALID_SOCKET; +#ifdef WITH_THREADING + mosq->thread_id = pthread_self(); +#endif + rc = mosquitto_reinitialise(mosq, id, clean_session, userdata); + if(rc){ + mosquitto_destroy(mosq); + if(rc == MOSQ_ERR_INVAL){ + errno = EINVAL; + }else if(rc == MOSQ_ERR_NOMEM){ + errno = ENOMEM; + } + return NULL; + } + }else{ + errno = ENOMEM; + } + return mosq; +} + +int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *userdata) +{ + int i; + + if(!mosq) return MOSQ_ERR_INVAL; + + if(clean_session == false && id == NULL){ + return MOSQ_ERR_INVAL; + } + + _mosquitto_destroy(mosq); + memset(mosq, 0, sizeof(struct mosquitto)); + + if(userdata){ + mosq->userdata = userdata; + }else{ + mosq->userdata = mosq; + } + mosq->sock = INVALID_SOCKET; + mosq->sockpairR = INVALID_SOCKET; + mosq->sockpairW = INVALID_SOCKET; + mosq->keepalive = 60; + mosq->message_retry = 20; + mosq->last_retry_check = 0; + mosq->clean_session = clean_session; + if(id){ + if(strlen(id) == 0){ + return MOSQ_ERR_INVAL; + } + mosq->id = _mosquitto_strdup(id); + }else{ + mosq->id = (char *)_mosquitto_calloc(24, sizeof(char)); + if(!mosq->id){ + return MOSQ_ERR_NOMEM; + } + mosq->id[0] = 'm'; + mosq->id[1] = 'o'; + mosq->id[2] = 's'; + mosq->id[3] = 'q'; + mosq->id[4] = '/'; + + for(i=5; i<23; i++){ + mosq->id[i] = (rand()%73)+48; + } + } + mosq->in_packet.payload = NULL; + _mosquitto_packet_cleanup(&mosq->in_packet); + mosq->out_packet = NULL; + mosq->current_out_packet = NULL; + mosq->last_msg_in = mosquitto_time(); + mosq->last_msg_out = mosquitto_time(); + mosq->ping_t = 0; + mosq->last_mid = 0; + mosq->state = mosq_cs_new; + mosq->in_messages = NULL; + mosq->in_messages_last = NULL; + mosq->out_messages = NULL; + mosq->out_messages_last = NULL; + mosq->max_inflight_messages = 20; + mosq->will = NULL; + mosq->on_connect = NULL; + mosq->on_publish = NULL; + mosq->on_message = NULL; + mosq->on_subscribe = NULL; + mosq->on_unsubscribe = NULL; + mosq->host = NULL; + mosq->port = 1883; + mosq->in_callback = false; + mosq->in_queue_len = 0; + mosq->out_queue_len = 0; + mosq->reconnect_delay = 1; + mosq->reconnect_delay_max = 1; + mosq->reconnect_exponential_backoff = false; + mosq->threaded = false; +#ifdef WITH_TLS + mosq->ssl = NULL; + mosq->tls_cert_reqs = SSL_VERIFY_PEER; + mosq->tls_insecure = false; +#endif +#ifdef WITH_THREADING + pthread_mutex_init(&mosq->callback_mutex, NULL); + pthread_mutex_init(&mosq->log_callback_mutex, NULL); + pthread_mutex_init(&mosq->state_mutex, NULL); + pthread_mutex_init(&mosq->out_packet_mutex, NULL); + pthread_mutex_init(&mosq->current_out_packet_mutex, NULL); + pthread_mutex_init(&mosq->msgtime_mutex, NULL); + pthread_mutex_init(&mosq->in_message_mutex, NULL); + pthread_mutex_init(&mosq->out_message_mutex, NULL); + mosq->thread_id = pthread_self(); +#endif + + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain) +{ + if(!mosq) return MOSQ_ERR_INVAL; + return _mosquitto_will_set(mosq, topic, payloadlen, payload, qos, retain); +} + +int mosquitto_will_clear(struct mosquitto *mosq) +{ + if(!mosq) return MOSQ_ERR_INVAL; + return _mosquitto_will_clear(mosq); +} + +int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password) +{ + if(!mosq) return MOSQ_ERR_INVAL; + + if(mosq->username){ + _mosquitto_free(mosq->username); + mosq->username = NULL; + } + if(mosq->password){ + _mosquitto_free(mosq->password); + mosq->password = NULL; + } + + if(username){ + mosq->username = _mosquitto_strdup(username); + if(!mosq->username) return MOSQ_ERR_NOMEM; + if(password){ + mosq->password = _mosquitto_strdup(password); + if(!mosq->password){ + _mosquitto_free(mosq->username); + mosq->username = NULL; + return MOSQ_ERR_NOMEM; + } + } + } + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff) +{ + if(!mosq) return MOSQ_ERR_INVAL; + + mosq->reconnect_delay = reconnect_delay; + mosq->reconnect_delay_max = reconnect_delay_max; + mosq->reconnect_exponential_backoff = reconnect_exponential_backoff; + + return MOSQ_ERR_SUCCESS; + +} + +void _mosquitto_destroy(struct mosquitto *mosq) +{ + struct _mosquitto_packet *packet; + if(!mosq) return; + +#ifdef WITH_THREADING + if(mosq->threaded && !pthread_equal(mosq->thread_id, pthread_self())){ + pthread_cancel(mosq->thread_id); + pthread_join(mosq->thread_id, NULL); + mosq->threaded = false; + } + + if(mosq->id){ + /* If mosq->id is not NULL then the client has already been initialised + * and so the mutexes need destroying. If mosq->id is NULL, the mutexes + * haven't been initialised. */ + pthread_mutex_destroy(&mosq->callback_mutex); + pthread_mutex_destroy(&mosq->log_callback_mutex); + pthread_mutex_destroy(&mosq->state_mutex); + pthread_mutex_destroy(&mosq->out_packet_mutex); + pthread_mutex_destroy(&mosq->current_out_packet_mutex); + pthread_mutex_destroy(&mosq->msgtime_mutex); + pthread_mutex_destroy(&mosq->in_message_mutex); + pthread_mutex_destroy(&mosq->out_message_mutex); + } +#endif + if(mosq->sock != INVALID_SOCKET){ + _mosquitto_socket_close(mosq); + } + _mosquitto_message_cleanup_all(mosq); + _mosquitto_will_clear(mosq); +#ifdef WITH_TLS + if(mosq->ssl){ + SSL_free(mosq->ssl); + } + if(mosq->ssl_ctx){ + SSL_CTX_free(mosq->ssl_ctx); + } + if(mosq->tls_cafile) _mosquitto_free(mosq->tls_cafile); + if(mosq->tls_capath) _mosquitto_free(mosq->tls_capath); + if(mosq->tls_certfile) _mosquitto_free(mosq->tls_certfile); + if(mosq->tls_keyfile) _mosquitto_free(mosq->tls_keyfile); + if(mosq->tls_pw_callback) mosq->tls_pw_callback = NULL; + if(mosq->tls_version) _mosquitto_free(mosq->tls_version); + if(mosq->tls_ciphers) _mosquitto_free(mosq->tls_ciphers); + if(mosq->tls_psk) _mosquitto_free(mosq->tls_psk); + if(mosq->tls_psk_identity) _mosquitto_free(mosq->tls_psk_identity); +#endif + + if(mosq->address){ + _mosquitto_free(mosq->address); + mosq->address = NULL; + } + if(mosq->id){ + _mosquitto_free(mosq->id); + mosq->id = NULL; + } + if(mosq->username){ + _mosquitto_free(mosq->username); + mosq->username = NULL; + } + if(mosq->password){ + _mosquitto_free(mosq->password); + mosq->password = NULL; + } + if(mosq->host){ + _mosquitto_free(mosq->host); + mosq->host = NULL; + } + if(mosq->bind_address){ + _mosquitto_free(mosq->bind_address); + mosq->bind_address = NULL; + } + + /* Out packet cleanup */ + if(mosq->out_packet && !mosq->current_out_packet){ + mosq->current_out_packet = mosq->out_packet; + mosq->out_packet = mosq->out_packet->next; + } + while(mosq->current_out_packet){ + packet = mosq->current_out_packet; + /* Free data and reset values */ + mosq->current_out_packet = mosq->out_packet; + if(mosq->out_packet){ + mosq->out_packet = mosq->out_packet->next; + } + + _mosquitto_packet_cleanup(packet); + _mosquitto_free(packet); + } + + _mosquitto_packet_cleanup(&mosq->in_packet); + if(mosq->sockpairR != INVALID_SOCKET){ + COMPAT_CLOSE(mosq->sockpairR); + mosq->sockpairR = INVALID_SOCKET; + } + if(mosq->sockpairW != INVALID_SOCKET){ + COMPAT_CLOSE(mosq->sockpairW); + mosq->sockpairW = INVALID_SOCKET; + } +} + +void mosquitto_destroy(struct mosquitto *mosq) +{ + if(!mosq) return; + + _mosquitto_destroy(mosq); + _mosquitto_free(mosq); +} + +int mosquitto_socket(struct mosquitto *mosq) +{ + if(!mosq) return MOSQ_ERR_INVAL; + return mosq->sock; +} + +static int _mosquitto_connect_init(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address) +{ + if(!mosq) return MOSQ_ERR_INVAL; + if(!host || port <= 0) return MOSQ_ERR_INVAL; + + if(mosq->host) _mosquitto_free(mosq->host); + mosq->host = _mosquitto_strdup(host); + if(!mosq->host) return MOSQ_ERR_NOMEM; + mosq->port = port; + + if(mosq->bind_address) _mosquitto_free(mosq->bind_address); + if(bind_address){ + mosq->bind_address = _mosquitto_strdup(bind_address); + if(!mosq->bind_address) return MOSQ_ERR_NOMEM; + } + + mosq->keepalive = keepalive; + + if(_mosquitto_socketpair(&mosq->sockpairR, &mosq->sockpairW)){ + _mosquitto_log_printf(mosq, MOSQ_LOG_WARNING, + "Warning: Unable to open socket pair, outgoing publish commands may be delayed."); + } + + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive) +{ + return mosquitto_connect_bind(mosq, host, port, keepalive, NULL); +} + +int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address) +{ + int rc; + rc = _mosquitto_connect_init(mosq, host, port, keepalive, bind_address); + if(rc) return rc; + + pthread_mutex_lock(&mosq->state_mutex); + mosq->state = mosq_cs_new; + pthread_mutex_unlock(&mosq->state_mutex); + + return _mosquitto_reconnect(mosq, true); +} + +int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive) +{ + return mosquitto_connect_bind_async(mosq, host, port, keepalive, NULL); +} + +int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address) +{ + int rc = _mosquitto_connect_init(mosq, host, port, keepalive, bind_address); + if(rc) return rc; + + pthread_mutex_lock(&mosq->state_mutex); + mosq->state = mosq_cs_connect_async; + pthread_mutex_unlock(&mosq->state_mutex); + + return _mosquitto_reconnect(mosq, false); +} + +int mosquitto_reconnect_async(struct mosquitto *mosq) +{ + return _mosquitto_reconnect(mosq, false); +} + +int mosquitto_reconnect(struct mosquitto *mosq) +{ + return _mosquitto_reconnect(mosq, true); +} + +static int _mosquitto_reconnect(struct mosquitto *mosq, bool blocking) +{ + int rc; + struct _mosquitto_packet *packet; + if(!mosq) return MOSQ_ERR_INVAL; + if(!mosq->host || mosq->port <= 0) return MOSQ_ERR_INVAL; + + pthread_mutex_lock(&mosq->state_mutex); + mosq->state = mosq_cs_new; + pthread_mutex_unlock(&mosq->state_mutex); + + pthread_mutex_lock(&mosq->msgtime_mutex); + mosq->last_msg_in = mosquitto_time(); + mosq->last_msg_out = mosquitto_time(); + pthread_mutex_unlock(&mosq->msgtime_mutex); + + mosq->ping_t = 0; + + _mosquitto_packet_cleanup(&mosq->in_packet); + + pthread_mutex_lock(&mosq->current_out_packet_mutex); + pthread_mutex_lock(&mosq->out_packet_mutex); + + if(mosq->out_packet && !mosq->current_out_packet){ + mosq->current_out_packet = mosq->out_packet; + mosq->out_packet = mosq->out_packet->next; + } + + while(mosq->current_out_packet){ + packet = mosq->current_out_packet; + /* Free data and reset values */ + mosq->current_out_packet = mosq->out_packet; + if(mosq->out_packet){ + mosq->out_packet = mosq->out_packet->next; + } + + _mosquitto_packet_cleanup(packet); + _mosquitto_free(packet); + } + pthread_mutex_unlock(&mosq->out_packet_mutex); + pthread_mutex_unlock(&mosq->current_out_packet_mutex); + + _mosquitto_messages_reconnect_reset(mosq); + + rc = _mosquitto_socket_connect(mosq, mosq->host, mosq->port, mosq->bind_address, blocking); + if(rc){ + return rc; + } + + return _mosquitto_send_connect(mosq, mosq->keepalive, mosq->clean_session); +} + +int mosquitto_disconnect(struct mosquitto *mosq) +{ + if(!mosq) return MOSQ_ERR_INVAL; + + pthread_mutex_lock(&mosq->state_mutex); + mosq->state = mosq_cs_disconnecting; + pthread_mutex_unlock(&mosq->state_mutex); + + if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; + return _mosquitto_send_disconnect(mosq); +} + +int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain) +{ + struct mosquitto_message_all *message; + uint16_t local_mid; + + if(!mosq || !topic || qos<0 || qos>2) return MOSQ_ERR_INVAL; + if(strlen(topic) == 0) return MOSQ_ERR_INVAL; + if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE; + + if(_mosquitto_topic_wildcard_len_check(topic) != MOSQ_ERR_SUCCESS){ + return MOSQ_ERR_INVAL; + } + + local_mid = _mosquitto_mid_generate(mosq); + if(mid){ + *mid = local_mid; + } + + if(qos == 0){ + return _mosquitto_send_publish(mosq, local_mid, topic, payloadlen, payload, qos, retain, false); + }else{ + message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all)); + if(!message) return MOSQ_ERR_NOMEM; + + message->next = NULL; + message->timestamp = mosquitto_time(); + message->msg.mid = local_mid; + message->msg.topic = _mosquitto_strdup(topic); + if(!message->msg.topic){ + _mosquitto_message_cleanup(&message); + return MOSQ_ERR_NOMEM; + } + if(payloadlen){ + message->msg.payloadlen = payloadlen; + message->msg.payload = _mosquitto_malloc(payloadlen*sizeof(uint8_t)); + if(!message->msg.payload){ + _mosquitto_message_cleanup(&message); + return MOSQ_ERR_NOMEM; + } + memcpy(message->msg.payload, payload, payloadlen*sizeof(uint8_t)); + }else{ + message->msg.payloadlen = 0; + message->msg.payload = NULL; + } + message->msg.qos = qos; + message->msg.retain = retain; + message->dup = false; + + pthread_mutex_lock(&mosq->out_message_mutex); + _mosquitto_message_queue(mosq, message, mosq_md_out); + if(mosq->max_inflight_messages == 0 || mosq->inflight_messages < mosq->max_inflight_messages){ + mosq->inflight_messages++; + if(qos == 1){ + message->state = mosq_ms_wait_for_puback; + }else if(qos == 2){ + message->state = mosq_ms_wait_for_pubrec; + } + pthread_mutex_unlock(&mosq->out_message_mutex); + return _mosquitto_send_publish(mosq, message->msg.mid, message->msg.topic, message->msg.payloadlen, message->msg.payload, message->msg.qos, message->msg.retain, message->dup); + }else{ + message->state = mosq_ms_invalid; + pthread_mutex_unlock(&mosq->out_message_mutex); + return MOSQ_ERR_SUCCESS; + } + } +} + +int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos) +{ + if(!mosq) return MOSQ_ERR_INVAL; + if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; + + if(_mosquitto_topic_wildcard_pos_check(sub)) return MOSQ_ERR_INVAL; + + return _mosquitto_send_subscribe(mosq, mid, false, sub, qos); +} + +int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub) +{ + if(!mosq) return MOSQ_ERR_INVAL; + if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; + + if(_mosquitto_topic_wildcard_pos_check(sub)) return MOSQ_ERR_INVAL; + + return _mosquitto_send_unsubscribe(mosq, mid, false, sub); +} + +int mosquitto_tls_set(struct mosquitto *mosq, const char *cafile, const char *capath, const char *certfile, const char *keyfile, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)) +{ +#ifdef WITH_TLS + FILE *fptr; + + if(!mosq || (!cafile && !capath) || (certfile && !keyfile) || (!certfile && keyfile)) return MOSQ_ERR_INVAL; + + if(cafile){ + fptr = _mosquitto_fopen(cafile, "rt"); + if(fptr){ + fclose(fptr); + }else{ + return MOSQ_ERR_INVAL; + } + mosq->tls_cafile = _mosquitto_strdup(cafile); + + if(!mosq->tls_cafile){ + return MOSQ_ERR_NOMEM; + } + }else if(mosq->tls_cafile){ + _mosquitto_free(mosq->tls_cafile); + mosq->tls_cafile = NULL; + } + + if(capath){ + mosq->tls_capath = _mosquitto_strdup(capath); + if(!mosq->tls_capath){ + return MOSQ_ERR_NOMEM; + } + }else if(mosq->tls_capath){ + _mosquitto_free(mosq->tls_capath); + mosq->tls_capath = NULL; + } + + if(certfile){ + fptr = _mosquitto_fopen(certfile, "rt"); + if(fptr){ + fclose(fptr); + }else{ + if(mosq->tls_cafile){ + _mosquitto_free(mosq->tls_cafile); + mosq->tls_cafile = NULL; + } + if(mosq->tls_capath){ + _mosquitto_free(mosq->tls_capath); + mosq->tls_capath = NULL; + } + return MOSQ_ERR_INVAL; + } + mosq->tls_certfile = _mosquitto_strdup(certfile); + if(!mosq->tls_certfile){ + return MOSQ_ERR_NOMEM; + } + }else{ + if(mosq->tls_certfile) _mosquitto_free(mosq->tls_certfile); + mosq->tls_certfile = NULL; + } + + if(keyfile){ + fptr = _mosquitto_fopen(keyfile, "rt"); + if(fptr){ + fclose(fptr); + }else{ + if(mosq->tls_cafile){ + _mosquitto_free(mosq->tls_cafile); + mosq->tls_cafile = NULL; + } + if(mosq->tls_capath){ + _mosquitto_free(mosq->tls_capath); + mosq->tls_capath = NULL; + } + if(mosq->tls_certfile){ + _mosquitto_free(mosq->tls_certfile); + mosq->tls_certfile = NULL; + } + return MOSQ_ERR_INVAL; + } + mosq->tls_keyfile = _mosquitto_strdup(keyfile); + if(!mosq->tls_keyfile){ + return MOSQ_ERR_NOMEM; + } + }else{ + if(mosq->tls_keyfile) _mosquitto_free(mosq->tls_keyfile); + mosq->tls_keyfile = NULL; + } + + mosq->tls_pw_callback = pw_callback; + + + return MOSQ_ERR_SUCCESS; +#else + return MOSQ_ERR_NOT_SUPPORTED; + +#endif +} + +int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers) +{ +#ifdef WITH_TLS + if(!mosq) return MOSQ_ERR_INVAL; + + mosq->tls_cert_reqs = cert_reqs; + if(tls_version){ +#if OPENSSL_VERSION_NUMBER >= 0x10001000L + if(!strcasecmp(tls_version, "tlsv1.2") + || !strcasecmp(tls_version, "tlsv1.1") + || !strcasecmp(tls_version, "tlsv1")){ + + mosq->tls_version = _mosquitto_strdup(tls_version); + if(!mosq->tls_version) return MOSQ_ERR_NOMEM; + }else{ + return MOSQ_ERR_INVAL; + } +#else + if(!strcasecmp(tls_version, "tlsv1")){ + mosq->tls_version = _mosquitto_strdup(tls_version); + if(!mosq->tls_version) return MOSQ_ERR_NOMEM; + }else{ + return MOSQ_ERR_INVAL; + } +#endif + }else{ +#if OPENSSL_VERSION_NUMBER >= 0x10001000L + mosq->tls_version = _mosquitto_strdup("tlsv1.2"); +#else + mosq->tls_version = _mosquitto_strdup("tlsv1"); +#endif + if(!mosq->tls_version) return MOSQ_ERR_NOMEM; + } + if(ciphers){ + mosq->tls_ciphers = _mosquitto_strdup(ciphers); + if(!mosq->tls_ciphers) return MOSQ_ERR_NOMEM; + }else{ + mosq->tls_ciphers = NULL; + } + + + return MOSQ_ERR_SUCCESS; +#else + return MOSQ_ERR_NOT_SUPPORTED; + +#endif +} + + +int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value) +{ +#ifdef WITH_TLS + if(!mosq) return MOSQ_ERR_INVAL; + mosq->tls_insecure = value; + return MOSQ_ERR_SUCCESS; +#else + return MOSQ_ERR_NOT_SUPPORTED; +#endif +} + + +int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers) +{ +#ifdef REAL_WITH_TLS_PSK + if(!mosq || !psk || !identity) return MOSQ_ERR_INVAL; + + /* Check for hex only digits */ + if(strspn(psk, "0123456789abcdefABCDEF") < strlen(psk)){ + return MOSQ_ERR_INVAL; + } + mosq->tls_psk = _mosquitto_strdup(psk); + if(!mosq->tls_psk) return MOSQ_ERR_NOMEM; + + mosq->tls_psk_identity = _mosquitto_strdup(identity); + if(!mosq->tls_psk_identity){ + _mosquitto_free(mosq->tls_psk); + return MOSQ_ERR_NOMEM; + } + if(ciphers){ + mosq->tls_ciphers = _mosquitto_strdup(ciphers); + if(!mosq->tls_ciphers) return MOSQ_ERR_NOMEM; + }else{ + mosq->tls_ciphers = NULL; + } + + return MOSQ_ERR_SUCCESS; +#else + return MOSQ_ERR_NOT_SUPPORTED; +#endif +} + + +int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets) +{ +#ifdef HAVE_PSELECT + struct timespec local_timeout; +#else + struct timeval local_timeout; +#endif + fd_set readfds, writefds; + int fdcount; + int rc; + char pairbuf; + int maxfd = 0; + + if(!mosq || max_packets < 1) return MOSQ_ERR_INVAL; + + FD_ZERO(&readfds); + FD_ZERO(&writefds); + if(mosq->sock != INVALID_SOCKET){ + maxfd = mosq->sock; + FD_SET(mosq->sock, &readfds); + pthread_mutex_lock(&mosq->current_out_packet_mutex); + pthread_mutex_lock(&mosq->out_packet_mutex); + if(mosq->out_packet || mosq->current_out_packet){ + FD_SET(mosq->sock, &writefds); +#ifdef WITH_TLS + }else if(mosq->ssl && mosq->want_write){ + FD_SET(mosq->sock, &writefds); +#endif + } + pthread_mutex_unlock(&mosq->out_packet_mutex); + pthread_mutex_unlock(&mosq->current_out_packet_mutex); + }else{ +#ifdef WITH_SRV + if(mosq->achan){ + pthread_mutex_lock(&mosq->state_mutex); + if(mosq->state == mosq_cs_connect_srv){ + rc = ares_fds(mosq->achan, &readfds, &writefds); + if(rc > maxfd){ + maxfd = rc; + } + }else{ + return MOSQ_ERR_NO_CONN; + } + pthread_mutex_unlock(&mosq->state_mutex); + } +#else + return MOSQ_ERR_NO_CONN; +#endif + } + if(mosq->sockpairR != INVALID_SOCKET){ + /* sockpairR is used to break out of select() before the timeout, on a + * call to publish() etc. */ + FD_SET(mosq->sockpairR, &readfds); + if(mosq->sockpairR > maxfd){ + maxfd = mosq->sockpairR; + } + } + + if(timeout >= 0){ + local_timeout.tv_sec = timeout/1000; +#ifdef HAVE_PSELECT + local_timeout.tv_nsec = (timeout-local_timeout.tv_sec*1000)*1e6; +#else + local_timeout.tv_usec = (timeout-local_timeout.tv_sec*1000)*1000; +#endif + }else{ + local_timeout.tv_sec = 1; +#ifdef HAVE_PSELECT + local_timeout.tv_nsec = 0; +#else + local_timeout.tv_usec = 0; +#endif + } + +#ifdef HAVE_PSELECT + fdcount = pselect(maxfd+1, &readfds, &writefds, NULL, &local_timeout, NULL); +#else + fdcount = select(maxfd+1, &readfds, &writefds, NULL, &local_timeout); +#endif + if(fdcount == -1){ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno == EINTR){ + return MOSQ_ERR_SUCCESS; + }else{ + return MOSQ_ERR_ERRNO; + } + }else{ + if(mosq->sock != INVALID_SOCKET){ + if(FD_ISSET(mosq->sock, &readfds)){ + rc = mosquitto_loop_read(mosq, max_packets); + if(rc || mosq->sock == INVALID_SOCKET){ + return rc; + } + } + if(mosq->sockpairR >= 0 && FD_ISSET(mosq->sockpairR, &readfds)){ +#ifndef WIN32 + if(read(mosq->sockpairR, &pairbuf, 1) == 0){ + } +#else + recv(mosq->sockpairR, &pairbuf, 1, 0); +#endif + /* Fake write possible, to stimulate output write even though + * we didn't ask for it, because at that point the publish or + * other command wasn't present. */ + FD_SET(mosq->sock, &writefds); + } + if(FD_ISSET(mosq->sock, &writefds)){ + rc = mosquitto_loop_write(mosq, max_packets); + if(rc || mosq->sock == INVALID_SOCKET){ + return rc; + } + } + } +#ifdef WITH_SRV + if(mosq->achan){ + ares_process(mosq->achan, &readfds, &writefds); + } +#endif + } + return mosquitto_loop_misc(mosq); +} + +int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets) +{ + int run = 1; + int rc; + unsigned int reconnects = 0; + unsigned long reconnect_delay; + + if(!mosq) return MOSQ_ERR_INVAL; + + if(mosq->state == mosq_cs_connect_async){ + mosquitto_reconnect(mosq); + } + + while(run){ + do{ + rc = mosquitto_loop(mosq, timeout, max_packets); + if (reconnects !=0 && rc == MOSQ_ERR_SUCCESS){ + reconnects = 0; + } + }while(rc == MOSQ_ERR_SUCCESS); + if(errno == EPROTO){ + return rc; + } + pthread_mutex_lock(&mosq->state_mutex); + if(mosq->state == mosq_cs_disconnecting){ + run = 0; + pthread_mutex_unlock(&mosq->state_mutex); + }else{ + pthread_mutex_unlock(&mosq->state_mutex); + + if(mosq->reconnect_delay > 0 && mosq->reconnect_exponential_backoff){ + reconnect_delay = mosq->reconnect_delay*reconnects*reconnects; + }else{ + reconnect_delay = mosq->reconnect_delay; + } + + if(reconnect_delay > mosq->reconnect_delay_max){ + reconnect_delay = mosq->reconnect_delay_max; + }else{ + reconnects++; + } + +#ifdef WIN32 + Sleep(reconnect_delay*1000); +#else + sleep(reconnect_delay); +#endif + + pthread_mutex_lock(&mosq->state_mutex); + if(mosq->state == mosq_cs_disconnecting){ + run = 0; + pthread_mutex_unlock(&mosq->state_mutex); + }else{ + pthread_mutex_unlock(&mosq->state_mutex); + mosquitto_reconnect(mosq); + } + } + } + return rc; +} + +int mosquitto_loop_misc(struct mosquitto *mosq) +{ + time_t now; + int rc; + + if(!mosq) return MOSQ_ERR_INVAL; + if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; + + now = mosquitto_time(); + + _mosquitto_check_keepalive(mosq); + if(mosq->last_retry_check+1 < now){ + _mosquitto_message_retry_check(mosq); + mosq->last_retry_check = now; + } + if(mosq->ping_t && now - mosq->ping_t >= mosq->keepalive){ + /* mosq->ping_t != 0 means we are waiting for a pingresp. + * This hasn't happened in the keepalive time so we should disconnect. + */ + _mosquitto_socket_close(mosq); + pthread_mutex_lock(&mosq->state_mutex); + if(mosq->state == mosq_cs_disconnecting){ + rc = MOSQ_ERR_SUCCESS; + }else{ + rc = 1; + } + pthread_mutex_unlock(&mosq->state_mutex); + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_disconnect){ + mosq->in_callback = true; + mosq->on_disconnect(mosq, mosq->userdata, rc); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + return MOSQ_ERR_CONN_LOST; + } + return MOSQ_ERR_SUCCESS; +} + +static int _mosquitto_loop_rc_handle(struct mosquitto *mosq, int rc) +{ + if(rc){ + _mosquitto_socket_close(mosq); + pthread_mutex_lock(&mosq->state_mutex); + if(mosq->state == mosq_cs_disconnecting){ + rc = MOSQ_ERR_SUCCESS; + } + pthread_mutex_unlock(&mosq->state_mutex); + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_disconnect){ + mosq->in_callback = true; + mosq->on_disconnect(mosq, mosq->userdata, rc); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + return rc; + } + return rc; +} + +int mosquitto_loop_read(struct mosquitto *mosq, int max_packets) +{ + int rc; + int i; + if(max_packets < 1) return MOSQ_ERR_INVAL; + + pthread_mutex_lock(&mosq->out_message_mutex); + max_packets = mosq->out_queue_len; + pthread_mutex_unlock(&mosq->out_message_mutex); + + pthread_mutex_lock(&mosq->in_message_mutex); + max_packets += mosq->in_queue_len; + pthread_mutex_unlock(&mosq->in_message_mutex); + + if(max_packets < 1) max_packets = 1; + /* Queue len here tells us how many messages are awaiting processing and + * have QoS > 0. We should try to deal with that many in this loop in order + * to keep up. */ + for(i=0; iout_message_mutex); + max_packets = mosq->out_queue_len; + pthread_mutex_unlock(&mosq->out_message_mutex); + + pthread_mutex_lock(&mosq->in_message_mutex); + max_packets += mosq->in_queue_len; + pthread_mutex_unlock(&mosq->in_message_mutex); + + if(max_packets < 1) max_packets = 1; + /* Queue len here tells us how many messages are awaiting processing and + * have QoS > 0. We should try to deal with that many in this loop in order + * to keep up. */ + for(i=0; iout_packet || mosq->current_out_packet){ + return true; +#ifdef WITH_TLS + }else if(mosq->ssl && mosq->want_write){ + return true; +#endif + }else{ + return false; + } +} + +void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)) +{ + pthread_mutex_lock(&mosq->callback_mutex); + mosq->on_connect = on_connect; + pthread_mutex_unlock(&mosq->callback_mutex); +} + +void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)) +{ + pthread_mutex_lock(&mosq->callback_mutex); + mosq->on_disconnect = on_disconnect; + pthread_mutex_unlock(&mosq->callback_mutex); +} + +void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)) +{ + pthread_mutex_lock(&mosq->callback_mutex); + mosq->on_publish = on_publish; + pthread_mutex_unlock(&mosq->callback_mutex); +} + +void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)) +{ + pthread_mutex_lock(&mosq->callback_mutex); + mosq->on_message = on_message; + pthread_mutex_unlock(&mosq->callback_mutex); +} + +void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)) +{ + pthread_mutex_lock(&mosq->callback_mutex); + mosq->on_subscribe = on_subscribe; + pthread_mutex_unlock(&mosq->callback_mutex); +} + +void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)) +{ + pthread_mutex_lock(&mosq->callback_mutex); + mosq->on_unsubscribe = on_unsubscribe; + pthread_mutex_unlock(&mosq->callback_mutex); +} + +void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)) +{ + pthread_mutex_lock(&mosq->log_callback_mutex); + mosq->on_log = on_log; + pthread_mutex_unlock(&mosq->log_callback_mutex); +} + +void mosquitto_user_data_set(struct mosquitto *mosq, void *userdata) +{ + if(mosq){ + mosq->userdata = userdata; + } +} + +const char *mosquitto_strerror(int mosq_errno) +{ + switch(mosq_errno){ + case MOSQ_ERR_SUCCESS: + return "No error."; + case MOSQ_ERR_NOMEM: + return "Out of memory."; + case MOSQ_ERR_PROTOCOL: + return "A network protocol error occurred when communicating with the broker."; + case MOSQ_ERR_INVAL: + return "Invalid function arguments provided."; + case MOSQ_ERR_NO_CONN: + return "The client is not currently connected."; + case MOSQ_ERR_CONN_REFUSED: + return "The connection was refused."; + case MOSQ_ERR_NOT_FOUND: + return "Message not found (internal error)."; + case MOSQ_ERR_CONN_LOST: + return "The connection was lost."; + case MOSQ_ERR_TLS: + return "A TLS error occurred."; + case MOSQ_ERR_PAYLOAD_SIZE: + return "Payload too large."; + case MOSQ_ERR_NOT_SUPPORTED: + return "This feature is not supported."; + case MOSQ_ERR_AUTH: + return "Authorisation failed."; + case MOSQ_ERR_ACL_DENIED: + return "Access denied by ACL."; + case MOSQ_ERR_UNKNOWN: + return "Unknown error."; + case MOSQ_ERR_ERRNO: + return strerror(errno); + default: + return "Unknown error."; + } +} + +const char *mosquitto_connack_string(int connack_code) +{ + switch(connack_code){ + case 0: + return "Connection Accepted."; + case 1: + return "Connection Refused: unacceptable protocol version."; + case 2: + return "Connection Refused: identifier rejected."; + case 3: + return "Connection Refused: broker unavailable."; + case 4: + return "Connection Refused: bad user name or password."; + case 5: + return "Connection Refused: not authorised."; + default: + return "Connection Refused: unknown reason."; + } +} + +int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count) +{ + int len; + int hier_count = 1; + int start, stop; + int hier; + int tlen; + int i, j; + + if(!subtopic || !topics || !count) return MOSQ_ERR_INVAL; + + len = strlen(subtopic); + + for(i=0; i len-1){ + /* Separator at end of line */ + }else{ + hier_count++; + } + } + } + + (*topics) = _mosquitto_calloc(hier_count, sizeof(char *)); + if(!(*topics)) return MOSQ_ERR_NOMEM; + + start = 0; + stop = 0; + hier = 0; + + for(i=0; i +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +This product includes software developed by the OpenSSL Project for use in the +OpenSSL Toolkit. (http://www.openssl.org/) +This product includes cryptographic software written by Eric Young +(eay@cryptsoft.com) +This product includes software written by Tim Hudson (tjh@cryptsoft.com) +*/ + +#ifndef _MOSQUITTO_H_ +#define _MOSQUITTO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(WIN32) && !defined(WITH_BROKER) +# ifdef libmosquitto_EXPORTS +# define libmosq_EXPORT __declspec(dllexport) +# else +# define libmosq_EXPORT __declspec(dllimport) +# endif +#else +# define libmosq_EXPORT +#endif + +#ifdef WIN32 +# ifndef __cplusplus +# define bool char +# define true 1 +# define false 0 +# endif +#else +# ifndef __cplusplus +# include +# endif +#endif + +#define LIBMOSQUITTO_MAJOR 1 +#define LIBMOSQUITTO_MINOR 3 +#define LIBMOSQUITTO_REVISION 1 +/* LIBMOSQUITTO_VERSION_NUMBER looks like 1002001 for e.g. version 1.2.1. */ +#define LIBMOSQUITTO_VERSION_NUMBER (LIBMOSQUITTO_MAJOR*1000000+LIBMOSQUITTO_MINOR*1000+LIBMOSQUITTO_REVISION) + +/* Log types */ +#define MOSQ_LOG_NONE 0x00 +#define MOSQ_LOG_INFO 0x01 +#define MOSQ_LOG_NOTICE 0x02 +#define MOSQ_LOG_WARNING 0x04 +#define MOSQ_LOG_ERR 0x08 +#define MOSQ_LOG_DEBUG 0x10 +#define MOSQ_LOG_SUBSCRIBE 0x20 +#define MOSQ_LOG_UNSUBSCRIBE 0x40 +#define MOSQ_LOG_ALL 0xFFFF + +/* Error values */ +enum mosq_err_t { + MOSQ_ERR_CONN_PENDING = -1, + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_NOMEM = 1, + MOSQ_ERR_PROTOCOL = 2, + MOSQ_ERR_INVAL = 3, + MOSQ_ERR_NO_CONN = 4, + MOSQ_ERR_CONN_REFUSED = 5, + MOSQ_ERR_NOT_FOUND = 6, + MOSQ_ERR_CONN_LOST = 7, + MOSQ_ERR_TLS = 8, + MOSQ_ERR_PAYLOAD_SIZE = 9, + MOSQ_ERR_NOT_SUPPORTED = 10, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12, + MOSQ_ERR_UNKNOWN = 13, + MOSQ_ERR_ERRNO = 14, + MOSQ_ERR_EAI = 15 +}; + +/* MQTT specification restricts client ids to a maximum of 23 characters */ +#define MOSQ_MQTT_ID_MAX_LENGTH 23 + +struct mosquitto_message{ + int mid; + char *topic; + void *payload; + int payloadlen; + int qos; + bool retain; +}; + +struct mosquitto; + +/* + * Topic: Threads + * libmosquitto provides thread safe operation, with the exception of + * which is not thread safe. + */ +/*************************************************** + * Important note + * + * The following functions that deal with network operations will return + * MOSQ_ERR_SUCCESS on success, but this does not mean that the operation has + * taken place. An attempt will be made to write the network data, but if the + * socket is not available for writing at that time then the packet will not be + * sent. To ensure the packet is sent, call mosquitto_loop() (which must also + * be called to process incoming network data). + * This is especially important when disconnecting a client that has a will. If + * the broker does not receive the DISCONNECT command, it will assume that the + * client has disconnected unexpectedly and send the will. + * + * mosquitto_connect() + * mosquitto_disconnect() + * mosquitto_subscribe() + * mosquitto_unsubscribe() + * mosquitto_publish() + ***************************************************/ + +/* + * Function: mosquitto_lib_version + * + * Can be used to obtain version information for the mosquitto library. + * This allows the application to compare the library version against the + * version it was compiled against by using the LIBMOSQUITTO_MAJOR, + * LIBMOSQUITTO_MINOR and LIBMOSQUITTO_REVISION defines. + * + * Parameters: + * major - an integer pointer. If not NULL, the major version of the + * library will be returned in this variable. + * minor - an integer pointer. If not NULL, the minor version of the + * library will be returned in this variable. + * revision - an integer pointer. If not NULL, the revision of the library will + * be returned in this variable. + * + * Returns: + * LIBMOSQUITTO_VERSION_NUMBER, which is a unique number based on the major, + * minor and revision values. + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_version(int *major, int *minor, int *revision); + +/* + * Function: mosquitto_lib_init + * + * Must be called before any other mosquitto functions. + * + * This function is *not* thread safe. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_init(void); + +/* + * Function: mosquitto_lib_cleanup + * + * Call to free resources associated with the library. + * + * Returns: + * MOSQ_ERR_SUCCESS - always + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_lib_cleanup(void); + +/* + * Function: mosquitto_new + * + * Create a new mosquitto client instance. + * + * Parameters: + * id - String to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Note that a client will never discard its own outgoing + * messages on disconnect. Calling or + * will cause the messages to be resent. + * Use to reset a client to its + * original state. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * Pointer to a struct mosquitto on success. + * NULL on failure. Interrogate errno to determine the cause for the failure: + * - ENOMEM on out of memory. + * - EINVAL on invalid input parameters. + * + * See Also: + * , , + */ +libmosq_EXPORT struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_destroy + * + * Use to free memory associated with a mosquitto client instance. + * + * Parameters: + * mosq - a struct mosquitto pointer to free. + * + * See Also: + * , + */ +libmosq_EXPORT void mosquitto_destroy(struct mosquitto *mosq); + +/* + * Function: mosquitto_reinitialise + * + * This function allows an existing mosquitto client to be reused. Call on a + * mosquitto instance to close any open network connections, free memory + * and reinitialise the client with the new parameters. The end result is the + * same as the output of . + * + * Parameters: + * mosq - a valid mosquitto instance. + * id - string to use as the client id. If NULL, a random client id + * will be generated. If id is NULL, clean_session must be true. + * clean_session - set to true to instruct the broker to clean all messages + * and subscriptions on disconnect, false to instruct it to + * keep them. See the man page mqtt(7) for more details. + * Must be set to true if the id parameter is NULL. + * obj - A user pointer that will be passed as an argument to any + * callbacks that are specified. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_session, void *obj); + +/* + * Function: mosquitto_will_set + * + * Configure will information for a mosquitto instance. By default, clients do + * not have a will. This must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * topic - the topic on which to publish the will. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the will. + * retain - set to true to make the will a retained message. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + */ +libmosq_EXPORT int mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_will_clear + * + * Remove a previously configured will. This must be called before calling + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_will_clear(struct mosquitto *mosq); + +/* + * Function: mosquitto_username_pw_set + * + * Configure username and password for a mosquitton instance. This is only + * supported by brokers that implement the MQTT spec v3.1. By default, no + * username or password will be sent. + * If username is NULL, the password argument is ignored. + * This must be called before calling mosquitto_connect(). + * + * This is must be called before calling . + * + * Parameters: + * mosq - a valid mosquitto instance. + * username - the username to send as a string, or NULL to disable + * authentication. + * password - the password to send as a string. Set to NULL when username is + * valid in order to send just a username. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); + +/* + * Function: mosquitto_connect + * + * Connect to an MQTT broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_bind + * + * Connect to an MQTT broker. This extends the functionality of + * by adding the bind_address parameter. Use this function + * if you need to restrict network communication over a particular interface. + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , , + */ +libmosq_EXPORT int mosquitto_connect_async(struct mosquitto *mosq, const char *host, int port, int keepalive); + +/* + * Function: mosquitto_connect_async + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * port - the network port to connect to. Usually 1883. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_bind_async(struct mosquitto *mosq, const char *host, int port, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_connect_srv + * + * Connect to an MQTT broker. This is a non-blocking call. If you use + * your client must use the threaded interface + * . If you need to use , you must use + * to connect the client. + * + * This extends the functionality of by adding the + * bind_address parameter. Use this function if you need to restrict network + * communication over a particular interface. + * + * May be called before or after . + * + * Parameters: + * mosq - a valid mosquitto instance. + * host - the hostname or ip address of the broker to connect to. + * keepalive - the number of seconds after which the broker should send a PING + * message to the client if no other messages have been exchanged + * in that time. + * bind_address - the hostname or ip address of the local network interface to + * bind to. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address); + +/* + * Function: mosquitto_reconnect + * + * Reconnect to a broker. + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * call. It must not be called before + * . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_reconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_reconnect_async + * + * Reconnect to a broker. Non blocking version of . + * + * This function provides an easy way of reconnecting to a broker after a + * connection has been lost. It uses the values that were provided in the + * or calls. It must not be + * called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_reconnect_async(struct mosquitto *mosq); + +/* + * Function: mosquitto_disconnect + * + * Disconnect from the broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_disconnect(struct mosquitto *mosq); + +/* + * Function: mosquitto_publish + * + * Publish a message on a given topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - pointer to an int. If not NULL, the function will set this + * to the message id of this particular message. This can be then + * used with the publish callback to determine when the message + * has been sent. + * Note that although the MQTT protocol doesn't use message ids + * for messages with QoS=0, libmosquitto assigns them message ids + * so they can be tracked with this parameter. + * payloadlen - the size of the payload (bytes). Valid values are between 0 and + * 268,435,455. + * payload - pointer to the data to send. If payloadlen > 0 this must be a + * valid memory location. + * qos - integer value 0, 1 or 2 indicating the Quality of Service to be + * used for the message. + * retain - set to true to make the message retained. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_PAYLOAD_SIZE - if payloadlen is too large. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_publish(struct mosquitto *mosq, int *mid, const char *topic, int payloadlen, const void *payload, int qos, bool retain); + +/* + * Function: mosquitto_subscribe + * + * Subscribe to a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the subscribe callback to determine when the message has been + * sent. + * sub - the subscription pattern. + * qos - the requested Quality of Service for this subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos); + +/* + * Function: mosquitto_unsubscribe + * + * Unsubscribe from a topic. + * + * Parameters: + * mosq - a valid mosquitto instance. + * mid - a pointer to an int. If not NULL, the function will set this to + * the message id of this particular message. This can be then used + * with the unsubscribe callback to determine when the message has been + * sent. + * sub - the unsubscription pattern. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + */ +libmosq_EXPORT int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub); + +/* + * Function: mosquitto_message_copy + * + * Copy the contents of a mosquitto message to another message. + * Useful for preserving a message received in the on_message() callback. + * + * Parameters: + * dst - a pointer to a valid mosquitto_message struct to copy to. + * src - a pointer to a valid mosquitto_message struct to copy from. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_message_copy(struct mosquitto_message *dst, const struct mosquitto_message *src); + +/* + * Function: mosquitto_message_free + * + * Completely free a mosquitto_message struct. + * + * Parameters: + * message - pointer to a mosquitto_message pointer to free. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_free(struct mosquitto_message **message); + +/* + * Function: mosquitto_loop + * + * The main network loop for the client. You must call this frequently in order + * to keep communications between the client and broker working. If incoming + * data is present it will then be processed. Outgoing commands, from e.g. + * , are normally sent immediately that their function is + * called, but this is not always possible. will also attempt + * to send any remaining outgoing messages, which also includes commands that + * are part of the flow for messages with QoS>0. + * + * An alternative approach is to use to run the client + * loop in its own thread. + * + * This calls select() to monitor the client network socket. If you want to + * integrate mosquitto client operation with your own select() call, use + * , , and + * . + * + * Threads: + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_forever + * + * This function call loop() for you in an infinite blocking loop. It is useful + * for the case where you only want to run the MQTT client loop in your + * program. + * + * It handles reconnecting in case server connection is lost. If you call + * mosquitto_disconnect() in a callback it will return. + * + * Parameters: + * mosq - a valid mosquitto instance. + * timeout - Maximum number of milliseconds to wait for network activity + * in the select() call before timing out. Set to 0 for instant + * return. Set negative to use the default of 1000ms. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets); + +/* + * Function: mosquitto_loop_start + * + * This is part of the threaded client interface. Call this once to start a new + * thread to process network traffic. This provides an alternative to + * repeatedly calling yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_start(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_stop + * + * This is part of the threaded client interface. Call this once to stop the + * network thread previously created with . This call + * will block until the network thread finishes. For the network thread to end, + * you must have previously called or have set the force + * parameter to true. + * + * Parameters: + * mosq - a valid mosquitto instance. + * force - set to true to force thread cancellation. If false, + * must have already been called. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOT_SUPPORTED - if thread support is not available. + * + * See Also: + * , + */ +libmosq_EXPORT int mosquitto_loop_stop(struct mosquitto *mosq, bool force); + +/* + * Function: mosquitto_socket + * + * Return the socket handle for a mosquitto instance. Useful if you want to + * include a mosquitto client in your own select() calls. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * The socket for the mosquitto client or -1 on failure. + */ +libmosq_EXPORT int mosquitto_socket(struct mosquitto *mosq); + +/* + * Function: mosquitto_loop_read + * + * Carry out network read operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_read(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_write + * + * Carry out network write operations. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_packets - this parameter is currently unused and should be set to 1 for + * future compatibility. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * MOSQ_ERR_CONN_LOST - if the connection to the broker was lost. + * MOSQ_ERR_PROTOCOL - if there is a protocol error communicating with the + * broker. + * MOSQ_ERR_ERRNO - if a system call returned an error. The variable errno + * contains the error code, even on Windows. + * Use strerror_r() where available or FormatMessage() on + * Windows. + * + * See Also: + * , , , + */ +libmosq_EXPORT int mosquitto_loop_write(struct mosquitto *mosq, int max_packets); + +/* + * Function: mosquitto_loop_misc + * + * Carry out miscellaneous operations required as part of the network loop. + * This should only be used if you are not using mosquitto_loop() and are + * monitoring the client network socket for activity yourself. + * + * This function deals with handling PINGs and checking whether messages need + * to be retried, so should be called fairly frequently. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NO_CONN - if the client isn't connected to a broker. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_loop_misc(struct mosquitto *mosq); + +/* + * Function: mosquitto_want_write + * + * Returns true if there is data ready to be written on the socket. + * + * Parameters: + * mosq - a valid mosquitto instance. + * + * See Also: + * , , + */ +libmosq_EXPORT bool mosquitto_want_write(struct mosquitto *mosq); + +/* + * Function: mosquitto_tls_set + * + * Configure the client for certificate based SSL/TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Define the Certificate Authority certificates to be trusted (ie. the server + * certificate must be signed with one of these certificates) using cafile. + * + * If the server you are connecting to requires clients to provide a + * certificate, define certfile and keyfile with your client certificate and + * private key. If your private key is encrypted, provide a password callback + * function or you will have to enter the password at the command line. + * + * Parameters: + * mosq - a valid mosquitto instance. + * cafile - path to a file containing the PEM encoded trusted CA + * certificate files. Either cafile or capath must not be NULL. + * capath - path to a directory containing the PEM encoded trusted CA + * certificate files. See mosquitto.conf for more details on + * configuring this directory. Either cafile or capath must not + * be NULL. + * certfile - path to a file containing the PEM encoded certificate file + * for this client. If NULL, keyfile must also be NULL and no + * client certificate will be used. + * keyfile - path to a file containing the PEM encoded private key for + * this client. If NULL, certfile must also be NULL and no + * client certificate will be used. + * pw_callback - if keyfile is encrypted, set pw_callback to allow your client + * to pass the correct password for decryption. If set to NULL, + * the password must be entered on the command line. + * Your callback must write the password into "buf", which is + * "size" bytes long. The return value must be the length of the + * password. "userdata" will be set to the calling mosquitto + * instance. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * , , + */ +libmosq_EXPORT int mosquitto_tls_set(struct mosquitto *mosq, + const char *cafile, const char *capath, + const char *certfile, const char *keyfile, + int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)); + +/* + * Function: mosquitto_tls_insecure_set + * + * Configure verification of the server hostname in the server certificate. If + * value is set to true, it is impossible to guarantee that the host you are + * connecting to is not impersonating your server. This can be useful in + * initial server testing, but makes it possible for a malicious third party to + * impersonate your server through DNS spoofing, for example. + * Do not use this function in a real system. Setting value to true makes the + * connection encryption pointless. + * Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * value - if set to false, the default, certificate hostname checking is + * performed. If set to true, no hostname checking is performed and + * the connection is insecure. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_insecure_set(struct mosquitto *mosq, bool value); + +/* + * Function: mosquitto_tls_opts_set + * + * Set advanced SSL/TLS options. Must be called before . + * + * Parameters: + * mosq - a valid mosquitto instance. + * cert_reqs - an integer defining the verification requirements the client + * will impose on the server. This can be one of: + * * SSL_VERIFY_NONE (0): the server will not be verified in any way. + * * SSL_VERIFY_PEER (1): the server certificate will be verified + * and the connection aborted if the verification fails. + * The default and recommended value is SSL_VERIFY_PEER. Using + * SSL_VERIFY_NONE provides no security. + * tls_version - the version of the SSL/TLS protocol to use as a string. If NULL, + * the default value is used. The default value and the + * available values depend on the version of openssl that the + * library was compiled against. For openssl >= 1.0.1, the + * available options are tlsv1.2, tlsv1.1 and tlsv1, with tlv1.2 + * as the default. For openssl < 1.0.1, only tlsv1 is available. + * ciphers - a string describing the ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_opts_set(struct mosquitto *mosq, int cert_reqs, const char *tls_version, const char *ciphers); + +/* + * Function: mosquitto_tls_psk_set + * + * Configure the client for pre-shared-key based TLS support. Must be called + * before . + * + * Cannot be used in conjunction with . + * + * Parameters: + * mosq - a valid mosquitto instance. + * psk - the pre-shared-key in hex format with no leading "0x". + * identity - the identity of this client. May be used as the username + * depending on the server settings. + * ciphers - a string describing the PSK ciphers available for use. See the + * "openssl ciphers" tool for more information. If NULL, the + * default ciphers will be used. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_tls_psk_set(struct mosquitto *mosq, const char *psk, const char *identity, const char *ciphers); + +/* + * Function: mosquitto_connect_callback_set + * + * Set the connect callback. This is called when the broker sends a CONNACK + * message in response to a connection. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_connect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int rc) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - the return code of the connection response, one of: + * + * * 0 - success + * * 1 - connection refused (unacceptable protocol version) + * * 2 - connection refused (identifier rejected) + * * 3 - connection refused (broker unavailable) + * * 4-255 - reserved for future use + */ +libmosq_EXPORT void mosquitto_connect_callback_set(struct mosquitto *mosq, void (*on_connect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_disconnect_callback_set + * + * Set the disconnect callback. This is called when the broker has received the + * DISCONNECT command and has disconnected the client. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_disconnect - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * rc - integer value indicating the reason for the disconnect. A value of 0 + * means the client has called . Any other value + * indicates that the disconnect is unexpected. + */ +libmosq_EXPORT void mosquitto_disconnect_callback_set(struct mosquitto *mosq, void (*on_disconnect)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_publish_callback_set + * + * Set the publish callback. This is called when a message initiated with + * has been sent to the broker successfully. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_publish - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the sent message. + */ +libmosq_EXPORT void mosquitto_publish_callback_set(struct mosquitto *mosq, void (*on_publish)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_message_callback_set + * + * Set the message callback. This is called when a message is received from the + * broker. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_message - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * message - the message data. This variable and associated memory will be + * freed by the library after the callback completes. The client + * should make copies of any of the data it requires. + * + * See Also: + * + */ +libmosq_EXPORT void mosquitto_message_callback_set(struct mosquitto *mosq, void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *)); + +/* + * Function: mosquitto_subscribe_callback_set + * + * Set the subscribe callback. This is called when the broker responds to a + * subscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_subscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the subscribe message. + * qos_count - the number of granted subscriptions (size of granted_qos). + * granted_qos - an array of integers indicating the granted QoS for each of + * the subscriptions. + */ +libmosq_EXPORT void mosquitto_subscribe_callback_set(struct mosquitto *mosq, void (*on_subscribe)(struct mosquitto *, void *, int, int, const int *)); + +/* + * Function: mosquitto_unsubscribe_callback_set + * + * Set the unsubscribe callback. This is called when the broker responds to a + * unsubscription request. + * + * Parameters: + * mosq - a valid mosquitto instance. + * on_unsubscribe - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int mid) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * mid - the message id of the unsubscribe message. + */ +libmosq_EXPORT void mosquitto_unsubscribe_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int)); + +/* + * Function: mosquitto_log_callback_set + * + * Set the logging callback. This should be used if you want event logging + * information from the client library. + * + * mosq - a valid mosquitto instance. + * on_log - a callback function in the following form: + * void callback(struct mosquitto *mosq, void *obj, int level, const char *str) + * + * Callback Parameters: + * mosq - the mosquitto instance making the callback. + * obj - the user data provided in + * level - the log message level from the values: + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * str - the message string. + */ +libmosq_EXPORT void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mosquitto *, void *, int, const char *)); + +/* + * Function: mosquitto_reconnect_delay_set + * + * Control the behaviour of the client when it has unexpectedly disconnected in + * or after . The default + * behaviour if this function is not used is to repeatedly attempt to reconnect + * with a delay of 1 second until the connection succeeds. + * + * Use reconnect_delay parameter to change the delay between successive + * reconnection attempts. You may also enable exponential backoff of the time + * between reconnections by setting reconnect_exponential_backoff to true and + * set an upper bound on the delay with reconnect_delay_max. + * + * Example 1: + * delay=2, delay_max=10, exponential_backoff=False + * Delays would be: 2, 4, 6, 8, 10, 10, ... + * + * Example 2: + * delay=3, delay_max=30, exponential_backoff=True + * Delays would be: 3, 6, 12, 24, 30, 30, ... + * + * Parameters: + * mosq - a valid mosquitto instance. + * reconnect_delay - the number of seconds to wait between + * reconnects. + * reconnect_delay_max - the maximum number of seconds to wait + * between reconnects. + * reconnect_exponential_backoff - use exponential backoff between + * reconnect attempts. Set to true to enable + * exponential backoff. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_reconnect_delay_set(struct mosquitto *mosq, unsigned int reconnect_delay, unsigned int reconnect_delay_max, bool reconnect_exponential_backoff); + +/* + * Function: mosquitto_max_inflight_messages_set + * + * Set the number of QoS 1 and 2 messages that can be "in flight" at one time. + * An in flight message is part way through its delivery flow. Attempts to send + * further messages with will result in the messages being + * queued until the number of in flight messages reduces. + * + * A higher number here results in greater message throughput, but if set + * higher than the maximum in flight messages on the broker may lead to + * delays in the messages being acknowledged. + * + * Set to 0 for no maximum. + * + * Parameters: + * mosq - a valid mosquitto instance. + * max_inflight_messages - the maximum number of inflight messages. Defaults + * to 20. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success. + * MOSQ_ERR_INVAL - if the input parameters were invalid. + */ +libmosq_EXPORT int mosquitto_max_inflight_messages_set(struct mosquitto *mosq, unsigned int max_inflight_messages); + +/* + * Function: mosquitto_message_retry_set + * + * Set the number of seconds to wait before retrying messages. This applies to + * publish messages with QoS>0. May be called at any time. + * + * Parameters: + * mosq - a valid mosquitto instance. + * message_retry - the number of seconds to wait for a response before + * retrying. Defaults to 20. + */ +libmosq_EXPORT void mosquitto_message_retry_set(struct mosquitto *mosq, unsigned int message_retry); + +/* + * Function: mosquitto_user_data_set + * + * When is called, the pointer given as the "obj" parameter + * will be passed to the callbacks as user data. The + * function allows this obj parameter to be updated at any time. This function + * will not modify the memory pointed to by the current user data pointer. If + * it is dynamically allocated memory you must free it yourself. + * + * Parameters: + * mosq - a valid mosquitto instance. + * obj - A user pointer that will be passed as an argument to any callbacks + * that are specified. + */ +libmosq_EXPORT void mosquitto_user_data_set(struct mosquitto *mosq, void *obj); + + +/* ============================================================================= + * + * Section: Utility functions + * + * ============================================================================= + */ + +/* + * Function: mosquitto_strerror + * + * Call to obtain a const string description of a mosquitto error number. + * + * Parameters: + * mosq_errno - a mosquitto error number. + * + * Returns: + * A constant string describing the error. + */ +libmosq_EXPORT const char *mosquitto_strerror(int mosq_errno); + +/* + * Function: mosquitto_connack_string + * + * Call to obtain a const string description of an MQTT connection result. + * + * Parameters: + * connack_code - an MQTT connection result. + * + * Returns: + * A constant string describing the result. + */ +libmosq_EXPORT const char *mosquitto_connack_string(int connack_code); + +/* + * Function: mosquitto_sub_topic_tokenise + * + * Tokenise a topic or subscription string into an array of strings + * representing the topic hierarchy. + * + * For example: + * + * subtopic: "a/deep/topic/hierarchy" + * + * Would result in: + * + * topics[0] = "a" + * topics[1] = "deep" + * topics[2] = "topic" + * topics[3] = "hierarchy" + * + * and: + * + * subtopic: "/a/deep/topic/hierarchy/" + * + * Would result in: + * + * topics[0] = NULL + * topics[1] = "a" + * topics[2] = "deep" + * topics[3] = "topic" + * topics[4] = "hierarchy" + * + * Parameters: + * subtopic - the subscription/topic to tokenise + * topics - a pointer to store the array of strings + * count - an int pointer to store the number of items in the topics array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + * + * Example: + * + * > char **topics; + * > int topic_count; + * > int i; + * > + * > mosquitto_sub_topic_tokenise("$SYS/broker/uptime", &topics, &topic_count); + * > + * > for(i=0; i printf("%d: %s\n", i, topics[i]); + * > } + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokenise(const char *subtopic, char ***topics, int *count); + +/* + * Function: mosquitto_sub_topic_tokens_free + * + * Free memory that was allocated in . + * + * Parameters: + * topics - pointer to string array. + * count - count of items in string array. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * + * See Also: + * + */ +libmosq_EXPORT int mosquitto_sub_topic_tokens_free(char ***topics, int count); + +/* + * Function: mosquitto_topic_matches_sub + * + * Check whether a topic matches a subscription. + * + * For example: + * + * foo/bar would match the subscription foo/# or +/bar + * non/matching would not match the subscription non/+/+ + * + * Parameters: + * sub - subscription string to check topic against. + * topic - topic to check. + * result - bool pointer to hold result. Will be set to true if the topic + * matches the subscription. + * + * Returns: + * MOSQ_ERR_SUCCESS - on success + * MOSQ_ERR_INVAL - if the input parameters were invalid. + * MOSQ_ERR_NOMEM - if an out of memory condition occurred. + */ +libmosq_EXPORT int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/mosquitto_internal.h b/service/protocol-plugin/plugins/mqtt-light/lib/mosquitto_internal.h new file mode 100644 index 0000000..f3d5fde --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/mosquitto_internal.h @@ -0,0 +1,243 @@ +/* +Copyright (c) 2010,2011,2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _MOSQUITTO_INTERNAL_H_ +#define _MOSQUITTO_INTERNAL_H_ + +#include "config.h" + +#ifdef WIN32 +# include +#endif + +#ifdef WITH_TLS +#include +#endif +#include + +#if defined(WITH_THREADING) && !defined(WITH_BROKER) +# include +#else +# include +#endif + +#ifdef WITH_SRV +# include +#endif + +#ifdef WIN32 +# if _MSC_VER < 1600 + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; +# else +# include +# endif +#else +# include +#endif + +#include "mosquitto.h" +#include "time_mosq.h" +#ifdef WITH_BROKER +struct mosquitto_client_msg; +#endif + +enum mosquitto_msg_direction { + mosq_md_in = 0, + mosq_md_out = 1 +}; + +enum mosquitto_msg_state { + mosq_ms_invalid = 0, + mosq_ms_publish_qos0 = 1, + mosq_ms_publish_qos1 = 2, + mosq_ms_wait_for_puback = 3, + mosq_ms_publish_qos2 = 4, + mosq_ms_wait_for_pubrec = 5, + mosq_ms_resend_pubrel = 6, + mosq_ms_wait_for_pubrel = 7, + mosq_ms_resend_pubcomp = 8, + mosq_ms_wait_for_pubcomp = 9, + mosq_ms_send_pubrec = 10, + mosq_ms_queued = 11 +}; + +enum mosquitto_client_state { + mosq_cs_new = 0, + mosq_cs_connected = 1, + mosq_cs_disconnecting = 2, + mosq_cs_connect_async = 3, + mosq_cs_connect_pending = 4, + mosq_cs_connect_srv = 5 +}; + +enum _mosquitto_protocol { + mosq_p_invalid = 0, + mosq_p_mqtt31 = 1, + mosq_p_mqtt311 = 2, + mosq_p_mqtts = 3 +}; + +enum _mosquitto_transport { + mosq_t_invalid = 0, + mosq_t_tcp = 1, + mosq_t_ws = 2, + mosq_t_sctp = 3 +}; + +struct _mosquitto_packet{ + uint8_t command; + uint8_t have_remaining; + uint8_t remaining_count; + uint16_t mid; + uint32_t remaining_mult; + uint32_t remaining_length; + uint32_t packet_length; + uint32_t to_process; + uint32_t pos; + uint8_t *payload; + struct _mosquitto_packet *next; +}; + +struct mosquitto_message_all{ + struct mosquitto_message_all *next; + time_t timestamp; + //enum mosquitto_msg_direction direction; + enum mosquitto_msg_state state; + bool dup; + struct mosquitto_message msg; +}; + +struct mosquitto { +#ifndef WIN32 + int sock; +# ifndef WITH_BROKER + int sockpairR, sockpairW; +# endif +#else + SOCKET sock; +# ifndef WITH_BROKER + SOCKET sockpairR, sockpairW; +# endif +#endif + enum _mosquitto_protocol protocol; + char *address; + char *id; + char *username; + char *password; + uint16_t keepalive; + bool clean_session; + enum mosquitto_client_state state; + time_t last_msg_in; + time_t last_msg_out; + time_t ping_t; + uint16_t last_mid; + struct _mosquitto_packet in_packet; + struct _mosquitto_packet *current_out_packet; + struct _mosquitto_packet *out_packet; + struct mosquitto_message *will; +#ifdef WITH_TLS + SSL *ssl; + SSL_CTX *ssl_ctx; + char *tls_cafile; + char *tls_capath; + char *tls_certfile; + char *tls_keyfile; + int (*tls_pw_callback)(char *buf, int size, int rwflag, void *userdata); + int tls_cert_reqs; + char *tls_version; + char *tls_ciphers; + char *tls_psk; + char *tls_psk_identity; + bool tls_insecure; +#endif + bool want_write; +#if defined(WITH_THREADING) && !defined(WITH_BROKER) + pthread_mutex_t callback_mutex; + pthread_mutex_t log_callback_mutex; + pthread_mutex_t msgtime_mutex; + pthread_mutex_t out_packet_mutex; + pthread_mutex_t current_out_packet_mutex; + pthread_mutex_t state_mutex; + pthread_mutex_t in_message_mutex; + pthread_mutex_t out_message_mutex; + pthread_t thread_id; +#endif +#ifdef WITH_BROKER + bool is_bridge; + struct _mqtt3_bridge *bridge; + struct mosquitto_client_msg *msgs; + struct mosquitto_client_msg *last_msg; + int msg_count; + int msg_count12; + struct _mosquitto_acl_user *acl_list; + struct _mqtt3_listener *listener; + time_t disconnect_t; + int pollfd_index; + int db_index; + struct _mosquitto_packet *out_packet_last; + bool is_dropping; +#else + void *userdata; + bool in_callback; + unsigned int message_retry; + time_t last_retry_check; + struct mosquitto_message_all *in_messages; + struct mosquitto_message_all *in_messages_last; + struct mosquitto_message_all *out_messages; + struct mosquitto_message_all *out_messages_last; + void (*on_connect)(struct mosquitto *, void *userdata, int rc); + void (*on_disconnect)(struct mosquitto *, void *userdata, int rc); + void (*on_publish)(struct mosquitto *, void *userdata, int mid); + void (*on_message)(struct mosquitto *, void *userdata, const struct mosquitto_message *message); + void (*on_subscribe)(struct mosquitto *, void *userdata, int mid, int qos_count, const int *granted_qos); + void (*on_unsubscribe)(struct mosquitto *, void *userdata, int mid); + void (*on_log)(struct mosquitto *, void *userdata, int level, const char *str); + //void (*on_error)(); + char *host; + int port; + int in_queue_len; + int out_queue_len; + char *bind_address; + unsigned int reconnect_delay; + unsigned int reconnect_delay_max; + bool reconnect_exponential_backoff; + bool threaded; + struct _mosquitto_packet *out_packet_last; + int inflight_messages; + int max_inflight_messages; +# ifdef WITH_SRV + ares_channel achan; +# endif +#endif +}; + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/mqtt3_protocol.h b/service/protocol-plugin/plugins/mqtt-light/lib/mqtt3_protocol.h new file mode 100644 index 0000000..d3fc045 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/mqtt3_protocol.h @@ -0,0 +1,66 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _MQTT3_PROTOCOL_H_ +#define _MQTT3_PROTOCOL_H_ + +/* For version 3 of the MQTT protocol */ + +#define PROTOCOL_NAME_v31 "MQIsdp" +#define PROTOCOL_VERSION_v31 3 + +#define PROTOCOL_NAME_v311 "MQTT" +#define PROTOCOL_VERSION_v311 4 + +/* Message types */ +#define CONNECT 0x10 +#define CONNACK 0x20 +#define PUBLISH 0x30 +#define PUBACK 0x40 +#define PUBREC 0x50 +#define PUBREL 0x60 +#define PUBCOMP 0x70 +#define SUBSCRIBE 0x80 +#define SUBACK 0x90 +#define UNSUBSCRIBE 0xA0 +#define UNSUBACK 0xB0 +#define PINGREQ 0xC0 +#define PINGRESP 0xD0 +#define DISCONNECT 0xE0 + +#define CONNACK_ACCEPTED 0 +#define CONNACK_REFUSED_PROTOCOL_VERSION 1 +#define CONNACK_REFUSED_IDENTIFIER_REJECTED 2 +#define CONNACK_REFUSED_SERVER_UNAVAILABLE 3 +#define CONNACK_REFUSED_BAD_USERNAME_PASSWORD 4 +#define CONNACK_REFUSED_NOT_AUTHORIZED 5 + +#define MQTT_MAX_PAYLOAD 268435455 + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.c new file mode 100644 index 0000000..517a485 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.c @@ -0,0 +1,1129 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#include +#else +#include +#include +#endif + +#ifdef __ANDROID__ +#include +#include +#include +#endif + +#ifdef __FreeBSD__ +# include +#endif + +#ifdef __SYMBIAN32__ +#include +#endif + +#ifdef __QNX__ +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 +#endif +#include +#include +#endif + +#ifdef WITH_TLS +#include +#include +#endif + +#ifdef WITH_BROKER +# include +# ifdef WITH_SYS_TREE + extern uint64_t g_bytes_received; + extern uint64_t g_bytes_sent; + extern unsigned long g_msgs_received; + extern unsigned long g_msgs_sent; + extern unsigned long g_pub_msgs_received; + extern unsigned long g_pub_msgs_sent; +# endif +#else +# include +#endif + +#include "logging_mosq.h" +#include "memory_mosq.h" +#include "mqtt3_protocol.h" +#include "net_mosq.h" +#include "time_mosq.h" +#include "util_mosq.h" + +#ifdef WITH_TLS +int tls_ex_index_mosq = -1; +#endif + +void _mosquitto_net_init(void) +{ +#ifdef WIN32 + WSADATA wsaData; + WSAStartup(MAKEWORD(2,2), &wsaData); +#endif + +#ifdef WITH_SRV + ares_library_init(ARES_LIB_INIT_ALL); +#endif + +#ifdef WITH_TLS + SSL_load_error_strings(); + SSL_library_init(); + OpenSSL_add_all_algorithms(); + if(tls_ex_index_mosq == -1){ + tls_ex_index_mosq = SSL_get_ex_new_index(0, "client context", NULL, NULL, NULL); + } +#endif +} + +void _mosquitto_net_cleanup(void) +{ +#ifdef WITH_TLS + ERR_free_strings(); + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); +#endif + +#ifdef WITH_SRV + ares_library_cleanup(); +#endif + +#ifdef WIN32 + WSACleanup(); +#endif +} + +void _mosquitto_packet_cleanup(struct _mosquitto_packet *packet) +{ + if(!packet) return; + + /* Free data and reset values */ + packet->command = 0; + packet->have_remaining = 0; + packet->remaining_count = 0; + packet->remaining_mult = 1; + packet->remaining_length = 0; + if(packet->payload) _mosquitto_free(packet->payload); + packet->payload = NULL; + packet->to_process = 0; + packet->pos = 0; +} + +int _mosquitto_packet_queue(struct mosquitto *mosq, struct _mosquitto_packet *packet) +{ +#ifndef WITH_BROKER + char sockpair_data = 0; +#endif + assert(mosq); + assert(packet); + + packet->pos = 0; + packet->to_process = packet->packet_length; + + packet->next = NULL; + pthread_mutex_lock(&mosq->out_packet_mutex); + if(mosq->out_packet){ + mosq->out_packet_last->next = packet; + }else{ + mosq->out_packet = packet; + } + mosq->out_packet_last = packet; + pthread_mutex_unlock(&mosq->out_packet_mutex); +#ifdef WITH_BROKER + return _mosquitto_packet_write(mosq); +#else + + /* Write a single byte to sockpairW (connected to sockpairR) to break out + * of select() if in threaded mode. */ + if(mosq->sockpairW != INVALID_SOCKET){ +#ifndef WIN32 + if(write(mosq->sockpairW, &sockpair_data, 1)){ + } +#else + send(mosq->sockpairW, &sockpair_data, 1, 0); +#endif + } + + if(mosq->in_callback == false && mosq->threaded == false){ + return _mosquitto_packet_write(mosq); + }else{ + return MOSQ_ERR_SUCCESS; + } +#endif +} + +/* Close a socket associated with a context and set it to -1. + * Returns 1 on failure (context is NULL) + * Returns 0 on success. + */ +int _mosquitto_socket_close(struct mosquitto *mosq) +{ + int rc = 0; + + assert(mosq); +#ifdef WITH_TLS + if(mosq->ssl){ + SSL_shutdown(mosq->ssl); + SSL_free(mosq->ssl); + mosq->ssl = NULL; + } + if(mosq->ssl_ctx){ + SSL_CTX_free(mosq->ssl_ctx); + mosq->ssl_ctx = NULL; + } +#endif + + if(mosq->sock != INVALID_SOCKET){ + rc = COMPAT_CLOSE(mosq->sock); + mosq->sock = INVALID_SOCKET; + } + + return rc; +} + +#ifdef REAL_WITH_TLS_PSK +static unsigned int psk_client_callback(SSL *ssl, const char *hint, + char *identity, unsigned int max_identity_len, + unsigned char *psk, unsigned int max_psk_len) +{ + struct mosquitto *mosq; + int len; + + mosq = SSL_get_ex_data(ssl, tls_ex_index_mosq); + if(!mosq) return 0; + + snprintf(identity, max_identity_len, "%s", mosq->tls_psk_identity); + + len = _mosquitto_hex2bin(mosq->tls_psk, psk, max_psk_len); + if (len < 0) return 0; + return len; +} +#endif + +int _mosquitto_try_connect(const char *host, uint16_t port, int *sock, const char *bind_address, bool blocking) +{ + struct addrinfo hints; + struct addrinfo *ainfo, *rp; + struct addrinfo *ainfo_bind, *rp_bind; + int s; + int rc; +#ifdef WIN32 + uint32_t val = 1; +#endif + + *sock = INVALID_SOCKET; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = PF_UNSPEC; + hints.ai_flags = AI_ADDRCONFIG; + hints.ai_socktype = SOCK_STREAM; + + s = getaddrinfo(host, NULL, &hints, &ainfo); + if(s){ + errno = s; + return MOSQ_ERR_EAI; + } + + if(bind_address){ + s = getaddrinfo(bind_address, NULL, &hints, &ainfo_bind); + if(s){ + freeaddrinfo(ainfo); + errno = s; + return MOSQ_ERR_EAI; + } + } + + for(rp = ainfo; rp != NULL; rp = rp->ai_next){ + *sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if(*sock == INVALID_SOCKET) continue; + + if(rp->ai_family == PF_INET){ + ((struct sockaddr_in *)rp->ai_addr)->sin_port = htons(port); + }else if(rp->ai_family == PF_INET6){ + ((struct sockaddr_in6 *)rp->ai_addr)->sin6_port = htons(port); + }else{ + continue; + } + + if(bind_address){ + for(rp_bind = ainfo_bind; rp_bind != NULL; rp_bind = rp_bind->ai_next){ + if(bind(*sock, rp_bind->ai_addr, rp_bind->ai_addrlen) == 0){ + break; + } + } + if(!rp_bind){ + COMPAT_CLOSE(*sock); + continue; + } + } + + if(!blocking){ + /* Set non-blocking */ + if(_mosquitto_socket_nonblock(*sock)){ + COMPAT_CLOSE(*sock); + continue; + } + } + + rc = connect(*sock, rp->ai_addr, rp->ai_addrlen); +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(rc == 0 || errno == EINPROGRESS || errno == COMPAT_EWOULDBLOCK){ + if(blocking){ + /* Set non-blocking */ + if(_mosquitto_socket_nonblock(*sock)){ + COMPAT_CLOSE(*sock); + continue; + } + } + break; + } + + COMPAT_CLOSE(*sock); + *sock = INVALID_SOCKET; + } + freeaddrinfo(ainfo); + if(bind_address){ + freeaddrinfo(ainfo_bind); + } + if(!rp){ + return MOSQ_ERR_ERRNO; + } + return MOSQ_ERR_SUCCESS; +} + +/* Create a socket and connect it to 'ip' on port 'port'. + * Returns -1 on failure (ip is NULL, socket creation/connection error) + * Returns sock number on success. + */ +int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking) +{ + int sock = INVALID_SOCKET; + int rc; +#ifdef WITH_TLS + int ret; + BIO *bio; +#endif + + if(!mosq || !host || !port) return MOSQ_ERR_INVAL; + +#ifdef WITH_TLS + if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ + blocking = true; + } +#endif + + rc = _mosquitto_try_connect(host, port, &sock, bind_address, blocking); + if(rc != MOSQ_ERR_SUCCESS) return rc; + +#ifdef WITH_TLS + if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ +#if OPENSSL_VERSION_NUMBER >= 0x10001000L + if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1.2")){ + mosq->ssl_ctx = SSL_CTX_new(TLSv1_2_client_method()); + }else if(!strcmp(mosq->tls_version, "tlsv1.1")){ + mosq->ssl_ctx = SSL_CTX_new(TLSv1_1_client_method()); + }else if(!strcmp(mosq->tls_version, "tlsv1")){ + mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method()); + }else{ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version); + COMPAT_CLOSE(sock); + return MOSQ_ERR_INVAL; + } +#else + if(!mosq->tls_version || !strcmp(mosq->tls_version, "tlsv1")){ + mosq->ssl_ctx = SSL_CTX_new(TLSv1_client_method()); + }else{ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Protocol %s not supported.", mosq->tls_version); + COMPAT_CLOSE(sock); + return MOSQ_ERR_INVAL; + } +#endif + if(!mosq->ssl_ctx){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to create TLS context."); + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + +#if OPENSSL_VERSION_NUMBER >= 0x10000000 + /* Disable compression */ + SSL_CTX_set_options(mosq->ssl_ctx, SSL_OP_NO_COMPRESSION); +#endif +#ifdef SSL_MODE_RELEASE_BUFFERS + /* Use even less memory per SSL connection. */ + SSL_CTX_set_mode(mosq->ssl_ctx, SSL_MODE_RELEASE_BUFFERS); +#endif + + if(mosq->tls_ciphers){ + ret = SSL_CTX_set_cipher_list(mosq->ssl_ctx, mosq->tls_ciphers); + if(ret == 0){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to set TLS ciphers. Check cipher list \"%s\".", mosq->tls_ciphers); + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + } + if(mosq->tls_cafile || mosq->tls_capath){ + ret = SSL_CTX_load_verify_locations(mosq->ssl_ctx, mosq->tls_cafile, mosq->tls_capath); + if(ret == 0){ +#ifdef WITH_BROKER + if(mosq->tls_cafile && mosq->tls_capath){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\" and bridge_capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); + }else if(mosq->tls_cafile){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_cafile \"%s\".", mosq->tls_cafile); + }else{ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check bridge_capath \"%s\".", mosq->tls_capath); + } +#else + if(mosq->tls_cafile && mosq->tls_capath){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\" and capath \"%s\".", mosq->tls_cafile, mosq->tls_capath); + }else if(mosq->tls_cafile){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check cafile \"%s\".", mosq->tls_cafile); + }else{ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load CA certificates, check capath \"%s\".", mosq->tls_capath); + } +#endif + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + if(mosq->tls_cert_reqs == 0){ + SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_NONE, NULL); + }else{ + SSL_CTX_set_verify(mosq->ssl_ctx, SSL_VERIFY_PEER, _mosquitto_server_certificate_verify); + } + + if(mosq->tls_pw_callback){ + SSL_CTX_set_default_passwd_cb(mosq->ssl_ctx, mosq->tls_pw_callback); + SSL_CTX_set_default_passwd_cb_userdata(mosq->ssl_ctx, mosq); + } + + if(mosq->tls_certfile){ + ret = SSL_CTX_use_certificate_chain_file(mosq->ssl_ctx, mosq->tls_certfile); + if(ret != 1){ +#ifdef WITH_BROKER + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate, check bridge_certfile \"%s\".", mosq->tls_certfile); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client certificate \"%s\".", mosq->tls_certfile); +#endif + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + } + if(mosq->tls_keyfile){ + ret = SSL_CTX_use_PrivateKey_file(mosq->ssl_ctx, mosq->tls_keyfile, SSL_FILETYPE_PEM); + if(ret != 1){ +#ifdef WITH_BROKER + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file, check bridge_keyfile \"%s\".", mosq->tls_keyfile); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unable to load client key file \"%s\".", mosq->tls_keyfile); +#endif + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + ret = SSL_CTX_check_private_key(mosq->ssl_ctx); + if(ret != 1){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Client certificate/key are inconsistent."); + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + } +#ifdef REAL_WITH_TLS_PSK + }else if(mosq->tls_psk){ + SSL_CTX_set_psk_client_callback(mosq->ssl_ctx, psk_client_callback); +#endif + } + + mosq->ssl = SSL_new(mosq->ssl_ctx); + if(!mosq->ssl){ + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + SSL_set_ex_data(mosq->ssl, tls_ex_index_mosq, mosq); + bio = BIO_new_socket(sock, BIO_NOCLOSE); + if(!bio){ + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + SSL_set_bio(mosq->ssl, bio, bio); + + ret = SSL_connect(mosq->ssl); + if(ret != 1){ + ret = SSL_get_error(mosq->ssl, ret); + if(ret == SSL_ERROR_WANT_READ){ + /* We always try to read anyway */ + }else if(ret == SSL_ERROR_WANT_WRITE){ + mosq->want_write = true; + }else{ + COMPAT_CLOSE(sock); + return MOSQ_ERR_TLS; + } + } + } +#endif + + mosq->sock = sock; + + return MOSQ_ERR_SUCCESS; +} + +int _mosquitto_read_byte(struct _mosquitto_packet *packet, uint8_t *byte) +{ + assert(packet); + if(packet->pos+1 > packet->remaining_length) return MOSQ_ERR_PROTOCOL; + + *byte = packet->payload[packet->pos]; + packet->pos++; + + return MOSQ_ERR_SUCCESS; +} + +void _mosquitto_write_byte(struct _mosquitto_packet *packet, uint8_t byte) +{ + assert(packet); + assert(packet->pos+1 <= packet->packet_length); + + packet->payload[packet->pos] = byte; + packet->pos++; +} + +int _mosquitto_read_bytes(struct _mosquitto_packet *packet, void *bytes, uint32_t count) +{ + assert(packet); + if(packet->pos+count > packet->remaining_length) return MOSQ_ERR_PROTOCOL; + + memcpy(bytes, &(packet->payload[packet->pos]), count); + packet->pos += count; + + return MOSQ_ERR_SUCCESS; +} + +void _mosquitto_write_bytes(struct _mosquitto_packet *packet, const void *bytes, uint32_t count) +{ + assert(packet); + assert(packet->pos+count <= packet->packet_length); + + memcpy(&(packet->payload[packet->pos]), bytes, count); + packet->pos += count; +} + +int _mosquitto_read_string(struct _mosquitto_packet *packet, char **str) +{ + uint16_t len; + int rc; + + assert(packet); + rc = _mosquitto_read_uint16(packet, &len); + if(rc) return rc; + + if(packet->pos+len > packet->remaining_length) return MOSQ_ERR_PROTOCOL; + + *str = _mosquitto_calloc(len+1, sizeof(char)); + if(*str){ + memcpy(*str, &(packet->payload[packet->pos]), len); + packet->pos += len; + }else{ + return MOSQ_ERR_NOMEM; + } + + return MOSQ_ERR_SUCCESS; +} + +void _mosquitto_write_string(struct _mosquitto_packet *packet, const char *str, uint16_t length) +{ + assert(packet); + _mosquitto_write_uint16(packet, length); + _mosquitto_write_bytes(packet, str, length); +} + +int _mosquitto_read_uint16(struct _mosquitto_packet *packet, uint16_t *word) +{ + uint8_t msb, lsb; + + assert(packet); + if(packet->pos+2 > packet->remaining_length) return MOSQ_ERR_PROTOCOL; + + msb = packet->payload[packet->pos]; + packet->pos++; + lsb = packet->payload[packet->pos]; + packet->pos++; + + *word = (msb<<8) + lsb; + + return MOSQ_ERR_SUCCESS; +} + +void _mosquitto_write_uint16(struct _mosquitto_packet *packet, uint16_t word) +{ + _mosquitto_write_byte(packet, MOSQ_MSB(word)); + _mosquitto_write_byte(packet, MOSQ_LSB(word)); +} + +ssize_t _mosquitto_net_read(struct mosquitto *mosq, void *buf, size_t count) +{ +#ifdef WITH_TLS + int ret; + int err; + char ebuf[256]; + unsigned long e; +#endif + assert(mosq); + errno = 0; +#ifdef WITH_TLS + if(mosq->ssl){ + ret = SSL_read(mosq->ssl, buf, count); + if(ret <= 0){ + err = SSL_get_error(mosq->ssl, ret); + if(err == SSL_ERROR_WANT_READ){ + ret = -1; + errno = EAGAIN; + }else if(err == SSL_ERROR_WANT_WRITE){ + ret = -1; + mosq->want_write = true; + errno = EAGAIN; + }else{ + e = ERR_get_error(); + while(e){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "OpenSSL Error: %s", ERR_error_string(e, ebuf)); + e = ERR_get_error(); + } + errno = EPROTO; + } + } + return (ssize_t )ret; + }else{ + /* Call normal read/recv */ + +#endif + +#ifndef WIN32 + return read(mosq->sock, buf, count); +#else + return recv(mosq->sock, buf, count, 0); +#endif + +#ifdef WITH_TLS + } +#endif +} + +ssize_t _mosquitto_net_write(struct mosquitto *mosq, void *buf, size_t count) +{ +#ifdef WITH_TLS + int ret; + int err; + char ebuf[256]; + unsigned long e; +#endif + assert(mosq); + + errno = 0; +#ifdef WITH_TLS + if(mosq->ssl){ + ret = SSL_write(mosq->ssl, buf, count); + if(ret < 0){ + err = SSL_get_error(mosq->ssl, ret); + if(err == SSL_ERROR_WANT_READ){ + ret = -1; + errno = EAGAIN; + }else if(err == SSL_ERROR_WANT_WRITE){ + ret = -1; + mosq->want_write = true; + errno = EAGAIN; + }else{ + e = ERR_get_error(); + while(e){ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "OpenSSL Error: %s", ERR_error_string(e, ebuf)); + e = ERR_get_error(); + } + errno = EPROTO; + } + } + return (ssize_t )ret; + }else{ + /* Call normal write/send */ +#endif + +#ifndef WIN32 + return write(mosq->sock, buf, count); +#else + return send(mosq->sock, buf, count, 0); +#endif + +#ifdef WITH_TLS + } +#endif +} + +int _mosquitto_packet_write(struct mosquitto *mosq) +{ + ssize_t write_length; + struct _mosquitto_packet *packet; + + if(!mosq) return MOSQ_ERR_INVAL; + if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; + + pthread_mutex_lock(&mosq->current_out_packet_mutex); + pthread_mutex_lock(&mosq->out_packet_mutex); + if(mosq->out_packet && !mosq->current_out_packet){ + mosq->current_out_packet = mosq->out_packet; + mosq->out_packet = mosq->out_packet->next; + if(!mosq->out_packet){ + mosq->out_packet_last = NULL; + } + } + pthread_mutex_unlock(&mosq->out_packet_mutex); + + while(mosq->current_out_packet){ + packet = mosq->current_out_packet; + + while(packet->to_process > 0){ + write_length = _mosquitto_net_write(mosq, &(packet->payload[packet->pos]), packet->to_process); + if(write_length > 0){ +#if defined(WITH_BROKER) && defined(WITH_SYS_TREE) + g_bytes_sent += write_length; +#endif + packet->to_process -= write_length; + packet->pos += write_length; + }else{ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){ + pthread_mutex_unlock(&mosq->current_out_packet_mutex); + return MOSQ_ERR_SUCCESS; + }else{ + pthread_mutex_unlock(&mosq->current_out_packet_mutex); + switch(errno){ + case COMPAT_ECONNRESET: + return MOSQ_ERR_CONN_LOST; + default: + return MOSQ_ERR_ERRNO; + } + } + } + } + +#ifdef WITH_BROKER +# ifdef WITH_SYS_TREE + g_msgs_sent++; + if(((packet->command)&0xF6) == PUBLISH){ + g_pub_msgs_sent++; + } +# endif +#else + if(((packet->command)&0xF6) == PUBLISH){ + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_publish){ + /* This is a QoS=0 message */ + mosq->in_callback = true; + mosq->on_publish(mosq, mosq->userdata, packet->mid); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + }else if(((packet->command)&0xF0) == DISCONNECT){ + /* FIXME what cleanup needs doing here? + * incoming/outgoing messages? */ + _mosquitto_socket_close(mosq); + + /* Start of duplicate, possibly unnecessary code. + * This does leave things in a consistent state at least. */ + /* Free data and reset values */ + pthread_mutex_lock(&mosq->out_packet_mutex); + mosq->current_out_packet = mosq->out_packet; + if(mosq->out_packet){ + mosq->out_packet = mosq->out_packet->next; + if(!mosq->out_packet){ + mosq->out_packet_last = NULL; + } + } + pthread_mutex_unlock(&mosq->out_packet_mutex); + + _mosquitto_packet_cleanup(packet); + _mosquitto_free(packet); + + pthread_mutex_lock(&mosq->msgtime_mutex); + mosq->last_msg_out = mosquitto_time(); + pthread_mutex_unlock(&mosq->msgtime_mutex); + /* End of duplicate, possibly unnecessary code */ + + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_disconnect){ + mosq->in_callback = true; + mosq->on_disconnect(mosq, mosq->userdata, 0); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->current_out_packet_mutex); + return MOSQ_ERR_SUCCESS; + } +#endif + + /* Free data and reset values */ + pthread_mutex_lock(&mosq->out_packet_mutex); + mosq->current_out_packet = mosq->out_packet; + if(mosq->out_packet){ + mosq->out_packet = mosq->out_packet->next; + if(!mosq->out_packet){ + mosq->out_packet_last = NULL; + } + } + pthread_mutex_unlock(&mosq->out_packet_mutex); + + _mosquitto_packet_cleanup(packet); + _mosquitto_free(packet); + + pthread_mutex_lock(&mosq->msgtime_mutex); + mosq->last_msg_out = mosquitto_time(); + pthread_mutex_unlock(&mosq->msgtime_mutex); + } + pthread_mutex_unlock(&mosq->current_out_packet_mutex); + return MOSQ_ERR_SUCCESS; +} + +#ifdef WITH_BROKER +int _mosquitto_packet_read(struct mosquitto_db *db, struct mosquitto *mosq) +#else +int _mosquitto_packet_read(struct mosquitto *mosq) +#endif +{ + uint8_t byte; + ssize_t read_length; + int rc = 0; + + if(!mosq) return MOSQ_ERR_INVAL; + if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; + /* This gets called if pselect() indicates that there is network data + * available - ie. at least one byte. What we do depends on what data we + * already have. + * If we've not got a command, attempt to read one and save it. This should + * always work because it's only a single byte. + * Then try to read the remaining length. This may fail because it is may + * be more than one byte - will need to save data pending next read if it + * does fail. + * Then try to read the remaining payload, where 'payload' here means the + * combined variable header and actual payload. This is the most likely to + * fail due to longer length, so save current data and current position. + * After all data is read, send to _mosquitto_handle_packet() to deal with. + * Finally, free the memory and reset everything to starting conditions. + */ + if(!mosq->in_packet.command){ + read_length = _mosquitto_net_read(mosq, &byte, 1); + if(read_length == 1){ + mosq->in_packet.command = byte; +#ifdef WITH_BROKER +# ifdef WITH_SYS_TREE + g_bytes_received++; +# endif + /* Clients must send CONNECT as their first command. */ + if(!(mosq->bridge) && mosq->state == mosq_cs_new && (byte&0xF0) != CONNECT) return MOSQ_ERR_PROTOCOL; +#endif + }else{ + if(read_length == 0) return MOSQ_ERR_CONN_LOST; /* EOF */ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){ + return MOSQ_ERR_SUCCESS; + }else{ + switch(errno){ + case COMPAT_ECONNRESET: + return MOSQ_ERR_CONN_LOST; + default: + return MOSQ_ERR_ERRNO; + } + } + } + } + if(!mosq->in_packet.have_remaining){ + do{ + read_length = _mosquitto_net_read(mosq, &byte, 1); + if(read_length == 1){ + mosq->in_packet.remaining_count++; + /* Max 4 bytes length for remaining length as defined by protocol. + * Anything more likely means a broken/malicious client. + */ + if(mosq->in_packet.remaining_count > 4) return MOSQ_ERR_PROTOCOL; + +#if defined(WITH_BROKER) && defined(WITH_SYS_TREE) + g_bytes_received++; +#endif + mosq->in_packet.remaining_length += (byte & 127) * mosq->in_packet.remaining_mult; + mosq->in_packet.remaining_mult *= 128; + }else{ + if(read_length == 0) return MOSQ_ERR_CONN_LOST; /* EOF */ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){ + return MOSQ_ERR_SUCCESS; + }else{ + switch(errno){ + case COMPAT_ECONNRESET: + return MOSQ_ERR_CONN_LOST; + default: + return MOSQ_ERR_ERRNO; + } + } + } + }while((byte & 128) != 0); + + if(mosq->in_packet.remaining_length > 0){ + mosq->in_packet.payload = _mosquitto_malloc(mosq->in_packet.remaining_length*sizeof(uint8_t)); + if(!mosq->in_packet.payload) return MOSQ_ERR_NOMEM; + mosq->in_packet.to_process = mosq->in_packet.remaining_length; + } + mosq->in_packet.have_remaining = 1; + } + while(mosq->in_packet.to_process>0){ + read_length = _mosquitto_net_read(mosq, &(mosq->in_packet.payload[mosq->in_packet.pos]), mosq->in_packet.to_process); + if(read_length > 0){ +#if defined(WITH_BROKER) && defined(WITH_SYS_TREE) + g_bytes_received += read_length; +#endif + mosq->in_packet.to_process -= read_length; + mosq->in_packet.pos += read_length; + }else{ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno == EAGAIN || errno == COMPAT_EWOULDBLOCK){ + if(mosq->in_packet.to_process > 1000){ + /* Update last_msg_in time if more than 1000 bytes left to + * receive. Helps when receiving large messages. + * This is an arbitrary limit, but with some consideration. + * If a client can't send 1000 bytes in a second it + * probably shouldn't be using a 1 second keep alive. */ + pthread_mutex_lock(&mosq->msgtime_mutex); + mosq->last_msg_in = mosquitto_time(); + pthread_mutex_unlock(&mosq->msgtime_mutex); + } + return MOSQ_ERR_SUCCESS; + }else{ + switch(errno){ + case COMPAT_ECONNRESET: + return MOSQ_ERR_CONN_LOST; + default: + return MOSQ_ERR_ERRNO; + } + } + } + } + + /* All data for this packet is read. */ + mosq->in_packet.pos = 0; +#ifdef WITH_BROKER +# ifdef WITH_SYS_TREE + g_msgs_received++; + if(((mosq->in_packet.command)&0xF5) == PUBLISH){ + g_pub_msgs_received++; + } +# endif + rc = mqtt3_packet_handle(db, mosq); +#else + rc = _mosquitto_packet_handle(mosq); +#endif + + /* Free data and reset values */ + _mosquitto_packet_cleanup(&mosq->in_packet); + + pthread_mutex_lock(&mosq->msgtime_mutex); + mosq->last_msg_in = mosquitto_time(); + pthread_mutex_unlock(&mosq->msgtime_mutex); + return rc; +} + +int _mosquitto_socket_nonblock(int sock) +{ +#ifndef WIN32 + int opt; + /* Set non-blocking */ + opt = fcntl(sock, F_GETFL, 0); + if(opt == -1){ + COMPAT_CLOSE(sock); + return 1; + } + if(fcntl(sock, F_SETFL, opt | O_NONBLOCK) == -1){ + /* If either fcntl fails, don't want to allow this client to connect. */ + COMPAT_CLOSE(sock); + return 1; + } +#else + opt = 1; + if(ioctlsocket(sock, FIONBIO, &opt)){ + COMPAT_CLOSE(sock); + return 1; + } +#endif + return 0; +} + + +#ifndef WITH_BROKER +int _mosquitto_socketpair(int *pairR, int *pairW) +{ +#ifdef WIN32 + int family[2] = {AF_INET, AF_INET6}; + int i; + struct sockaddr_storage ss; + struct sockaddr_in *sa = (struct sockaddr_in *)&ss; + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&ss; + socklen_t ss_len; + int spR, spW; + + int listensock; + + *pairR = -1; + *pairW = -1; + + for(i=0; i<2; i++){ + memset(&ss, 0, sizeof(ss)); + if(family[i] == AF_INET){ + sa->sin_family = family[i]; + sa->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sa->sin_port = 0; + ss_len = sizeof(struct sockaddr_in); + }else if(family[i] == AF_INET6){ + sa6->sin6_family = family[i]; + sa6->sin6_addr = in6addr_loopback; + sa6->sin6_port = 0; + ss_len = sizeof(struct sockaddr_in6); + }else{ + return MOSQ_ERR_INVAL; + } + + listensock = socket(family[i], SOCK_STREAM, IPPROTO_TCP); + if(listensock == -1){ + continue; + } + + if(bind(listensock, (struct sockaddr *)&ss, ss_len) == -1){ + COMPAT_CLOSE(listensock); + continue; + } + + if(listen(listensock, 1) == -1){ + COMPAT_CLOSE(listensock); + continue; + } + memset(&ss, 0, sizeof(ss)); + ss_len = sizeof(ss); + if(getsockname(listensock, (struct sockaddr *)&ss, &ss_len) < 0){ + COMPAT_CLOSE(listensock); + continue; + } + + if(_mosquitto_socket_nonblock(listensock)){ + continue; + } + + if(family[i] == AF_INET){ + sa->sin_family = family[i]; + sa->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + ss_len = sizeof(struct sockaddr_in); + }else if(family[i] == AF_INET6){ + sa6->sin6_family = family[i]; + sa6->sin6_addr = in6addr_loopback; + ss_len = sizeof(struct sockaddr_in6); + } + + spR = socket(family[i], SOCK_STREAM, IPPROTO_TCP); + if(spR == -1){ + COMPAT_CLOSE(listensock); + continue; + } + if(_mosquitto_socket_nonblock(spR)){ + COMPAT_CLOSE(listensock); + continue; + } + if(connect(spR, (struct sockaddr *)&ss, ss_len) < 0){ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno != EINPROGRESS && errno != COMPAT_EWOULDBLOCK){ + COMPAT_CLOSE(spR); + COMPAT_CLOSE(listensock); + continue; + } + } + spW = accept(listensock, NULL, 0); + if(spW == -1){ +#ifdef WIN32 + errno = WSAGetLastError(); +#endif + if(errno != EINPROGRESS && errno != COMPAT_EWOULDBLOCK){ + COMPAT_CLOSE(spR); + COMPAT_CLOSE(listensock); + continue; + } + } + + if(_mosquitto_socket_nonblock(spW)){ + COMPAT_CLOSE(spR); + COMPAT_CLOSE(listensock); + continue; + } + COMPAT_CLOSE(listensock); + + *pairR = spR; + *pairW = spW; + return MOSQ_ERR_SUCCESS; + } + return MOSQ_ERR_UNKNOWN; +#else + int sv[2]; + + if(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1){ + return MOSQ_ERR_ERRNO; + } + if(_mosquitto_socket_nonblock(sv[0])){ + COMPAT_CLOSE(sv[0]); + COMPAT_CLOSE(sv[1]); + return MOSQ_ERR_ERRNO; + } + if(_mosquitto_socket_nonblock(sv[1])){ + COMPAT_CLOSE(sv[0]); + COMPAT_CLOSE(sv[1]); + return MOSQ_ERR_ERRNO; + } + *pairR = sv[0]; + *pairW = sv[1]; + return MOSQ_ERR_SUCCESS; +#endif +} +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.h new file mode 100644 index 0000000..96f89a1 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/net_mosq.h @@ -0,0 +1,104 @@ +/* +Copyright (c) 2010,2011,2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _NET_MOSQ_H_ +#define _NET_MOSQ_H_ + +#ifndef WIN32 +#include +#else +#include +typedef int ssize_t; +#endif + +#include "mosquitto_internal.h" +#include "mosquitto.h" + +#ifdef WITH_BROKER +struct mosquitto_db; +#endif + +#ifdef WIN32 +# define COMPAT_CLOSE(a) closesocket(a) +# define COMPAT_ECONNRESET WSAECONNRESET +# define COMPAT_EWOULDBLOCK WSAEWOULDBLOCK +#else +# define COMPAT_CLOSE(a) close(a) +# define COMPAT_ECONNRESET ECONNRESET +# define COMPAT_EWOULDBLOCK EWOULDBLOCK +#endif + +#ifndef WIN32 +#else +#endif + +/* For when not using winsock libraries. */ +#ifndef INVALID_SOCKET +#define INVALID_SOCKET -1 +#endif + +/* Macros for accessing the MSB and LSB of a uint16_t */ +#define MOSQ_MSB(A) (uint8_t)((A & 0xFF00) >> 8) +#define MOSQ_LSB(A) (uint8_t)(A & 0x00FF) + +void _mosquitto_net_init(void); +void _mosquitto_net_cleanup(void); + +void _mosquitto_packet_cleanup(struct _mosquitto_packet *packet); +int _mosquitto_packet_queue(struct mosquitto *mosq, struct _mosquitto_packet *packet); +int _mosquitto_socket_connect(struct mosquitto *mosq, const char *host, uint16_t port, const char *bind_address, bool blocking); +int _mosquitto_socket_close(struct mosquitto *mosq); +int _mosquitto_try_connect(const char *host, uint16_t port, int *sock, const char *bind_address, bool blocking); +int _mosquitto_socket_nonblock(int sock); +int _mosquitto_socketpair(int *sp1, int *sp2); + +int _mosquitto_read_byte(struct _mosquitto_packet *packet, uint8_t *byte); +int _mosquitto_read_bytes(struct _mosquitto_packet *packet, void *bytes, uint32_t count); +int _mosquitto_read_string(struct _mosquitto_packet *packet, char **str); +int _mosquitto_read_uint16(struct _mosquitto_packet *packet, uint16_t *word); + +void _mosquitto_write_byte(struct _mosquitto_packet *packet, uint8_t byte); +void _mosquitto_write_bytes(struct _mosquitto_packet *packet, const void *bytes, uint32_t count); +void _mosquitto_write_string(struct _mosquitto_packet *packet, const char *str, uint16_t length); +void _mosquitto_write_uint16(struct _mosquitto_packet *packet, uint16_t word); + +ssize_t _mosquitto_net_read(struct mosquitto *mosq, void *buf, size_t count); +ssize_t _mosquitto_net_write(struct mosquitto *mosq, void *buf, size_t count); + +int _mosquitto_packet_write(struct mosquitto *mosq); +#ifdef WITH_BROKER +int _mosquitto_packet_read(struct mosquitto_db *db, struct mosquitto *mosq); +#else +int _mosquitto_packet_read(struct mosquitto *mosq); +#endif + +#ifdef WITH_TLS +int _mosquitto_socket_apply_tls(struct mosquitto *mosq); +#endif + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/python/Makefile b/service/protocol-plugin/plugins/mqtt-light/lib/python/Makefile new file mode 100644 index 0000000..ed5b926 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/python/Makefile @@ -0,0 +1,25 @@ +include ../config.mk + +# Set DESTDIR if it isn't given +DESTDIR?=/ + +.PHONY : all clean install + +ifeq ($(WITH_PYTHON),yes) +all : mosquitto.pyc +else +all : +endif + +ifeq ($(WITH_PYTHON),yes) +install : all + python ./setup.py install --prefix=${prefix} --root=${DESTDIR} +else +install : +endif + +mosquitto.pyc : mosquitto.py + python ./setup.py build + +clean : + -rm -rf build mosquitto.pyc __pycache__ diff --git a/service/protocol-plugin/plugins/mqtt/lib/python/build/lib.linux-i686-2.7/mosquitto.py b/service/protocol-plugin/plugins/mqtt-light/lib/python/mosquitto.py similarity index 100% rename from service/protocol-plugin/plugins/mqtt/lib/python/build/lib.linux-i686-2.7/mosquitto.py rename to service/protocol-plugin/plugins/mqtt-light/lib/python/mosquitto.py diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/python/setup.py b/service/protocol-plugin/plugins/mqtt-light/lib/python/setup.py new file mode 100644 index 0000000..59eb7c1 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/python/setup.py @@ -0,0 +1,28 @@ +from sys import version + +from distutils.core import setup +setup(name='mosquitto', + version='1.3.1', + description='MQTT version 3.1 client class', + author='Roger Light', + author_email='roger@atchoo.org', + url='http://mosquitto.org/', + download_url='http://mosquitto.org/files/', + license='BSD License', + py_modules=['mosquitto'], + + classifiers=[ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: BSD License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Topic :: Communications', + 'Topic :: Internet', + ] + ) diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/python/sub.py b/service/protocol-plugin/plugins/mqtt-light/lib/python/sub.py new file mode 100644 index 0000000..5805693 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/python/sub.py @@ -0,0 +1,66 @@ +#!/usr/bin/python + +# Copyright (c) 2010,2011 Roger Light +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of mosquitto nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import mosquitto + +def on_connect(mosq, obj, rc): + mosq.subscribe("$SYS/#", 0) + print("rc: "+str(rc)) + +def on_message(mosq, obj, msg): + print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) + +def on_publish(mosq, obj, mid): + print("mid: "+str(mid)) + +def on_subscribe(mosq, obj, mid, granted_qos): + print("Subscribed: "+str(mid)+" "+str(granted_qos)) + +def on_log(mosq, obj, level, string): + print(string) + +# If you want to use a specific client id, use +# mqttc = mosquitto.Mosquitto("client-id") +# but note that the client id must be unique on the broker. Leaving the client +# id parameter empty will generate a random id for you. +mqttc = mosquitto.Mosquitto() +mqttc.on_message = on_message +mqttc.on_connect = on_connect +mqttc.on_publish = on_publish +mqttc.on_subscribe = on_subscribe +# Uncomment to enable debug messages +#mqttc.on_log = on_log +mqttc.connect("test.mosquitto.org", 1883, 60) + +#mqttc.subscribe("string", 0) +#mqttc.subscribe(("tuple", 1)) +#mqttc.subscribe([("list0", 0), ("list1", 1)]) + +mqttc.loop_forever() + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/read_handle.c b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle.c new file mode 100644 index 0000000..536fe7f --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle.c @@ -0,0 +1,168 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "mosquitto.h" +#include "logging_mosq.h" +#include "memory_mosq.h" +#include "messages_mosq.h" +#include "mqtt3_protocol.h" +#include "net_mosq.h" +#include "read_handle.h" +#include "send_mosq.h" +#include "time_mosq.h" +#include "util_mosq.h" + +int _mosquitto_packet_handle(struct mosquitto *mosq) +{ + assert(mosq); + + switch((mosq->in_packet.command)&0xF0){ + case PINGREQ: + return _mosquitto_handle_pingreq(mosq); + case PINGRESP: + return _mosquitto_handle_pingresp(mosq); + case PUBACK: + return _mosquitto_handle_pubackcomp(mosq, "PUBACK"); + case PUBCOMP: + return _mosquitto_handle_pubackcomp(mosq, "PUBCOMP"); + case PUBLISH: + return _mosquitto_handle_publish(mosq); + case PUBREC: + return _mosquitto_handle_pubrec(mosq); + case PUBREL: + return _mosquitto_handle_pubrel(NULL, mosq); + case CONNACK: + return _mosquitto_handle_connack(mosq); + case SUBACK: + return _mosquitto_handle_suback(mosq); + case UNSUBACK: + return _mosquitto_handle_unsuback(mosq); + default: + /* If we don't recognise the command, return an error straight away. */ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: Unrecognised command %d\n", (mosq->in_packet.command)&0xF0); + return MOSQ_ERR_PROTOCOL; + } +} + +int _mosquitto_handle_publish(struct mosquitto *mosq) +{ + uint8_t header; + struct mosquitto_message_all *message; + int rc = 0; + uint16_t mid; + + assert(mosq); + + message = _mosquitto_calloc(1, sizeof(struct mosquitto_message_all)); + if(!message) return MOSQ_ERR_NOMEM; + + header = mosq->in_packet.command; + + message->dup = (header & 0x08)>>3; + message->msg.qos = (header & 0x06)>>1; + message->msg.retain = (header & 0x01); + + rc = _mosquitto_read_string(&mosq->in_packet, &message->msg.topic); + if(rc){ + _mosquitto_message_cleanup(&message); + return rc; + } + if(!strlen(message->msg.topic)){ + _mosquitto_message_cleanup(&message); + return MOSQ_ERR_PROTOCOL; + } + + if(message->msg.qos > 0){ + rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); + if(rc){ + _mosquitto_message_cleanup(&message); + return rc; + } + message->msg.mid = (int)mid; + } + + message->msg.payloadlen = mosq->in_packet.remaining_length - mosq->in_packet.pos; + if(message->msg.payloadlen){ + message->msg.payload = _mosquitto_calloc(message->msg.payloadlen+1, sizeof(uint8_t)); + if(!message->msg.payload){ + _mosquitto_message_cleanup(&message); + return MOSQ_ERR_NOMEM; + } + rc = _mosquitto_read_bytes(&mosq->in_packet, message->msg.payload, message->msg.payloadlen); + if(rc){ + _mosquitto_message_cleanup(&message); + return rc; + } + } + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, + "Client %s received PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", + mosq->id, message->dup, message->msg.qos, message->msg.retain, + message->msg.mid, message->msg.topic, + (long)message->msg.payloadlen); + + message->timestamp = mosquitto_time(); + switch(message->msg.qos){ + case 0: + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_message){ + mosq->in_callback = true; + mosq->on_message(mosq, mosq->userdata, &message->msg); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + _mosquitto_message_cleanup(&message); + return MOSQ_ERR_SUCCESS; + case 1: + rc = _mosquitto_send_puback(mosq, message->msg.mid); + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_message){ + mosq->in_callback = true; + mosq->on_message(mosq, mosq->userdata, &message->msg); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + _mosquitto_message_cleanup(&message); + return rc; + case 2: + rc = _mosquitto_send_pubrec(mosq, message->msg.mid); + pthread_mutex_lock(&mosq->in_message_mutex); + message->state = mosq_ms_wait_for_pubrel; + _mosquitto_message_queue(mosq, message, mosq_md_in); + pthread_mutex_unlock(&mosq->in_message_mutex); + return rc; + default: + _mosquitto_message_cleanup(&message); + return MOSQ_ERR_PROTOCOL; + } +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/read_handle.h b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle.h new file mode 100644 index 0000000..698e862 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle.h @@ -0,0 +1,47 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _READ_HANDLE_H_ +#define _READ_HANDLE_H_ + +#include "mosquitto.h" +struct mosquitto_db; + +int _mosquitto_packet_handle(struct mosquitto *mosq); +int _mosquitto_handle_connack(struct mosquitto *mosq); +int _mosquitto_handle_pingreq(struct mosquitto *mosq); +int _mosquitto_handle_pingresp(struct mosquitto *mosq); +int _mosquitto_handle_pubackcomp(struct mosquitto *mosq, const char *type); +int _mosquitto_handle_publish(struct mosquitto *mosq); +int _mosquitto_handle_pubrec(struct mosquitto *mosq); +int _mosquitto_handle_pubrel(struct mosquitto_db *db, struct mosquitto *mosq); +int _mosquitto_handle_suback(struct mosquitto *mosq); +int _mosquitto_handle_unsuback(struct mosquitto *mosq); + + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/read_handle_client.c b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle_client.c new file mode 100644 index 0000000..9ebedd3 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle_client.c @@ -0,0 +1,76 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include + +#include "mosquitto.h" +#include "logging_mosq.h" +#include "memory_mosq.h" +#include "net_mosq.h" +#include "read_handle.h" + +int _mosquitto_handle_connack(struct mosquitto *mosq) +{ + uint8_t byte; + uint8_t result; + int rc; + + assert(mosq); +#ifdef WITH_STRICT_PROTOCOL + if(mosq->in_packet.remaining_length != 2){ + return MOSQ_ERR_PROTOCOL; + } +#endif + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received CONNACK", mosq->id); + rc = _mosquitto_read_byte(&mosq->in_packet, &byte); // Reserved byte, not used + if(rc) return rc; + rc = _mosquitto_read_byte(&mosq->in_packet, &result); + if(rc) return rc; + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_connect){ + mosq->in_callback = true; + mosq->on_connect(mosq, mosq->userdata, result); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + switch(result){ + case 0: + mosq->state = mosq_cs_connected; + return MOSQ_ERR_SUCCESS; + case 1: + case 2: + case 3: + case 4: + case 5: + return MOSQ_ERR_CONN_REFUSED; + default: + return MOSQ_ERR_PROTOCOL; + } +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/read_handle_shared.c b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle_shared.c new file mode 100644 index 0000000..103d655 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/read_handle_shared.c @@ -0,0 +1,271 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "mosquitto.h" +#include "logging_mosq.h" +#include "memory_mosq.h" +#include "messages_mosq.h" +#include "mqtt3_protocol.h" +#include "net_mosq.h" +#include "read_handle.h" +#include "send_mosq.h" +#include "util_mosq.h" +#ifdef WITH_BROKER +#include "mosquitto_broker.h" +#endif + +int _mosquitto_handle_pingreq(struct mosquitto *mosq) +{ + assert(mosq); +#ifdef WITH_STRICT_PROTOCOL + if(mosq->in_packet.remaining_length != 0){ + return MOSQ_ERR_PROTOCOL; + } +#endif +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGREQ from %s", mosq->id); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGREQ", mosq->id); +#endif + return _mosquitto_send_pingresp(mosq); +} + +int _mosquitto_handle_pingresp(struct mosquitto *mosq) +{ + assert(mosq); +#ifdef WITH_STRICT_PROTOCOL + if(mosq->in_packet.remaining_length != 0){ + return MOSQ_ERR_PROTOCOL; + } +#endif + mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */ +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", mosq->id); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGRESP", mosq->id); +#endif + return MOSQ_ERR_SUCCESS; +} + +int _mosquitto_handle_pubackcomp(struct mosquitto *mosq, const char *type) +{ + uint16_t mid; + int rc; + + assert(mosq); +#ifdef WITH_STRICT_PROTOCOL + if(mosq->in_packet.remaining_length != 2){ + return MOSQ_ERR_PROTOCOL; + } +#endif + rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); + if(rc) return rc; +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received %s from %s (Mid: %d)", type, mosq->id, mid); + + if(mid){ + rc = mqtt3_db_message_delete(mosq, mid, mosq_md_out); + if(rc) return rc; + } +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received %s (Mid: %d)", mosq->id, type, mid); + + if(!_mosquitto_message_delete(mosq, mid, mosq_md_out)){ + /* Only inform the client the message has been sent once. */ + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_publish){ + mosq->in_callback = true; + mosq->on_publish(mosq, mosq->userdata, mid); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + } +#endif + + return MOSQ_ERR_SUCCESS; +} + +int _mosquitto_handle_pubrec(struct mosquitto *mosq) +{ + uint16_t mid; + int rc; + + assert(mosq); +#ifdef WITH_STRICT_PROTOCOL + if(mosq->in_packet.remaining_length != 2){ + return MOSQ_ERR_PROTOCOL; + } +#endif + rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); + if(rc) return rc; +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREC from %s (Mid: %d)", mosq->id, mid); + + rc = mqtt3_db_message_update(mosq, mid, mosq_md_out, mosq_ms_wait_for_pubcomp); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREC (Mid: %d)", mosq->id, mid); + + rc = _mosquitto_message_out_update(mosq, mid, mosq_ms_wait_for_pubcomp); +#endif + if(rc) return rc; + rc = _mosquitto_send_pubrel(mosq, mid, false); + if(rc) return rc; + + return MOSQ_ERR_SUCCESS; +} + +int _mosquitto_handle_pubrel(struct mosquitto_db *db, struct mosquitto *mosq) +{ + uint16_t mid; +#ifndef WITH_BROKER + struct mosquitto_message_all *message = NULL; +#endif + int rc; + + assert(mosq); +#ifdef WITH_STRICT_PROTOCOL + if(mosq->in_packet.remaining_length != 2){ + return MOSQ_ERR_PROTOCOL; + } +#endif + if(mosq->protocol == mosq_p_mqtt311){ + if((mosq->in_packet.command&0x0F) != 0x02){ + return MOSQ_ERR_PROTOCOL; + } + } + rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); + if(rc) return rc; +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBREL from %s (Mid: %d)", mosq->id, mid); + + if(mqtt3_db_message_release(db, mosq, mid, mosq_md_in)){ + /* Message not found. Still send a PUBCOMP anyway because this could be + * due to a repeated PUBREL after a client has reconnected. */ + } +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PUBREL (Mid: %d)", mosq->id, mid); + + if(!_mosquitto_message_remove(mosq, mid, mosq_md_in, &message)){ + /* Only pass the message on if we have removed it from the queue - this + * prevents multiple callbacks for the same message. */ + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_message){ + mosq->in_callback = true; + mosq->on_message(mosq, mosq->userdata, &message->msg); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); + _mosquitto_message_cleanup(&message); + } +#endif + rc = _mosquitto_send_pubcomp(mosq, mid); + if(rc) return rc; + + return MOSQ_ERR_SUCCESS; +} + +int _mosquitto_handle_suback(struct mosquitto *mosq) +{ + uint16_t mid; + uint8_t qos; + int *granted_qos; + int qos_count; + int i = 0; + int rc; + + assert(mosq); +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received SUBACK from %s", mosq->id); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received SUBACK", mosq->id); +#endif + rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); + if(rc) return rc; + + qos_count = mosq->in_packet.remaining_length - mosq->in_packet.pos; + granted_qos = _mosquitto_malloc(qos_count*sizeof(int)); + if(!granted_qos) return MOSQ_ERR_NOMEM; + while(mosq->in_packet.pos < mosq->in_packet.remaining_length){ + rc = _mosquitto_read_byte(&mosq->in_packet, &qos); + if(rc){ + _mosquitto_free(granted_qos); + return rc; + } + granted_qos[i] = (int)qos; + i++; + } +#ifndef WITH_BROKER + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_subscribe){ + mosq->in_callback = true; + mosq->on_subscribe(mosq, mosq->userdata, mid, qos_count, granted_qos); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); +#endif + _mosquitto_free(granted_qos); + + return MOSQ_ERR_SUCCESS; +} + +int _mosquitto_handle_unsuback(struct mosquitto *mosq) +{ + uint16_t mid; + int rc; + + assert(mosq); +#ifdef WITH_STRICT_PROTOCOL + if(mosq->in_packet.remaining_length != 2){ + return MOSQ_ERR_PROTOCOL; + } +#endif +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received UNSUBACK from %s", mosq->id); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s received UNSUBACK", mosq->id); +#endif + rc = _mosquitto_read_uint16(&mosq->in_packet, &mid); + if(rc) return rc; +#ifndef WITH_BROKER + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_unsubscribe){ + mosq->in_callback = true; + mosq->on_unsubscribe(mosq, mosq->userdata, mid); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); +#endif + + return MOSQ_ERR_SUCCESS; +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/send_client_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/send_client_mosq.c new file mode 100644 index 0000000..66ea655 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/send_client_mosq.c @@ -0,0 +1,227 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#include "mosquitto.h" +#include "logging_mosq.h" +#include "memory_mosq.h" +#include "mqtt3_protocol.h" +#include "net_mosq.h" +#include "send_mosq.h" +#include "util_mosq.h" + +#ifdef WITH_BROKER +#include "mosquitto_broker.h" +#endif + +int _mosquitto_send_connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session) +{ + struct _mosquitto_packet *packet = NULL; + int payloadlen; + uint8_t will = 0; + uint8_t byte; + int rc; + uint8_t version = PROTOCOL_VERSION_v31; + + assert(mosq); + assert(mosq->id); + + packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); + if(!packet) return MOSQ_ERR_NOMEM; + + payloadlen = 2+strlen(mosq->id); + if(mosq->will){ + will = 1; + assert(mosq->will->topic); + + payloadlen += 2+strlen(mosq->will->topic) + 2+mosq->will->payloadlen; + } + if(mosq->username){ + payloadlen += 2+strlen(mosq->username); + if(mosq->password){ + payloadlen += 2+strlen(mosq->password); + } + } + + packet->command = CONNECT; + packet->remaining_length = 12+payloadlen; + rc = _mosquitto_packet_alloc(packet); + if(rc){ + _mosquitto_free(packet); + return rc; + } + + /* Variable header */ + _mosquitto_write_string(packet, PROTOCOL_NAME_v31, strlen(PROTOCOL_NAME_v31)); +#if defined(WITH_BROKER) && defined(WITH_BRIDGE) + if(mosq->bridge && mosq->bridge->try_private && mosq->bridge->try_private_accepted){ + version |= 0x80; + }else{ + } +#endif + _mosquitto_write_byte(packet, version); + byte = (clean_session&0x1)<<1; + if(will){ + byte = byte | ((mosq->will->retain&0x1)<<5) | ((mosq->will->qos&0x3)<<3) | ((will&0x1)<<2); + } + if(mosq->username){ + byte = byte | 0x1<<7; + if(mosq->password){ + byte = byte | 0x1<<6; + } + } + _mosquitto_write_byte(packet, byte); + _mosquitto_write_uint16(packet, keepalive); + + /* Payload */ + _mosquitto_write_string(packet, mosq->id, strlen(mosq->id)); + if(will){ + _mosquitto_write_string(packet, mosq->will->topic, strlen(mosq->will->topic)); + _mosquitto_write_string(packet, (const char *)mosq->will->payload, mosq->will->payloadlen); + } + if(mosq->username){ + _mosquitto_write_string(packet, mosq->username, strlen(mosq->username)); + if(mosq->password){ + _mosquitto_write_string(packet, mosq->password, strlen(mosq->password)); + } + } + + mosq->keepalive = keepalive; +#ifdef WITH_BROKER +# ifdef WITH_BRIDGE + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending CONNECT", mosq->id); +# endif +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending CONNECT", mosq->id); +#endif + return _mosquitto_packet_queue(mosq, packet); +} + +int _mosquitto_send_disconnect(struct mosquitto *mosq) +{ + assert(mosq); +#ifdef WITH_BROKER +# ifdef WITH_BRIDGE + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending DISCONNECT", mosq->id); +# endif +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending DISCONNECT", mosq->id); +#endif + return _mosquitto_send_simple_command(mosq, DISCONNECT); +} + +int _mosquitto_send_subscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic, uint8_t topic_qos) +{ + /* FIXME - only deals with a single topic */ + struct _mosquitto_packet *packet = NULL; + uint32_t packetlen; + uint16_t local_mid; + int rc; + + assert(mosq); + assert(topic); + + packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); + if(!packet) return MOSQ_ERR_NOMEM; + + packetlen = 2 + 2+strlen(topic) + 1; + + packet->command = SUBSCRIBE | (dup<<3) | (1<<1); + packet->remaining_length = packetlen; + rc = _mosquitto_packet_alloc(packet); + if(rc){ + _mosquitto_free(packet); + return rc; + } + + /* Variable header */ + local_mid = _mosquitto_mid_generate(mosq); + if(mid) *mid = (int)local_mid; + _mosquitto_write_uint16(packet, local_mid); + + /* Payload */ + _mosquitto_write_string(packet, topic, strlen(topic)); + _mosquitto_write_byte(packet, topic_qos); + +#ifdef WITH_BROKER +# ifdef WITH_BRIDGE + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending SUBSCRIBE (Mid: %d, Topic: %s, QoS: %d)", mosq->id, local_mid, topic, topic_qos); +# endif +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending SUBSCRIBE (Mid: %d, Topic: %s, QoS: %d)", mosq->id, local_mid, topic, topic_qos); +#endif + + return _mosquitto_packet_queue(mosq, packet); +} + + +int _mosquitto_send_unsubscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic) +{ + /* FIXME - only deals with a single topic */ + struct _mosquitto_packet *packet = NULL; + uint32_t packetlen; + uint16_t local_mid; + int rc; + + assert(mosq); + assert(topic); + + packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); + if(!packet) return MOSQ_ERR_NOMEM; + + packetlen = 2 + 2+strlen(topic); + + packet->command = UNSUBSCRIBE | (dup<<3) | (1<<1); + packet->remaining_length = packetlen; + rc = _mosquitto_packet_alloc(packet); + if(rc){ + _mosquitto_free(packet); + return rc; + } + + /* Variable header */ + local_mid = _mosquitto_mid_generate(mosq); + if(mid) *mid = (int)local_mid; + _mosquitto_write_uint16(packet, local_mid); + + /* Payload */ + _mosquitto_write_string(packet, topic, strlen(topic)); + +#ifdef WITH_BROKER +# ifdef WITH_BRIDGE + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Bridge %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic); +# endif +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending UNSUBSCRIBE (Mid: %d, Topic: %s)", mosq->id, local_mid, topic); +#endif + return _mosquitto_packet_queue(mosq, packet); +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.c new file mode 100644 index 0000000..73ef06f --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.c @@ -0,0 +1,289 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "mosquitto.h" +#include "mosquitto_internal.h" +#include "logging_mosq.h" +#include "mqtt3_protocol.h" +#include "memory_mosq.h" +#include "net_mosq.h" +#include "send_mosq.h" +#include "time_mosq.h" +#include "util_mosq.h" + +#ifdef WITH_BROKER +#include "mosquitto_broker.h" +# ifdef WITH_SYS_TREE +extern uint64_t g_pub_bytes_sent; +# endif +#endif + +int _mosquitto_send_pingreq(struct mosquitto *mosq) +{ + int rc; + assert(mosq); +#ifdef WITH_BROKER + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PINGREQ to %s", mosq->id); +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PINGREQ", mosq->id); +#endif + rc = _mosquitto_send_simple_command(mosq, PINGREQ); + if(rc == MOSQ_ERR_SUCCESS){ + mosq->ping_t = mosquitto_time(); + } + return rc; +} + +int _mosquitto_send_pingresp(struct mosquitto *mosq) +{ +#ifdef WITH_BROKER + if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PINGRESP to %s", mosq->id); +#else + if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PINGRESP", mosq->id); +#endif + return _mosquitto_send_simple_command(mosq, PINGRESP); +} + +int _mosquitto_send_puback(struct mosquitto *mosq, uint16_t mid) +{ +#ifdef WITH_BROKER + if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBACK to %s (Mid: %d)", mosq->id, mid); +#else + if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBACK (Mid: %d)", mosq->id, mid); +#endif + return _mosquitto_send_command_with_mid(mosq, PUBACK, mid, false); +} + +int _mosquitto_send_pubcomp(struct mosquitto *mosq, uint16_t mid) +{ +#ifdef WITH_BROKER + if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBCOMP to %s (Mid: %d)", mosq->id, mid); +#else + if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBCOMP (Mid: %d)", mosq->id, mid); +#endif + return _mosquitto_send_command_with_mid(mosq, PUBCOMP, mid, false); +} + +int _mosquitto_send_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup) +{ +#ifdef WITH_BROKER + size_t len; +#ifdef WITH_BRIDGE + int i; + struct _mqtt3_bridge_topic *cur_topic; + bool match; + int rc; + char *mapped_topic = NULL; + char *topic_temp = NULL; +#endif +#endif + assert(mosq); + assert(topic); + + if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; +#ifdef WITH_BROKER + if(mosq->listener && mosq->listener->mount_point){ + len = strlen(mosq->listener->mount_point); + if(len < strlen(topic)){ + topic += len; + }else{ + /* Invalid topic string. Should never happen, but silently swallow the message anyway. */ + return MOSQ_ERR_SUCCESS; + } + } +#ifdef WITH_BRIDGE + if(mosq->bridge && mosq->bridge->topics && mosq->bridge->topic_remapping){ + for(i=0; ibridge->topic_count; i++){ + cur_topic = &mosq->bridge->topics[i]; + if((cur_topic->direction == bd_both || cur_topic->direction == bd_out) + && (cur_topic->remote_prefix || cur_topic->local_prefix)){ + /* Topic mapping required on this topic if the message matches */ + + rc = mosquitto_topic_matches_sub(cur_topic->local_topic, topic, &match); + if(rc){ + return rc; + } + if(match){ + mapped_topic = _mosquitto_strdup(topic); + if(!mapped_topic) return MOSQ_ERR_NOMEM; + if(cur_topic->local_prefix){ + /* This prefix needs removing. */ + if(!strncmp(cur_topic->local_prefix, mapped_topic, strlen(cur_topic->local_prefix))){ + topic_temp = _mosquitto_strdup(mapped_topic+strlen(cur_topic->local_prefix)); + _mosquitto_free(mapped_topic); + if(!topic_temp){ + return MOSQ_ERR_NOMEM; + } + mapped_topic = topic_temp; + } + } + + if(cur_topic->remote_prefix){ + /* This prefix needs adding. */ + len = strlen(mapped_topic) + strlen(cur_topic->remote_prefix)+1; + topic_temp = _mosquitto_calloc(len+1, sizeof(char)); + if(!topic_temp){ + _mosquitto_free(mapped_topic); + return MOSQ_ERR_NOMEM; + } + snprintf(topic_temp, len, "%s%s", cur_topic->remote_prefix, mapped_topic); + _mosquitto_free(mapped_topic); + mapped_topic = topic_temp; + } + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBLISH to %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, mapped_topic, (long)payloadlen); +#ifdef WITH_SYS_TREE + g_pub_bytes_sent += payloadlen; +#endif + rc = _mosquitto_send_real_publish(mosq, mid, mapped_topic, payloadlen, payload, qos, retain, dup); + _mosquitto_free(mapped_topic); + return rc; + } + } + } + } +#endif + _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBLISH to %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, topic, (long)payloadlen); +# ifdef WITH_SYS_TREE + g_pub_bytes_sent += payloadlen; +# endif +#else + _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBLISH (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", mosq->id, dup, qos, retain, mid, topic, (long)payloadlen); +#endif + + return _mosquitto_send_real_publish(mosq, mid, topic, payloadlen, payload, qos, retain, dup); +} + +int _mosquitto_send_pubrec(struct mosquitto *mosq, uint16_t mid) +{ +#ifdef WITH_BROKER + if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBREC to %s (Mid: %d)", mosq->id, mid); +#else + if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBREC (Mid: %d)", mosq->id, mid); +#endif + return _mosquitto_send_command_with_mid(mosq, PUBREC, mid, false); +} + +int _mosquitto_send_pubrel(struct mosquitto *mosq, uint16_t mid, bool dup) +{ +#ifdef WITH_BROKER + if(mosq) _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Sending PUBREL to %s (Mid: %d)", mosq->id, mid); +#else + if(mosq) _mosquitto_log_printf(mosq, MOSQ_LOG_DEBUG, "Client %s sending PUBREL (Mid: %d)", mosq->id, mid); +#endif + return _mosquitto_send_command_with_mid(mosq, PUBREL|2, mid, dup); +} + +/* For PUBACK, PUBCOMP, PUBREC, and PUBREL */ +int _mosquitto_send_command_with_mid(struct mosquitto *mosq, uint8_t command, uint16_t mid, bool dup) +{ + struct _mosquitto_packet *packet = NULL; + int rc; + + assert(mosq); + packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); + if(!packet) return MOSQ_ERR_NOMEM; + + packet->command = command; + if(dup){ + packet->command |= 8; + } + packet->remaining_length = 2; + rc = _mosquitto_packet_alloc(packet); + if(rc){ + _mosquitto_free(packet); + return rc; + } + + packet->payload[packet->pos+0] = MOSQ_MSB(mid); + packet->payload[packet->pos+1] = MOSQ_LSB(mid); + + return _mosquitto_packet_queue(mosq, packet); +} + +/* For DISCONNECT, PINGREQ and PINGRESP */ +int _mosquitto_send_simple_command(struct mosquitto *mosq, uint8_t command) +{ + struct _mosquitto_packet *packet = NULL; + int rc; + + assert(mosq); + packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); + if(!packet) return MOSQ_ERR_NOMEM; + + packet->command = command; + packet->remaining_length = 0; + + rc = _mosquitto_packet_alloc(packet); + if(rc){ + _mosquitto_free(packet); + return rc; + } + + return _mosquitto_packet_queue(mosq, packet); +} + +int _mosquitto_send_real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup) +{ + struct _mosquitto_packet *packet = NULL; + int packetlen; + int rc; + + assert(mosq); + assert(topic); + + packetlen = 2+strlen(topic) + payloadlen; + if(qos > 0) packetlen += 2; /* For message id */ + packet = _mosquitto_calloc(1, sizeof(struct _mosquitto_packet)); + if(!packet) return MOSQ_ERR_NOMEM; + + packet->mid = mid; + packet->command = PUBLISH | ((dup&0x1)<<3) | (qos<<1) | retain; + packet->remaining_length = packetlen; + rc = _mosquitto_packet_alloc(packet); + if(rc){ + _mosquitto_free(packet); + return rc; + } + /* Variable header (topic string) */ + _mosquitto_write_string(packet, topic, strlen(topic)); + if(qos > 0){ + _mosquitto_write_uint16(packet, mid); + } + + /* Payload */ + if(payloadlen){ + _mosquitto_write_bytes(packet, payload, payloadlen); + } + + return _mosquitto_packet_queue(mosq, packet); +} diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.h new file mode 100644 index 0000000..35e8544 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/send_mosq.h @@ -0,0 +1,50 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _SEND_MOSQ_H_ +#define _SEND_MOSQ_H_ + +#include "mosquitto.h" + +int _mosquitto_send_simple_command(struct mosquitto *mosq, uint8_t command); +int _mosquitto_send_command_with_mid(struct mosquitto *mosq, uint8_t command, uint16_t mid, bool dup); +int _mosquitto_send_real_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup); + +int _mosquitto_send_connect(struct mosquitto *mosq, uint16_t keepalive, bool clean_session); +int _mosquitto_send_disconnect(struct mosquitto *mosq); +int _mosquitto_send_pingreq(struct mosquitto *mosq); +int _mosquitto_send_pingresp(struct mosquitto *mosq); +int _mosquitto_send_puback(struct mosquitto *mosq, uint16_t mid); +int _mosquitto_send_pubcomp(struct mosquitto *mosq, uint16_t mid); +int _mosquitto_send_publish(struct mosquitto *mosq, uint16_t mid, const char *topic, uint32_t payloadlen, const void *payload, int qos, bool retain, bool dup); +int _mosquitto_send_pubrec(struct mosquitto *mosq, uint16_t mid); +int _mosquitto_send_pubrel(struct mosquitto *mosq, uint16_t mid, bool dup); +int _mosquitto_send_subscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic, uint8_t topic_qos); +int _mosquitto_send_unsubscribe(struct mosquitto *mosq, int *mid, bool dup, const char *topic); + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/srv_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/srv_mosq.c new file mode 100644 index 0000000..4e9b2cc --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/srv_mosq.c @@ -0,0 +1,106 @@ +/* +Copyright (c) 2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef WITH_SRV +# include + +# include +# include +# include +#endif + +#include "logging_mosq.h" +#include "memory_mosq.h" +#include "mosquitto_internal.h" +#include "mosquitto.h" + +#ifdef WITH_SRV +static void srv_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) +{ + struct mosquitto *mosq = arg; + struct ares_srv_reply *reply = NULL; + if(status == ARES_SUCCESS){ + status = ares_parse_srv_reply(abuf, alen, &reply); + if(status == ARES_SUCCESS){ + // FIXME - choose which answer to use based on rfc2782 page 3. */ + mosquitto_connect(mosq, reply->host, reply->port, mosq->keepalive); + } + }else{ + _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: SRV lookup failed (%d).", status); + exit(1); + } +} +#endif + +int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address) +{ +#ifdef WITH_SRV + char *h; + int rc; + if(!mosq) return MOSQ_ERR_INVAL; + + rc = ares_init(&mosq->achan); + if(rc != ARES_SUCCESS){ + return MOSQ_ERR_UNKNOWN; + } + + if(!host){ + // get local domain + }else{ +#ifdef WITH_TLS + if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ + h = _mosquitto_malloc(strlen(host) + strlen("_secure-mqtt._tcp.") + 1); + if(!h) return MOSQ_ERR_NOMEM; + sprintf(h, "_secure-mqtt._tcp.%s", host); + }else{ +#endif + h = _mosquitto_malloc(strlen(host) + strlen("_mqtt._tcp.") + 1); + if(!h) return MOSQ_ERR_NOMEM; + sprintf(h, "_mqtt._tcp.%s", host); +#ifdef WITH_TLS + } +#endif + ares_search(mosq->achan, h, ns_c_in, ns_t_srv, srv_callback, mosq); + _mosquitto_free(h); + } + + pthread_mutex_lock(&mosq->state_mutex); + mosq->state = mosq_cs_connect_srv; + pthread_mutex_unlock(&mosq->state_mutex); + + mosq->keepalive = keepalive; + + return MOSQ_ERR_SUCCESS; + +#else + return MOSQ_ERR_NOT_SUPPORTED; +#endif +} + + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/thread_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/thread_mosq.c new file mode 100644 index 0000000..b9f2a7b --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/thread_mosq.c @@ -0,0 +1,114 @@ +/* +Copyright (c) 2011-2014 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "config.h" + +#ifndef WIN32 +#include +#endif + +#include "mosquitto_internal.h" +#include "net_mosq.h" + +void *_mosquitto_thread_main(void *obj); + +int mosquitto_loop_start(struct mosquitto *mosq) +{ +#ifdef WITH_THREADING + if(!mosq || mosq->threaded) return MOSQ_ERR_INVAL; + + mosq->threaded = true; + pthread_create(&mosq->thread_id, NULL, _mosquitto_thread_main, mosq); + return MOSQ_ERR_SUCCESS; +#else + return MOSQ_ERR_NOT_SUPPORTED; +#endif +} + +int mosquitto_loop_stop(struct mosquitto *mosq, bool force) +{ +#ifdef WITH_THREADING +# ifndef WITH_BROKER + char sockpair_data = 0; +# endif + + if(!mosq || !mosq->threaded) return MOSQ_ERR_INVAL; + + + /* Write a single byte to sockpairW (connected to sockpairR) to break out + * of select() if in threaded mode. */ + if(mosq->sockpairW != INVALID_SOCKET){ +#ifndef WIN32 + if(write(mosq->sockpairW, &sockpair_data, 1)){ + } +#else + send(mosq->sockpairW, &sockpair_data, 1, 0); +#endif + } + + if(force){ + pthread_cancel(mosq->thread_id); + } + pthread_join(mosq->thread_id, NULL); + mosq->thread_id = pthread_self(); + mosq->threaded = false; + + return MOSQ_ERR_SUCCESS; +#else + return MOSQ_ERR_NOT_SUPPORTED; +#endif +} + +#ifdef WITH_THREADING +void *_mosquitto_thread_main(void *obj) +{ + struct mosquitto *mosq = obj; + + if(!mosq) return NULL; + + pthread_mutex_lock(&mosq->state_mutex); + if(mosq->state == mosq_cs_connect_async){ + pthread_mutex_unlock(&mosq->state_mutex); + mosquitto_reconnect(mosq); + }else{ + pthread_mutex_unlock(&mosq->state_mutex); + } + + if(!mosq->keepalive){ + /* Sleep for a day if keepalive disabled. */ + mosquitto_loop_forever(mosq, mosq->keepalive*1000*86400, 1); + }else{ + /* Sleep for our keepalive value. publish() etc. will wake us up. */ + mosquitto_loop_forever(mosq, mosq->keepalive*1000, 1); + } + + return obj; +} +#endif + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.c new file mode 100644 index 0000000..9d2e499 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.c @@ -0,0 +1,95 @@ +/* +Copyright (c) 2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef __APPLE__ +#include +#include +#endif + +#ifdef WIN32 +# define _WIN32_WINNT _WIN32_WINNT_VISTA +# include +#else +# include +#endif +#include + +#include "mosquitto.h" +#include "time_mosq.h" + +#ifdef WIN32 +static bool tick64 = false; + +void _windows_time_version_check(void) +{ + OSVERSIONINFO vi; + + tick64 = false; + + memset(&vi, 0, sizeof(OSVERSIONINFO)); + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if(GetVersionEx(&vi)){ + if(vi.dwMajorVersion > 5){ + tick64 = true; + } + } +} +#endif + +time_t mosquitto_time(void) +{ +#ifdef WIN32 + if(tick64){ + return GetTickCount64()/1000; + }else{ + return GetTickCount()/1000; /* FIXME - need to deal with overflow. */ + } +#elif _POSIX_TIMERS>0 && defined(_POSIX_MONOTONIC_CLOCK) + struct timespec tp; + + clock_gettime(CLOCK_MONOTONIC, &tp); + return tp.tv_sec; +#elif defined(__APPLE__) + static mach_timebase_info_data_t tb; + uint64_t ticks; + uint64_t sec; + + ticks = mach_absolute_time(); + + if(tb.denom == 0){ + mach_timebase_info(&tb); + } + sec = ticks*tb.numer/tb.denom/1000000000; + + return (time_t)sec; +#else + return time(NULL); +#endif +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.h new file mode 100644 index 0000000..31a81a1 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/time_mosq.h @@ -0,0 +1,35 @@ +/* +Copyright (c) 2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _TIME_MOSQ_H_ +#define _TIME_MOSQ_H_ + +time_t mosquitto_time(void); + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.c new file mode 100644 index 0000000..362c015 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.c @@ -0,0 +1,147 @@ +/* +Copyright (c) 2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef WITH_TLS + +#ifdef WIN32 +# include +# include +#else +# include +#endif + +#include +#include +#include +#include + +#ifdef WITH_BROKER +# include "mosquitto_broker.h" +#endif +#include "mosquitto_internal.h" +#include "tls_mosq.h" + +extern int tls_ex_index_mosq; + +int _mosquitto_server_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx) +{ + /* Preverify should have already checked expiry, revocation. + * We need to verify the hostname. */ + struct mosquitto *mosq; + SSL *ssl; + X509 *cert; + + /* Always reject if preverify_ok has failed. */ + if(!preverify_ok) return 0; + + ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + mosq = SSL_get_ex_data(ssl, tls_ex_index_mosq); + if(!mosq) return 0; + + if(mosq->tls_insecure == false){ + if(X509_STORE_CTX_get_error_depth(ctx) == 0){ + /* FIXME - use X509_check_host() etc. for sufficiently new openssl (>=1.1.x) */ + cert = X509_STORE_CTX_get_current_cert(ctx); + /* This is the peer certificate, all others are upwards in the chain. */ +#if defined(WITH_BROKER) + return _mosquitto_verify_certificate_hostname(cert, mosq->bridge->addresses[mosq->bridge->cur_address].address); +#else + return _mosquitto_verify_certificate_hostname(cert, mosq->host); +#endif + }else{ + return preverify_ok; + } + }else{ + return preverify_ok; + } +} + +/* This code is based heavily on the example provided in "Secure Programming + * Cookbook for C and C++". + */ +int _mosquitto_verify_certificate_hostname(X509 *cert, const char *hostname) +{ + int i; + char name[256]; + X509_NAME *subj; + bool have_san_dns = false; + STACK_OF(GENERAL_NAME) *san; + const GENERAL_NAME *nval; + const unsigned char *data; + unsigned char ipv6_addr[16]; + unsigned char ipv4_addr[4]; + int ipv6_ok; + int ipv4_ok; + +#ifdef WIN32 + ipv6_ok = InetPton(AF_INET6, hostname, &ipv6_addr); + ipv4_ok = InetPton(AF_INET, hostname, &ipv4_addr); +#else + ipv6_ok = inet_pton(AF_INET6, hostname, &ipv6_addr); + ipv4_ok = inet_pton(AF_INET, hostname, &ipv4_addr); +#endif + + san = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); + if(san){ + for(i=0; itype == GEN_DNS){ + data = ASN1_STRING_data(nval->d.dNSName); + if(data && !strcasecmp((char *)data, hostname)){ + return 1; + } + have_san_dns = true; + }else if(nval->type == GEN_IPADD){ + data = ASN1_STRING_data(nval->d.iPAddress); + if(nval->d.iPAddress->length == 4 && ipv4_ok){ + if(!memcmp(ipv4_addr, data, 4)){ + return 1; + } + }else if(nval->d.iPAddress->length == 16 && ipv6_ok){ + if(!memcmp(ipv6_addr, data, 16)){ + return 1; + } + } + } + } + if(have_san_dns){ + /* Only check CN if subjectAltName DNS entry does not exist. */ + return 0; + } + } + subj = X509_get_subject_name(cert); + if(X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0){ + name[sizeof(name) - 1] = '\0'; + if (!strcasecmp(name, hostname)) return 1; + } + return 0; +} + +#endif + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.h new file mode 100644 index 0000000..136bd29 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/tls_mosq.h @@ -0,0 +1,49 @@ +/* +Copyright (c) 2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _TLS_MOSQ_H_ +#define _TLS_MOSQ_H_ + +#ifdef WITH_TLS + +#include +#ifdef WITH_TLS_PSK +# if OPENSSL_VERSION_NUMBER >= 0x10000000 +# define REAL_WITH_TLS_PSK +# else +# warning "TLS-PSK not supported, openssl too old." +# endif +#endif + +int _mosquitto_server_certificate_verify(int preverify_ok, X509_STORE_CTX *ctx); +int _mosquitto_verify_certificate_hostname(X509 *cert, const char *hostname); + +#endif /* WITH_TLS */ + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.c new file mode 100644 index 0000000..f50f7e8 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.c @@ -0,0 +1,320 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#ifdef WIN32 +#include +#endif + + +#include "mosquitto.h" +#include "memory_mosq.h" +#include "net_mosq.h" +#include "send_mosq.h" +#include "time_mosq.h" +#include "tls_mosq.h" +#include "util_mosq.h" + +#ifdef WITH_BROKER +#include "mosquitto_broker.h" +#endif + +int _mosquitto_packet_alloc(struct _mosquitto_packet *packet) +{ + uint8_t remaining_bytes[5], byte; + uint32_t remaining_length; + int i; + + assert(packet); + + remaining_length = packet->remaining_length; + packet->payload = NULL; + packet->remaining_count = 0; + do{ + byte = remaining_length % 128; + remaining_length = remaining_length / 128; + /* If there are more digits to encode, set the top bit of this digit */ + if(remaining_length > 0){ + byte = byte | 0x80; + } + remaining_bytes[packet->remaining_count] = byte; + packet->remaining_count++; + }while(remaining_length > 0 && packet->remaining_count < 5); + if(packet->remaining_count == 5) return MOSQ_ERR_PAYLOAD_SIZE; + packet->packet_length = packet->remaining_length + 1 + packet->remaining_count; + packet->payload = _mosquitto_malloc(sizeof(uint8_t)*packet->packet_length); + if(!packet->payload) return MOSQ_ERR_NOMEM; + + packet->payload[0] = packet->command; + for(i=0; iremaining_count; i++){ + packet->payload[i+1] = remaining_bytes[i]; + } + packet->pos = 1 + packet->remaining_count; + + return MOSQ_ERR_SUCCESS; +} + +void _mosquitto_check_keepalive(struct mosquitto *mosq) +{ + time_t last_msg_out; + time_t last_msg_in; + time_t now = mosquitto_time(); +#ifndef WITH_BROKER + int rc; +#endif + + assert(mosq); +#if defined(WITH_BROKER) && defined(WITH_BRIDGE) + /* Check if a lazy bridge should be timed out due to idle. */ + if(mosq->bridge && mosq->bridge->start_type == bst_lazy + && mosq->sock != INVALID_SOCKET + && now - mosq->last_msg_out >= mosq->bridge->idle_timeout){ + + _mosquitto_log_printf(NULL, MOSQ_LOG_NOTICE, "Bridge connection %s has exceeded idle timeout, disconnecting.", mosq->id); + _mosquitto_socket_close(mosq); + return; + } +#endif + pthread_mutex_lock(&mosq->msgtime_mutex); + last_msg_out = mosq->last_msg_out; + last_msg_in = mosq->last_msg_in; + pthread_mutex_unlock(&mosq->msgtime_mutex); + if(mosq->keepalive && mosq->sock != INVALID_SOCKET && + (now - last_msg_out >= mosq->keepalive || now - last_msg_in >= mosq->keepalive)){ + + if(mosq->state == mosq_cs_connected && mosq->ping_t == 0){ + _mosquitto_send_pingreq(mosq); + /* Reset last msg times to give the server time to send a pingresp */ + pthread_mutex_lock(&mosq->msgtime_mutex); + mosq->last_msg_in = now; + mosq->last_msg_out = now; + pthread_mutex_unlock(&mosq->msgtime_mutex); + }else{ +#ifdef WITH_BROKER + if(mosq->listener){ + mosq->listener->client_count--; + assert(mosq->listener->client_count >= 0); + } + mosq->listener = NULL; +#endif + _mosquitto_socket_close(mosq); +#ifndef WITH_BROKER + pthread_mutex_lock(&mosq->state_mutex); + if(mosq->state == mosq_cs_disconnecting){ + rc = MOSQ_ERR_SUCCESS; + }else{ + rc = 1; + } + pthread_mutex_unlock(&mosq->state_mutex); + pthread_mutex_lock(&mosq->callback_mutex); + if(mosq->on_disconnect){ + mosq->in_callback = true; + mosq->on_disconnect(mosq, mosq->userdata, rc); + mosq->in_callback = false; + } + pthread_mutex_unlock(&mosq->callback_mutex); +#endif + } + } +} + +uint16_t _mosquitto_mid_generate(struct mosquitto *mosq) +{ + assert(mosq); + + mosq->last_mid++; + if(mosq->last_mid == 0) mosq->last_mid++; + + return mosq->last_mid; +} + +/* Search for + or # in a topic. Return MOSQ_ERR_INVAL if found. + * Also returns MOSQ_ERR_INVAL if the topic string is too long. + * Returns MOSQ_ERR_SUCCESS if everything is fine. + */ +int _mosquitto_topic_wildcard_len_check(const char *str) +{ + int len = 0; + while(str && str[0]){ + if(str[0] == '+' || str[0] == '#'){ + return MOSQ_ERR_INVAL; + } + len++; + str = &str[1]; + } + if(len > 65535) return MOSQ_ERR_INVAL; + + return MOSQ_ERR_SUCCESS; +} + +/* Search for + or # in a topic, check they aren't in invalid positions such as foo/#/bar, foo/+bar or foo/bar#. + * Return MOSQ_ERR_INVAL if invalid position found. + * Also returns MOSQ_ERR_INVAL if the topic string is too long. + * Returns MOSQ_ERR_SUCCESS if everything is fine. + */ +int _mosquitto_topic_wildcard_pos_check(const char *str) +{ + char c = '\0'; + int len = 0; + while(str && str[0]){ + if(str[0] == '+'){ + if((c != '\0' && c != '/') || (str[1] != '\0' && str[1] != '/')){ + return MOSQ_ERR_INVAL; + } + }else if(str[0] == '#'){ + if((c != '\0' && c != '/') || str[1] != '\0'){ + return MOSQ_ERR_INVAL; + } + } + len++; + c = str[0]; + str = &str[1]; + } + if(len > 65535) return MOSQ_ERR_INVAL; + + return MOSQ_ERR_SUCCESS; +} + +/* Does a topic match a subscription? */ +int mosquitto_topic_matches_sub(const char *sub, const char *topic, bool *result) +{ + int slen, tlen; + int spos, tpos; + bool multilevel_wildcard = false; + + if(!sub || !topic || !result) return MOSQ_ERR_INVAL; + + slen = strlen(sub); + tlen = strlen(topic); + + if(slen && tlen){ + if((sub[0] == '$' && topic[0] != '$') + || (topic[0] == '$' && sub[0] != '$')){ + + *result = false; + return MOSQ_ERR_SUCCESS; + } + } + + spos = 0; + tpos = 0; + + while(spos < slen && tpos < tlen){ + if(sub[spos] == topic[tpos]){ + spos++; + tpos++; + if(spos == slen && tpos == tlen){ + *result = true; + return MOSQ_ERR_SUCCESS; + }else if(tpos == tlen && spos == slen-1 && sub[spos] == '+'){ + spos++; + *result = true; + return MOSQ_ERR_SUCCESS; + } + }else{ + if(sub[spos] == '+'){ + spos++; + while(tpos < tlen && topic[tpos] != '/'){ + tpos++; + } + if(tpos == tlen && spos == slen){ + *result = true; + return MOSQ_ERR_SUCCESS; + } + }else if(sub[spos] == '#'){ + multilevel_wildcard = true; + if(spos+1 != slen){ + *result = false; + return MOSQ_ERR_SUCCESS; + }else{ + *result = true; + return MOSQ_ERR_SUCCESS; + } + }else{ + *result = false; + return MOSQ_ERR_SUCCESS; + } + } + if(tpos == tlen-1){ + /* Check for e.g. foo matching foo/# */ + if(spos == slen-3 + && sub[spos+1] == '/' + && sub[spos+2] == '#'){ + *result = true; + multilevel_wildcard = true; + return MOSQ_ERR_SUCCESS; + } + } + } + if(multilevel_wildcard == false && (tpos < tlen || spos < slen)){ + *result = false; + } + + return MOSQ_ERR_SUCCESS; +} + +#ifdef REAL_WITH_TLS_PSK +int _mosquitto_hex2bin(const char *hex, unsigned char *bin, int bin_max_len) +{ + BIGNUM *bn = NULL; + int len; + + if(BN_hex2bn(&bn, hex) == 0){ + if(bn) BN_free(bn); + return 0; + } + if(BN_num_bytes(bn) > bin_max_len){ + BN_free(bn); + return 0; + } + + len = BN_bn2bin(bn, bin); + BN_free(bn); + return len; +} +#endif + +FILE *_mosquitto_fopen(const char *path, const char *mode) +{ +#ifdef WIN32 + char buf[MAX_PATH]; + int rc; + rc = ExpandEnvironmentStrings(path, buf, MAX_PATH); + if(rc == 0 || rc == MAX_PATH){ + return NULL; + }else{ + return fopen(buf, mode); + } +#else + return fopen(path, mode); +#endif +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.h new file mode 100644 index 0000000..e2afd86 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/util_mosq.h @@ -0,0 +1,48 @@ +/* +Copyright (c) 2009-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _UTIL_MOSQ_H_ +#define _UTIL_MOSQ_H_ + +#include + +#include "tls_mosq.h" +#include "mosquitto.h" + +int _mosquitto_packet_alloc(struct _mosquitto_packet *packet); +void _mosquitto_check_keepalive(struct mosquitto *mosq); +uint16_t _mosquitto_mid_generate(struct mosquitto *mosq); +int _mosquitto_topic_wildcard_len_check(const char *str); +int _mosquitto_topic_wildcard_pos_check(const char *str); +FILE *_mosquitto_fopen(const char *path, const char *mode); + +#ifdef REAL_WITH_TLS_PSK +int _mosquitto_hex2bin(const char *hex, unsigned char *bin, int bin_max_len); +#endif + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.c b/service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.c new file mode 100644 index 0000000..4e93aef --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.c @@ -0,0 +1,130 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#ifndef WIN32 +#include +#include +#else +#include +typedef int ssize_t; +#endif + +#include "mosquitto.h" +#include "mosquitto_internal.h" +#include "logging_mosq.h" +#include "messages_mosq.h" +#include "memory_mosq.h" +#include "mqtt3_protocol.h" +#include "net_mosq.h" +#include "read_handle.h" +#include "send_mosq.h" +#include "util_mosq.h" + +int _mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain) +{ + int rc = MOSQ_ERR_SUCCESS; + + if(!mosq || !topic) return MOSQ_ERR_INVAL; + if(payloadlen < 0 || payloadlen > MQTT_MAX_PAYLOAD) return MOSQ_ERR_PAYLOAD_SIZE; + if(payloadlen > 0 && !payload) return MOSQ_ERR_INVAL; + + if(_mosquitto_topic_wildcard_pos_check(topic)) return MOSQ_ERR_INVAL; + + if(mosq->will){ + if(mosq->will->topic){ + _mosquitto_free(mosq->will->topic); + mosq->will->topic = NULL; + } + if(mosq->will->payload){ + _mosquitto_free(mosq->will->payload); + mosq->will->payload = NULL; + } + _mosquitto_free(mosq->will); + mosq->will = NULL; + } + + mosq->will = _mosquitto_calloc(1, sizeof(struct mosquitto_message)); + if(!mosq->will) return MOSQ_ERR_NOMEM; + mosq->will->topic = _mosquitto_strdup(topic); + if(!mosq->will->topic){ + rc = MOSQ_ERR_NOMEM; + goto cleanup; + } + mosq->will->payloadlen = payloadlen; + if(mosq->will->payloadlen > 0){ + if(!payload){ + rc = MOSQ_ERR_INVAL; + goto cleanup; + } + mosq->will->payload = _mosquitto_malloc(sizeof(char)*mosq->will->payloadlen); + if(!mosq->will->payload){ + rc = MOSQ_ERR_NOMEM; + goto cleanup; + } + + memcpy(mosq->will->payload, payload, payloadlen); + } + mosq->will->qos = qos; + mosq->will->retain = retain; + + return MOSQ_ERR_SUCCESS; + +cleanup: + if(mosq->will){ + if(mosq->will->topic) _mosquitto_free(mosq->will->topic); + if(mosq->will->payload) _mosquitto_free(mosq->will->payload); + } + _mosquitto_free(mosq->will); + mosq->will = NULL; + + return rc; +} + +int _mosquitto_will_clear(struct mosquitto *mosq) +{ + if(!mosq->will) return MOSQ_ERR_SUCCESS; + + if(mosq->will->topic){ + _mosquitto_free(mosq->will->topic); + mosq->will->topic = NULL; + } + if(mosq->will->payload){ + _mosquitto_free(mosq->will->payload); + mosq->will->payload = NULL; + } + _mosquitto_free(mosq->will); + mosq->will = NULL; + + return MOSQ_ERR_SUCCESS; +} + diff --git a/service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.h b/service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.h new file mode 100644 index 0000000..61d0a79 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/lib/will_mosq.h @@ -0,0 +1,39 @@ +/* +Copyright (c) 2010-2013 Roger Light +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of mosquitto nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _WILL_MOSQ_H_ +#define _WILL_MOSQ_H_ + +#include "mosquitto.h" +#include "mosquitto_internal.h" + +int _mosquitto_will_set(struct mosquitto *mosq, const char *topic, int payloadlen, const void *payload, int qos, bool retain); +int _mosquitto_will_clear(struct mosquitto *mosq); + +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/src/lightserver.cpp b/service/protocol-plugin/plugins/mqtt-light/src/lightserver.cpp new file mode 100644 index 0000000..93bad63 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/src/lightserver.cpp @@ -0,0 +1,525 @@ +//****************************************************************** +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +/// +/// This sample provides steps to define an interface for a resource +/// (properties and methods) and host this resource on the server. +/// + +#include +#include +#include + +#include "OCPlatform.h" +#include "OCApi.h" +#include "../lib/mosquitto.h" +#include "lightserver.h" + +#include + +using namespace OC; +using namespace std; +namespace PH = std::placeholders; + +time_t timer; // Define the timer +struct tm *tblock; // Define a structure for time block + +int gObservation = 0; +void *ChangeLightRepresentation (void *param); + +// Specifies where to notify all observers or list of observers +// 0 - notifies all observers +// 1 - notifies list of observers +int isListOfObservers = 0; + +// Forward declaring the entityHandler + +/// This class represents a single resource named 'lightResource'. This resource has +/// two simple properties named 'state' and 'power' + + + +// Forward declaring the entityHandler +// void entityHandler(std::shared_ptr request, +// std::shared_ptr response); + +/// This class represents a single resource named 'lightResource'. This resource has +/// two simple properties named 'state' and 'power' +typedef struct plugin_data_t plugin_data_t; + +struct plugin_data_t +{ + cp_context_t *ctx; + pthread_t m_thread; // 2 + void *str; + bool flag; +}; + + +class LightResource +{ + public: + /// Access this property from a TB client + std::string m_name; + bool m_state; + int m_power; + int m_health; + std::string m_lightUri; + OCResourceHandle m_resourceHandle; + OCRepresentation m_lightRep; + ObservationIds m_interestedObservers; + + public: + /// Constructor + LightResource(): m_name("John's light"), m_state(false), m_power(0), m_lightUri("/a/light") + { + // Initialize representation + m_lightRep.setUri(m_lightUri); + + m_lightRep.setValue("state", m_state); + m_lightRep.setValue("power", m_power); + m_lightRep.setValue("name", m_name); + } + + + /* Note that this does not need to be a member function: for classes you do not have + access to, you can accomplish this with a free function: */ + + /// This function internally calls registerResource API. + void createResource() + { + std::string resourceURI = m_lightUri; // URI of the resource + std::string resourceTypeName = "core.light"; // resource type name. In this case, it is light + std::string resourceInterface = DEFAULT_INTERFACE; // resource interface. + + // OCResourceProperty is defined ocstack.h + uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; + + EntityHandler cb = std::bind(&LightResource::entityHandler, this, PH::_1, PH::_2); + + // This will internally create and register the resource. + OCStackResult result = OCPlatform::registerResource( + m_resourceHandle, resourceURI, resourceTypeName, + resourceInterface, cb, resourceProperty); + + if (OC_STACK_OK != result) + { + cout << "Resource creation was unsuccessful\n"; + } + } + + OCStackResult createResource1() + { + std::string resourceURI = "/a/light1"; // URI of the resource + std::string resourceTypeName = "core.light"; // resource type name. In this case, it is light + std::string resourceInterface = DEFAULT_INTERFACE; // resource interface. + + // OCResourceProperty is defined ocstack.h + uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; + + EntityHandler cb = std::bind(&LightResource::entityHandler, this, PH::_1, PH::_2); + + OCResourceHandle resHandle; + + // This will internally create and register the resource. + OCStackResult result = OCPlatform::registerResource( + resHandle, resourceURI, resourceTypeName, + resourceInterface, cb, resourceProperty); + + if (OC_STACK_OK != result) + { + cout << "Resource creation was unsuccessful\n"; + } + + return result; + } + + OCResourceHandle getHandle() + { + return m_resourceHandle; + } + + // Puts representation. + // Gets values from the representation and + // updates the internal state + void put(OCRepresentation &rep) + { + try + { + if (rep.getValue("state", m_state)) + { + cout << "\t\t\t\t" << "state: " << m_state << endl; + } + else + { + cout << "\t\t\t\t" << "state not found in the representation" << endl; + } + + if (rep.getValue("power", m_power)) + { + cout << "\t\t\t\t" << "power: " << m_power << endl; + } + else + { + cout << "\t\t\t\t" << "power not found in the representation" << endl; + } + } + catch (exception &e) + { + cout << e.what() << endl; + } + + } + + // Post representation. + // Post can create new resource or simply act like put. + // Gets values from the representation and + // updates the internal state + OCRepresentation post(OCRepresentation &rep) + { + static int first = 1; + + // for the first time it tries to create a resource + if (first) + { + first = 0; + + if (OC_STACK_OK == createResource1()) + { + OCRepresentation rep1; + rep1.setValue("createduri", std::string("/a/light1")); + + return rep1; + } + } + + // from second time onwards it just puts + put(rep); + return get(); + } + + + // gets the updated representation. + // Updates the representation with latest internal state before + // sending out. + OCRepresentation get() + { + m_lightRep.setValue("state", m_state); + m_lightRep.setValue("power", m_power); + + return m_lightRep; + } + + + void addType(const std::string &type) const + { + OCStackResult result = OCPlatform::bindTypeToResource(m_resourceHandle, type); + if (OC_STACK_OK != result) + { + cout << "Binding TypeName to Resource was unsuccessful\n"; + } + } + + void addInterface(const std::string &interface) const + { + OCStackResult result = OCPlatform::bindInterfaceToResource(m_resourceHandle, interface); + if (OC_STACK_OK != result) + { + cout << "Binding TypeName to Resource was unsuccessful\n"; + } + } + + private: + // This is just a sample implementation of entity handler. + // Entity handler can be implemented in several ways by the manufacturer + OCEntityHandlerResult entityHandler(std::shared_ptr request, + std::shared_ptr response) + { + OCEntityHandlerResult result = OC_EH_OK; + + cout << "\tIn Server CPP entity handler:\n"; + + if (request) + { + // Get the request type and request flag + std::string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag & RequestHandlerFlag::InitFlag) + { + cout << "\t\trequestFlag : Init\n"; + + // entity handler to perform resource initialization operations + } + if (requestFlag & RequestHandlerFlag::RequestFlag) + { + cout << "\t\trequestFlag : Request === Handle by LightServer\n"; + + // If the request type is GET + if (requestType == "GET") + { + cout << "\t\t\trequestType : GET\n"; + + if (response) + { + // TODO Error Code + response->setErrorCode(200); + + response->setResourceRepresentation(get()); + } + } + else if (requestType == "PUT") + { + cout << "\t\t\trequestType : PUT\n"; + + OCRepresentation rep = request->getResourceRepresentation(); + + // Do related operations related to PUT request + + // Update the lightResource + put(rep); + + if (response) + { + // TODO Error Code + response->setErrorCode(200); + + response->setResourceRepresentation(get()); + } + + } + else if (requestType == "POST") + { + cout << "\t\t\trequestType : POST\n"; + + OCRepresentation rep = request->getResourceRepresentation(); + + // Do related operations related to POST request + + OCRepresentation rep_post = post(rep); + + if (response) + { + // TODO Error Code + response->setErrorCode(200); + + response->setResourceRepresentation(rep_post); + + if (rep_post.hasAttribute("createduri")) + { + result = OC_EH_RESOURCE_CREATED; + + response->setNewResourceUri(rep_post.getValue("createduri")); + } + + } + + // POST request operations + } + else if (requestType == "DELETE") + { + // DELETE request operations + } + } + + if (requestFlag & RequestHandlerFlag::ObserverFlag) + { + ObservationInfo observationInfo = request->getObservationInfo(); + if (ObserveAction::ObserveRegister == observationInfo.action) + { + m_interestedObservers.push_back(observationInfo.obsId); + } + else if (ObserveAction::ObserveUnregister == observationInfo.action) + { + m_interestedObservers.erase(std::remove( + m_interestedObservers.begin(), + m_interestedObservers.end(), + observationInfo.obsId), + m_interestedObservers.end()); + } + + pthread_t threadId; + + cout << "\t\trequestFlag : Observer\n"; + gObservation = 1; + static int startedThread = 0; + + // Observation happens on a different thread in ChangeLightRepresentation function. + // If we have not created the thread already, we will create one here. + if (!startedThread) + { + pthread_create (&threadId, NULL, ChangeLightRepresentation, (void *)this); + startedThread = 1; + } + } + } + else + { + std::cout << "Request invalid" << std::endl; + } + + return result; + } +}; + +// Create the instance of the resource class (in this case instance of class 'LightResource'). +struct mosquitto *myMosquitto; + +// ChangeLightRepresentaion is an observation function, +// which notifies any changes to the resource to stack +// via notifyObservers +void *ChangeLightRepresentation (void *param) +{ + LightResource *lightPtr = (LightResource *) param; + + // This function continuously monitors for the changes + while (1) + { + sleep (5); + + if (gObservation) + { + // If under observation if there are any changes to the light resource + // we call notifyObservors + // + // For demostration we are changing the power value and notifying. + lightPtr->m_power += 10; + + cout << "\nPower updated to : " << lightPtr->m_power << endl; + cout << "Notifying observers with resource handle: " << lightPtr->getHandle() << endl; + + OCStackResult result = OC_STACK_OK; + + if (isListOfObservers) + { + std::shared_ptr resourceResponse(new OCResourceResponse()); + + resourceResponse->setErrorCode(200); + resourceResponse->setResourceRepresentation(lightPtr->get(), DEFAULT_INTERFACE); + + result = OCPlatform::notifyListOfObservers( lightPtr->getHandle(), + lightPtr->m_interestedObservers, + resourceResponse); + } + else + { + result = OCPlatform::notifyAllObservers(lightPtr->getHandle()); + } + + if (OC_STACK_NO_OBSERVERS == result) + { + cout << "No More observers, stopping notifications" << endl; + gObservation = 0; + } + } + } + + return NULL; +} + + + + +//int start_lightserver(void*) // 1 +void *start_lightserver(void *d) // 2 +{ + /*PlatformConfig cfg; + cfg.ipAddress = "192.168.2.5"; + cfg.port = 56832; + cfg.mode = ModeType::Server; + cfg.serviceType = ServiceType::InProc;*/ + // PlatformConfig cfg + // { + // OC::ServiceType::InProc, + // OC::ModeType::Server, + // "192.168.2.5", + // 56832, + // OC::QualityOfService::NonConfirmable + // }; + + // Create PlatformConfig object + + // Create a OCPlatform instance. + // Note: Platform creation is synchronous call. + + // Create PlatformConfig object + PlatformConfig cfg + { + OC::ServiceType::InProc, + OC::ModeType::Server, + "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces + 0, // Uses randomly available port + OC::QualityOfService::LowQos + }; + + OCPlatform::Configure(cfg); + + printf("start_fanserver [mosquitto] Null\n"); + try + { + LightResource myLightResource; + mosquitto_lib_init(); + myMosquitto = mosquitto_new("MQTT plug-in", true, NULL); + if (!myMosquitto) + { + printf("[mosquitto] Null\n"); + printf("You need to install mqtt broker\n"); + } + else + { + printf("Mosquitto is working\n"); + } + + //plugin_data_t *data = (plugin_data_t *)d; + //OCPlatform *platform = (OCPlatform*)data->str; + //myLightResource.m_platform = (OCPlatform*)data->str; + //OCPlatform platform(cfg); + // Invoke createResource function of class light. + + //mosquitto_connect(myMosquitto, "192.168.2.5", 1883, 60); + mosquitto_connect(myMosquitto, "127.0.0.1", 1883, 60); + printf("Mosquitto Connection is done\n"); + myLightResource.createResource(); + //myLightResource.addType(std::string("core.light")); + //myLightResource.addInterface(std::string("oc.mi.ll")); + // Get time of day + timer = time(NULL); + // Converts date/time to a structure + tblock = localtime(&timer); + // Output ASCII data/time + printf("LightReousrce reigishter time is: %s", asctime(tblock)); + // Perform app tasks + while (true) + { + // some tasks + } + } + catch (OCException e) + { + //log(e.what()); + } + // No explicit call to stop the platform. + // When OCPlatform destructor is invoked, internally we do platform cleanup + mosquitto_destroy(myMosquitto); + + mosquitto_lib_cleanup(); + printf("start_lightserver finish\n"); + pthread_exit((void *)0); +} diff --git a/service/protocol-plugin/plugins/mqtt-light/src/lightserver.h b/service/protocol-plugin/plugins/mqtt-light/src/lightserver.h new file mode 100644 index 0000000..d949162 --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/src/lightserver.h @@ -0,0 +1,2 @@ +//int start_fanserver(void*); // 1 +void *start_lightserver(void *ocplatform); // 2 diff --git a/service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.cpp b/service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.cpp new file mode 100644 index 0000000..28b1c5d --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.cpp @@ -0,0 +1,80 @@ +#include "lightserver_mqtt_plugin.h" +#include "lightserver.h" +#include +#include // 2 + +//int start_fanserver(void*); // 1 +void *start_lightserver(void *d); // 2 + +typedef struct plugin_data_t plugin_data_t; + +struct plugin_data_t +{ + cp_context_t *ctx; + pthread_t m_thread; // 2 + void *str; + bool flag; +}; + + +#ifdef __cplusplus +extern "C" +{ +#endif + +static void *create(cp_context_t *ctx) +{ + plugin_data_t *data = (plugin_data_t *)malloc(sizeof(plugin_data_t)); + + if (data != NULL) + { + data->ctx = ctx; + data->flag = true; + } + else + { + printf("[MQTT] ERROR: Plug-in Data - NULL\n"); + } + + return data; +} + +static int start(void *d) +{ + plugin_data_t *data = (plugin_data_t *)d; + + data->str = (void *)cp_resolve_symbol(data->ctx, "lightserver_mqtt_plugin", "START_ARGUMENT", NULL); + + //cp_run_function(data->ctx, (cp_run_func_t)start_fanserver); // 1 + pthread_create(&(data->m_thread), NULL, start_lightserver, data); // 2 + return 0; +} + +static void stop(void *d) +{ + printf("function_stop\n"); + plugin_data_t *data = (plugin_data_t *)d; + + data->flag = false; + cp_release_symbol(data->ctx, data->str); + pthread_join(data->m_thread, (void **)NULL); +} + +static void destroy(void *d) +{ + printf("function_destroy\n"); + plugin_data_t *data = (plugin_data_t *)d; + free(data); +} + +CP_EXPORT cp_plugin_runtime_t mqtt_plugin_lightserver_funcs = +{ + create, + start, + stop, + destroy +}; + +#ifdef __cplusplus +} +#endif diff --git a/service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.h b/service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.h new file mode 100644 index 0000000..d2fb82c --- /dev/null +++ b/service/protocol-plugin/plugins/mqtt-light/src/lightserver_mqtt_plugin.h @@ -0,0 +1,6 @@ +#ifndef PLUGIN_1_HEADER_INCLUDED +#define PLUGIN_1_HEADER_INCLUDED + +#include +#include +#endif diff --git a/service/protocol-plugin/plugins/mqtt/src/fanserver.cpp b/service/protocol-plugin/plugins/mqtt/src/fanserver.cpp deleted file mode 100644 index c3d6b43..0000000 --- a/service/protocol-plugin/plugins/mqtt/src/fanserver.cpp +++ /dev/null @@ -1,419 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 Intel Corporation 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -/// -/// This sample provides steps to define an interface for a resource -/// (properties and methods) and host this resource on the server. -/// - -#include -#include -#include - -#include "OCPlatform.h" -#include "OCApi.h" -#include "../lib/mosquitto.h" - - -using namespace OC; -using namespace std; - -int gObservation = 0; - -// Forward declaring the entityHandler -void entityHandler(std::shared_ptr request, - std::shared_ptr response); - -/// This class represents a single resource named 'fanResource'. This resource has -/// two simple properties named 'state' and 'power' -typedef struct plugin_data_t plugin_data_t; - -struct plugin_data_t -{ - cp_context_t *ctx; - pthread_t m_thread; // 2 - void *str; - bool flag; -}; - - -class FanResource -{ - public: - /// Access this property from a TB client - bool m_state; - int m_power; - int m_health; - std::string m_fanUri; - OCResourceHandle m_resourceHandle; - - public: - /// Constructor - FanResource(): m_state(false), m_power(0), m_health(0), m_fanUri {"/a/fan"} { } - - /* Note that this does not need to be a member function: for classes you do not have - access to, you can accomplish this with a free function: */ - - /// This function internally calls registerResource API. - void createResource(OC::OCPlatform &platform) - { - std::string resourceURI = m_fanUri; // URI of the resource - std::string resourceTypeName = "core.fan"; // resource type name. In this case, it is fan - std::string resourceInterface = DEFAULT_INTERFACE; // resource interface. - - // OCResourceProperty is defined ocstack.h - uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; - - // This will internally create and register the resource. - OCStackResult result = platform.registerResource( - m_resourceHandle, resourceURI, resourceTypeName, - resourceInterface, &entityHandler, resourceProperty); - - if (OC_STACK_OK != result) - { - cout << "Resource creation was unsuccessful\n"; - } - } - - OCResourceHandle getHandle() - { - return m_resourceHandle; - } - - void setRepresentation(OCRepresentation &fan) - { - AttributeMap attributeMap = fan.getAttributeMap(); - - if (attributeMap.find("state") != attributeMap.end() - && attributeMap.find("power") != attributeMap.end() - && attributeMap.find("health") != attributeMap.end()) - { - cout << "\t\t\t" << "Received representation: " << endl; - cout << "\t\t\t\t" << "power: " << attributeMap["power"][0] << endl; - cout << "\t\t\t\t" << "state: " << attributeMap["state"][0] << endl; - cout << "\t\t\t\t" << "health: " << attributeMap["health"][0] << endl; - - m_state = attributeMap["state"][0].compare("true") == 0; - m_power = std::stoi(attributeMap["power"][0]); - m_health = std::stoi(attributeMap["health"][0]); - } - - } - - OCRepresentation getRepresentation() - { - OCRepresentation fan; - - fan.setUri(m_fanUri); - - std::vector interfaces; - fan.setResourceInterfaces(interfaces); - - std::vector types; - fan.setResourceTypes(types); - - AttributeMap attributeMap; - AttributeValues stateVal; - - if (m_state) - { - stateVal.push_back("true"); - } - else - { - stateVal.push_back("false"); - } - - AttributeValues powerVal; - powerVal.push_back(to_string(m_power)); - - AttributeValues healthVal; - healthVal.push_back(to_string(m_health)); - - attributeMap["state"] = stateVal; - attributeMap["power"] = powerVal; - attributeMap["health"] = healthVal; - - fan.setAttributeMap(attributeMap); - - return fan; - } - - void addType(const OC::OCPlatform &platform, const std::string &type) const - { - OCStackResult result = platform.bindTypeToResource(m_resourceHandle, type); - if (OC_STACK_OK != result) - { - cout << "Binding TypeName to Resource was unsuccessful\n"; - } - } - - void addInterface(const OC::OCPlatform &platform, const std::string &interface) const - { - OCStackResult result = platform.bindInterfaceToResource(m_resourceHandle, interface); - if (OC_STACK_OK != result) - { - cout << "Binding TypeName to Resource was unsuccessful\n"; - } - } -}; - -// Create the instance of the resource class (in this case instance of class 'FanResource'). -FanResource myFanResource; -struct mosquitto *myMosquitto; - -// ChangeFanRepresentaion is an observation function, -// which notifies any changes to the resource to stack -// via notifyObservers -void *ChangeFanRepresentation (void *param) -{ - // This function continuously monitors for the changes - while (1) - { - sleep (5); - - if (gObservation) - { - // If under observation if there are any changes to the fan resource - // we call notifyObservors - // - // For demostration we are changing the power value and notifying. - if (myFanResource.m_health != 0) - myFanResource.m_health += 1; - - cout << "\nPower updated to : " << myFanResource.m_health << endl; - cout << "Notifying observers with resource handle: " << myFanResource.getHandle() << endl; - - OCStackResult result = OCPlatform::notifyObservers(myFanResource.getHandle()); - - if (OC_STACK_NO_OBSERVERS == result) - { - cout << "No More observers, stopping notifications" << endl; - gObservation = 0; - } - } - } - - return NULL; -} - - -// This is just a sample implementation of entity handler. -// Entity handler can be implemented in several ways by the manufacturer -void entityHandler(std::shared_ptr request, - std::shared_ptr response) -{ - cout << "\tIn Server CPP entity handler:\n"; - - if (request) - { - // Get the request type and request flag - std::string requestType = request->getRequestType(); - RequestHandlerFlag requestFlag = request->getRequestHandlerFlag(); - - if (requestFlag == RequestHandlerFlag::InitFlag) - { - cout << "\t\trequestFlag : Init\n"; - - // entity handler to perform resource initialization operations - } - else if (requestFlag == RequestHandlerFlag::RequestFlag) - { - cout << "\t\trequestFlag : Request\n"; - - // If the request type is GET - if (requestType == "GET") - { - cout << "\t\t\trequestType : GET\n"; - - // Check for query params (if any) - QueryParamsMap queryParamsMap = request->getQueryParameters(); - - cout << "\t\t\tquery params: \n"; - for (QueryParamsMap::iterator it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) - { - cout << "\t\t\t\t" << it->first << ":" << it->second << endl; - } - - // Process query params and do required operations .. - - // Get the representation of this resource at this point and send it as response - //AttributeMap attributeMap; - OCRepresentation rep; - rep = myFanResource.getRepresentation(); - - if (response) - { - // TODO Error Code - response->setErrorCode(200); - auto findRes = queryParamsMap.find("if"); - - if (findRes != queryParamsMap.end()) - { - response->setResourceRepresentation(rep, findRes->second); - } - else - { - response->setResourceRepresentation(rep, DEFAULT_INTERFACE); - } - } - } - else if (requestType == "PUT") - { - cout << "\t\t\trequestType : PUT\n"; - - // Check for query params (if any) - QueryParamsMap queryParamsMap = request->getQueryParameters(); - - cout << "\t\t\tquery params: \n"; - for (auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) - { - cout << "\t\t\t\t" << it->first << ":" << it->second << endl; - } - - // Get the representation from the request - OCRepresentation rep = request->getResourceRepresentation(); - AttributeMap attributeMap = rep.getAttributeMap(); - - myFanResource.setRepresentation(rep); - // Do related operations related to PUT request - rep = myFanResource.getRepresentation(); - - int power = std::stoi(attributeMap["power"][0]); - - if (power == 1) - { - mosquitto_publish(myMosquitto, NULL, "actuators/fan", 32, "onfan", 0, true); - } - else - { - mosquitto_publish(myMosquitto, NULL, "actuators/fan", 32, "offfan", 0, true); - } - - if (response) - { - response->setErrorCode(200); - auto findRes = queryParamsMap.find("if"); - - if (findRes != queryParamsMap.end()) - { - response->setResourceRepresentation(rep, findRes->second); - } - else - { - response->setResourceRepresentation(rep, DEFAULT_INTERFACE); - } - } - } - else if (requestType == "POST") - { - // POST request operations - } - else if (requestType == "DELETE") - { - // DELETE request operations - } - } - else if (requestFlag == RequestHandlerFlag::ObserverFlag) - { - pthread_t threadId; - - cout << "\t\trequestFlag : Observer\n"; - gObservation = 1; - - static int startedThread = 0; - - // Observation happens on a different thread in ChangeFanRepresentation function. - // If we have not created the thread already, we will create one here. - if (!startedThread) - { - pthread_create (&threadId, NULL, ChangeFanRepresentation, (void *)NULL); - startedThread = 1; - } - - } - } - else - { - std::cout << "Request invalid" << std::endl; - } -} - -//int start_fanserver(void*) // 1 -void *start_fanserver(void *d) // 2 -{ - /*PlatformConfig cfg; - cfg.ipAddress = "192.168.2.5"; - cfg.port = 56832; - cfg.mode = ModeType::Server; - cfg.serviceType = ServiceType::InProc;*/ - PlatformConfig cfg - { - OC::ServiceType::InProc, - OC::ModeType::Server, - "192.168.2.5", - 56832, - OC::QualityOfService::NonConfirmable - }; - - // Create PlatformConfig object - - // Create a OCPlatform instance. - // Note: Platform creation is synchronous call. - try - { - mosquitto_lib_init(); - myMosquitto = mosquitto_new("MQTT plug-in", true, NULL); - if (!myMosquitto) - { - printf("[mosquitto] Null\n"); - //return 1; // 1 - } - - plugin_data_t *data = (plugin_data_t *)d; - //OCPlatform *platform = (OCPlatform*)data->str; - OCPlatform platform(cfg); - // Invoke createResource function of class fan. - - mosquitto_connect(myMosquitto, "192.168.2.5", 1883, 60); - myFanResource.createResource(platform); - myFanResource.addType(platform, std::string("core.fan")); - myFanResource.addInterface(platform, std::string("oc.mi.ll")); - // Perform app tasks - while (data->flag) - { - // some tasks - } - } - catch (OCException e) - { - //log(e.what()); - } - - // No explicit call to stop the platform. - // When OCPlatform destructor is invoked, internally we do platform cleanup - - gObservation = 0; - mosquitto_destroy(myMosquitto); - - mosquitto_lib_cleanup(); - printf("start_fanserver finish\n"); - pthread_exit((void *)0); -} diff --git a/service/protocol-plugin/sample-app/linux/fan-control/Makefile b/service/protocol-plugin/sample-app/linux/fan-control/Makefile index 1b964ec..6b5d664 100644 --- a/service/protocol-plugin/sample-app/linux/fan-control/Makefile +++ b/service/protocol-plugin/sample-app/linux/fan-control/Makefile @@ -1,5 +1,3 @@ -include ../../../config.mk - CXX = g++ CXX_FLAGS = -std=c++0x -Wall -pthread @@ -7,23 +5,30 @@ CXX_FLAGS = -std=c++0x -Wall -pthread LIB_DIR = ../../../../../resource CXX_INC := -I$(LIB_DIR)/include/ +CXX_INC += -I$(LIB_DIR)/oc_logger/include/ CXX_INC += -I$(LIB_DIR)/csdk/stack/include/ CXX_INC += -I$(LIB_DIR)/csdk/ocsocket/include/ CXX_INC += -I$(LIB_DIR)/csdk/ocrandom/include/ -CXX_INC += -I$(LIB_DIR)/csdk/logger/include/ +CXX_INC += -I$(LIB_DIR)/csdk/logger/include/ CXX_INC += -I$(BOOST_DIR) -CXX_INC += -I./lib +CXX_INC += -I../../lib +CXX_INC += -I../../../lib/cpluff/libcpluff +CXX_INC += -I../../../plugin-manager/src +LIB_OC_LOGGER := $(LIB_DIR)/oc_logger/lib/oc_logger.a +CXX_LIBS := $(LIB_DIR)/release/obj/liboc.a $(LIB_DIR)/csdk/linux/release/liboctbstack.a $(LIB_OC_LOGGER) ../../../build/linux/release/libppm.a ../../../lib/cpluff/libcpluff/.libs/libcpluff.a +LINK_LIB = -lboost_system -ldl -lexpat -lboost_thread .PHONY: fanclient all: .PHONY -fanclient: $(LIB_DIR)/build/linux/release/obj/liboc.a fanclient.o - $(CXX) $(CXX_FLAGS) -o fanclient fanclient.o $(LIB_DIR)/build/linux/release/obj/liboc.a $(LIB_DIR)/csdk/build/linux/release/liboctbstack.a +fanclient: fanclient.o + $(CXX) $(CXX_FLAGS) -o fanclient fanclient.o $(CXX_LIBS) $(LINK_LIB) fanclient.o: fanclient.cpp $(CXX) $(CXX_FLAGS) -c fanclient.cpp $(CXX_INC) + clean: rm -f *.o diff --git a/service/protocol-plugin/sample-app/linux/fan-control/fanclient.cpp b/service/protocol-plugin/sample-app/linux/fan-control/fanclient.cpp index e30447f..64f4154 100644 --- a/service/protocol-plugin/sample-app/linux/fan-control/fanclient.cpp +++ b/service/protocol-plugin/sample-app/linux/fan-control/fanclient.cpp @@ -1,58 +1,89 @@ -/****************************************************************** -* -* Copyright 2014 Samsung Electronics All Rights Reserved. -* : Initialization Part has been referenced from OCClient.cpp file of Intel copyright. -* -* 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. -* -*******************************************************************/ - -// FanClient.cpp : Defines the entry point for the console application for controlling fan. +//****************************************************************** +// +// 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + +// OCClient.cpp : Defines the entry point for the console application. // #include #include #include #include "OCPlatform.h" +#include "PluginManager.h" #include "OCApi.h" +#include using namespace OC; +using namespace OIC; -const int SUCCESS_RESPONSE = 0; std::shared_ptr curResource; static ObserveType OBSERVE_TYPE_TO_USE = ObserveType::Observe; +time_t timer; // Define the timer +struct tm *tblock; // Define a structure for time block + +class Fan +{ + public: + + bool m_state; + int m_power; + std::string m_name; + + Fan() : m_state(false), m_power(0), m_name("") + { + } +}; + +Fan myfan; + int observe_count() { static int oc = 0; return ++oc; } -void onObserve(const OCRepresentation &rep, const int &eCode, const int &sequenceNumber) +void onObserve(const HeaderOptions headerOptions, const OCRepresentation &rep, + const int &eCode, const int &sequenceNumber) { - if (eCode == SUCCESS_RESPONSE) + if (eCode == OC_STACK_OK) { - AttributeMap attributeMap = rep.getAttributeMap(); - std::cout << "OBSERVE RESULT:" << std::endl; std::cout << "\tSequenceNumber: " << sequenceNumber << endl; - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) + + rep.getValue("state", myfan.m_state); + rep.getValue("power", myfan.m_power); + rep.getValue("name", myfan.m_name); + + std::cout << "\tstate: " << myfan.m_state << std::endl; + std::cout << "\tpower: " << myfan.m_power << std::endl; + std::cout << "\tname: " << myfan.m_name << std::endl; + + if (observe_count() > 30) { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - std::cout << std::endl; + std::cout << "Cancelling Observe..." << std::endl; + OCStackResult result = curResource->cancelObserve(); + + std::cout << "Cancel result: " << result << std::endl; + sleep(10); + std::cout << "DONE" << std::endl; + std::exit(0); } } else @@ -62,42 +93,26 @@ void onObserve(const OCRepresentation &rep, const int &eCode, const int &sequenc } } -// callback handler on PUT request -void onPut(const OCRepresentation &rep, const int eCode) +void onPost2(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode) { - if (eCode == SUCCESS_RESPONSE) + if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED) { - std::cout << "PUT request was successful" << std::endl; + std::cout << "POST request was successful" << std::endl; - AttributeMap attributeMap = rep.getAttributeMap(); - - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) + if (rep.hasAttribute("createduri")) { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - - std::cout << std::endl; + std::cout << "\tUri of the created resource: " + << rep.getValue("createduri") << std::endl; } - - std::vector children = rep.getChildren(); - - for (auto oit = children.begin(); oit != children.end(); ++oit) + else { - attributeMap = oit->getAttributeMap(); - - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } + rep.getValue("state", myfan.m_state); + rep.getValue("power", myfan.m_power); + rep.getValue("name", myfan.m_name); - std::cout << std::endl; - } + std::cout << "\tstate: " << myfan.m_state << std::endl; + std::cout << "\tpower: " << myfan.m_power << std::endl; + std::cout << "\tname: " << myfan.m_name << std::endl; } if (OBSERVE_TYPE_TO_USE == ObserveType::Observe) @@ -105,177 +120,163 @@ void onPut(const OCRepresentation &rep, const int eCode) else if (OBSERVE_TYPE_TO_USE == ObserveType::ObserveAll) std::cout << endl << "ObserveAll is used." << endl << endl; - QueryParamsMap test; - - curResource->observe(OBSERVE_TYPE_TO_USE, test, &onObserve); + curResource->observe(OBSERVE_TYPE_TO_USE, QueryParamsMap(), &onObserve); } else { - std::cout << "onPut Response error: " << eCode << std::endl; + std::cout << "onPost Response error: " << eCode << std::endl; std::exit(-1); } } -// Local function to put a different state for this resource -void putFanRepresentation(std::shared_ptr resource) +void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode) { - if (resource) + if (eCode == OC_STACK_OK || eCode == OC_STACK_RESOURCE_CREATED) { - OCRepresentation rep; - - std::cout << "Putting light representation..." << std::endl; - // Create AttributeMap - AttributeMap attributeMap; - // Add the attribute name and values in the attribute map - AttributeValues stateVal; - stateVal.push_back("true"); + std::cout << "POST request was successful" << std::endl; - AttributeValues powerVal; - powerVal.push_back("1"); + if (rep.hasAttribute("createduri")) + { + std::cout << "\tUri of the created resource: " + << rep.getValue("createduri") << std::endl; + } + else + { + rep.getValue("state", myfan.m_state); + rep.getValue("power", myfan.m_power); + rep.getValue("name", myfan.m_name); - AttributeValues healthVal; - healthVal.push_back("1"); + std::cout << "\tstate: " << myfan.m_state << std::endl; + std::cout << "\tpower: " << myfan.m_power << std::endl; + std::cout << "\tname: " << myfan.m_name << std::endl; + } + OCRepresentation rep2; - attributeMap["state"] = stateVal; - attributeMap["power"] = powerVal; - attributeMap["health"] = healthVal; + std::cout << "Posting fan representation..." << std::endl; - // Create QueryParameters Map and add query params (if any) - QueryParamsMap queryParamsMap; + myfan.m_state = true; + myfan.m_power = 55; - rep.setAttributeMap(attributeMap); + rep2.setValue("state", myfan.m_state); + rep2.setValue("power", myfan.m_power); - // Invoke resource's pit API with attribute map, query map and the callback parameter - resource->put(rep, queryParamsMap, &onPut); + curResource->post(rep2, QueryParamsMap(), &onPost2); + } + else + { + std::cout << "onPost Response error: " << eCode << std::endl; + std::exit(-1); } } - -void putFanRepresentationON(std::shared_ptr resource) +// Local function to put a different state for this resource +void postFanRepresentation(std::shared_ptr resource) { if (resource) { OCRepresentation rep; - std::cout << "Putting Fan representation..." << std::endl; - // Create AttributeMap - AttributeMap attributeMap; - // Add the attribute name and values in the attribute map - AttributeValues stateVal; - stateVal.push_back("true"); + std::cout << "Posting fan representation..." << std::endl; - AttributeValues powerVal; - powerVal.push_back("1"); + myfan.m_state = false; + myfan.m_power = 105; - AttributeValues healthVal; - healthVal.push_back("1"); + rep.setValue("state", myfan.m_state); + rep.setValue("power", myfan.m_power); + // Invoke resource's post API with rep, query map and the callback parameter + resource->post(rep, QueryParamsMap(), &onPost); + } +} - attributeMap["state"] = stateVal; - attributeMap["power"] = powerVal; - attributeMap["health"] = healthVal; +// callback handler on PUT request +void onPut(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode) +{ + if (eCode == OC_STACK_OK) + { + std::cout << "PUT request was successful" << std::endl; - // Create QueryParameters Map and add query params (if any) - QueryParamsMap queryParamsMap; + rep.getValue("state", myfan.m_state); + rep.getValue("power", myfan.m_power); + rep.getValue("name", myfan.m_name); - rep.setAttributeMap(attributeMap); + std::cout << "\tstate: " << myfan.m_state << std::endl; + std::cout << "\tpower: " << myfan.m_power << std::endl; + std::cout << "\tname: " << myfan.m_name << std::endl; - // Invoke resource's pit API with attribute map, query map and the callback parameter - resource->put(rep, queryParamsMap, &onPut); + postFanRepresentation(curResource); + } + else + { + std::cout << "onPut Response error: " << eCode << std::endl; + std::exit(-1); } } -void putFanRepresentationOFF(std::shared_ptr resource) +// Local function to put a different state for this resource +void putFanRepresentation(std::shared_ptr resource) { if (resource) { OCRepresentation rep; std::cout << "Putting fan representation..." << std::endl; - // Create AttributeMap - AttributeMap attributeMap; - // Add the attribute name and values in the attribute map - AttributeValues stateVal; - stateVal.push_back("false"); - - AttributeValues powerVal; - powerVal.push_back("0"); - AttributeValues healthVal; - healthVal.push_back("0"); + myfan.m_state = true; + myfan.m_power = 15; + rep.setValue("state", myfan.m_state); + rep.setValue("power", myfan.m_power); - attributeMap["state"] = stateVal; - attributeMap["power"] = powerVal; - attributeMap["health"] = healthVal; - - // Create QueryParameters Map and add query params (if any) - QueryParamsMap queryParamsMap; - - // Invoke resource's pit API with attribute map, query map and the callback parameter - rep.setAttributeMap(attributeMap); - - // Invoke resource's pit API with attribute map, query map and the callback parameter - resource->put(rep, queryParamsMap, &onPut); + // Invoke resource's put API with rep, query map and the callback parameter + resource->put(rep, QueryParamsMap(), &onPut); } } - -// callback handler on GET request -void onGet(const OCRepresentation &rep, const int eCode) +// Callback handler on GET request +void onGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, const int eCode) { - if (eCode == SUCCESS_RESPONSE) + if (eCode == OC_STACK_OK) { - std::cout << "GET Succeeded:" << std::endl; - - AttributeMap attributeMap = rep.getAttributeMap(); + std::cout << "GET request was successful" << std::endl; std::cout << "Resource URI: " << rep.getUri() << std::endl; - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } - - std::cout << std::endl; - } - - std::vector children = rep.getChildren(); - - for (auto oit = children.begin(); oit != children.end(); ++oit) - { - std::cout << "Child Resource URI: " << oit->getUri() << std::endl; - - attributeMap = oit->getAttributeMap(); + rep.getValue("state", myfan.m_state); + rep.getValue("power", myfan.m_power); + rep.getValue("name", myfan.m_name); - for (auto it = attributeMap.begin(); it != attributeMap.end(); ++it) - { - std::cout << "\tAttribute name: " << it->first << " value: "; - for (auto valueItr = it->second.begin(); valueItr != it->second.end(); ++valueItr) - { - std::cout << "\t" << *valueItr << " "; - } + std::cout << "\tstate: " << myfan.m_state << std::endl; + std::cout << "\tpower: " << myfan.m_power << std::endl; + std::cout << "\tname: " << myfan.m_name << std::endl; - std::cout << std::endl; - } - } putFanRepresentation(curResource); } else { - std::cout << "onGet Response error: " << eCode << std::endl; + std::cout << "onGET Response error: " << eCode << std::endl; std::exit(-1); } } + // Local function to get representation of fan resource void getFanRepresentation(std::shared_ptr resource) { if (resource) { + std::cout << "Getting Fan Representation..." << std::endl; + // Invoke resource's get API with the callback parameter + + QueryParamsMap test; + resource->get(test, &onGet); + } +} + +void getLightRepresentation(std::shared_ptr resource) +{ + if (resource) + { std::cout << "Getting Light Representation..." << std::endl; // Invoke resource's get API with the callback parameter @@ -285,9 +286,8 @@ void getFanRepresentation(std::shared_ptr resource) } // Callback to found resources -void foundResource(std::shared_ptr resource) +void foundResourceFan(std::shared_ptr resource) { - if (curResource) { std::cout << "Found another resource, ignoring" << std::endl; @@ -308,6 +308,7 @@ void foundResource(std::shared_ptr resource) // Get the resource host address hostAddress = resource->host(); std::cout << "\tHost address of the resource: " << hostAddress << std::endl; + // Get the resource types std::cout << "\tList of resource types: " << std::endl; for (auto &resourceTypes : resource->getResourceTypes()) @@ -342,41 +343,199 @@ void foundResource(std::shared_ptr resource) } } +// Callback to found resources +void foundResourceLight(std::shared_ptr resource) +{ + if (curResource) + { + std::cout << "Found another resource, ignoring" << std::endl; + } + + std::string resourceURI; + std::string hostAddress; + try + { + // Do some operations with resource object. + if (resource) + { + std::cout << "DISCOVERED Resource:" << std::endl; + // Get the resource URI + resourceURI = resource->uri(); + std::cout << "\tURI of the resource: " << resourceURI << std::endl; + + // Get the resource host address + hostAddress = resource->host(); + std::cout << "\tHost address of the resource: " << hostAddress << std::endl; + + // Get the resource types + std::cout << "\tList of resource types: " << std::endl; + for (auto &resourceTypes : resource->getResourceTypes()) + { + std::cout << "\t\t" << resourceTypes << std::endl; + } + + // Get the resource interfaces + std::cout << "\tList of resource interfaces: " << std::endl; + for (auto &resourceInterfaces : resource->getResourceInterfaces()) + { + std::cout << "\t\t" << resourceInterfaces << std::endl; + } + + if (resourceURI == "/a/light") + { + curResource = resource; + // Call a local function which will internally invoke get API on the resource pointer + getLightRepresentation(resource); + } + } + else + { + // Resource is invalid + std::cout << "Resource is invalid" << std::endl; + } + + } + catch (std::exception &e) + { + //log(e.what()); + } +} + +void PrintUsage() +{ + std::cout << std::endl; + std::cout << "Usage : simpleclient " << std::endl; + std::cout << " ObserveType : 1 - Observe" << std::endl; + std::cout << " ObserveType : 2 - ObserveAll" << std::endl; +} + +void client1() +{ + std::cout << "in client1\n"; + + // OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.foo", + // foundResource1); + std::cout << "starting findResource = core.fan" << std::endl; + // Find all resources + OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.fan", &foundResourceFan); + // Get time of day + timer = time(NULL); + // Converts date/time to a structure + tblock = localtime(&timer); + std::cout << "Finding Fan Resource... time : " << asctime(tblock) << std::endl; + while (1) + { + // client1 related operations + } +} + +void client2() +{ + std::cout << "in client2\n"; + + // OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.foo", + // foundResource2); + + std::cout << "starting findResource = core.light" << std::endl; + // Find all resources + OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=core.light", &foundResourceLight); + // Get time of day + timer = time(NULL); + // Converts date/time to a structure + tblock = localtime(&timer); + std::cout << "Finding Light Resource... time : " << asctime(tblock) << std::endl; + + + + while (1) + { + // client2 related operations + } +} + + + int main(int argc, char *argv[]) { + if (argc == 1) + { + OBSERVE_TYPE_TO_USE = ObserveType::Observe; + } + else if (argc == 2) + { + int value = atoi(argv[1]); + if (value == 1) + OBSERVE_TYPE_TO_USE = ObserveType::Observe; + else if (value == 2) + OBSERVE_TYPE_TO_USE = ObserveType::ObserveAll; + else + OBSERVE_TYPE_TO_USE = ObserveType::Observe; + } + else + { + PrintUsage(); + return -1; + } + + // Create PlatformConfig object PlatformConfig cfg { OC::ServiceType::InProc, - OC::ModeType::Client, - "192.168.2.5", - 5683, - OC::QualityOfService::NonConfirmable + OC::ModeType::Both, + "0.0.0.0", + 0, + OC::QualityOfService::LowQos }; - // Create a OCPlatform instance. - // Note: Platform creation is synchronous call. + OCPlatform::Configure(cfg); try { - OCPlatform platform(cfg); + std::cout << "Created Platform..." << std::endl; - // Find all resources - platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.fan", &foundResource); - std::cout << "Finding Resource... " << std::endl; - sleep(20); + + + PluginManager *m_pm = new PluginManager(); + + std::cout << "======================" << std::endl; + + std::cout << "start light Plugin by Resource Type" << std::endl; + m_pm->startPlugins("ResourceType", "oic.light"); + + sleep(2); + + std::cout << "======================" << std::endl; + std::cout << "get Plugin List" << std::endl; + std::vector user_plugin; + user_plugin = m_pm->getPlugins(); + for (unsigned int i = 0; i < user_plugin.size(); i++) + { + printf("value Name = %s\n", user_plugin[i].getName().c_str()); + printf("value ID = %s\n", user_plugin[i].getID().c_str()); + } + + std::cout << "======================" << std::endl; + std::cout << "start Fan Plugin by Name" << std::endl; + m_pm->startPlugins("Name", "mqtt-fan"); + + + // Start each client in a seperate thread +// std::thread t1(client1); +// t1.detach(); + +///* +// sleep(5); + // Start each client in a seperate thread +// std::thread t2(client2); +// t2.detach(); +//*/ while (true) { - //Test Simple Scenario - std::cout << "Turn off the Fan" << std::endl; - putFanRepresentationOFF(curResource); - sleep(15); - std::cout << "Turn on the Fan" << std::endl; - putFanRepresentationON(curResource); - sleep(30); // some operations } + } - catch (OCException e) + catch (OCException &e) { //log(e.what()); } -- 2.7.4