diff options
81 files changed, 12061 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..15d1344 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,76 @@ +cmake_minimum_required (VERSION 2.8) + +project (ua-client) + +#set(CMAKE_SKIP_BUILD_RPATH TRUE) + +include(CheckCXXCompilerFlag) + +CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11) +CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X) +IF(COMPILER_SUPPORTS_CXX11) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +ELSEIF(COMPILER_SUPPORTS_CXX0X) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +ELSE() + MESSAGE(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++ support. Please use a different C++ compiler.") +ENDIF() + +install(FILES ${CMAKE_SOURCE_DIR}/res/device_info.ini DESTINATION /opt/usr/data/ua_client/) +install(FILES ${CMAKE_SOURCE_DIR}/res/.firmware_controlee.dat DESTINATION /opt/usr/data/ua_client/) + + +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} -O2 -g -Wall") + +add_definitions(-D__TIZEN__ -D_GNU_SOURCE -DTIZEN_DEBUG_ENABLE -DTB_LOG -DWITH_CLOUD -DRD_SERVER) + +include_directories( + ${CMAKE_SOURCE_DIR}/inc/ + ${CMAKE_SOURCE_DIR}/inc/iotivity/ + ) + +set(SOURCES + ${CMAKE_SOURCE_DIR}/src/ua_client.cpp + ${CMAKE_SOURCE_DIR}/src/ua_http.cpp + ${CMAKE_SOURCE_DIR}/src/ua_json_parser.cpp + ) + +#set(dependents "boost dlog glib-2.0 iotivity libcurl uuid json-glib-1.0 capi-network-connection") +set(dependents "boost dlog glib-2.0 libcurl uuid json-glib-1.0 capi-network-connection capi-network-wifi") +include(FindPkgConfig) +pkg_check_modules(${PROJECT_NAME} REQUIRED ${dependents}) + +foreach(flag ${${PROJECT_NAME}_CFLAGS}) + set(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag} -std=c++11") +endforeach(flag) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}") + +#find_library(IOTIVITY_LIBRARY +# NAMES oc oc_logger octbstack ocsrm routingmanager connectivity_abstraction c_common coap logger +# PATHS ${CMAKE_SOURCE_DIR}/lib/ +#) + +set(LINK_STATIC_LIBS + oc + oc_logger + octbstack + ocsrm + routingmanager + connectivity_abstraction + c_common + coap + resource_directory + logger + pthread + rt + uuid + capi-network-wifi + ) + +set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") + +link_directories(${CMAKE_SOURCE_DIR}/lib/) +add_executable(${PROJECT_NAME} ${SOURCES}) +target_link_libraries(${PROJECT_NAME} ${${PROJECT_NAME}_LDFLAGS} ${LINK_STATIC_LIBS}) +install(TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/content_server/content_server.js b/content_server/content_server.js new file mode 100644 index 0000000..8ee06e0 --- /dev/null +++ b/content_server/content_server.js @@ -0,0 +1,299 @@ +const PORT = 8000 +const IMAGE_DIR = "/var/www/images/" + +const HTTP_OK = 200; +const HTTP_BAD_REQUEST = 400; +const HTTP_INTERNAL_ERROR = 500; + +var express = require('express'); +var app = express(); +var fs = require("fs"); +var host_ip = require("ip"); + +var bodyParser = require('body-parser'); +var multer = require('multer'); +const cp = require('child_process'); +var sqlite3 = require('sqlite3').verbose(); +var db = new sqlite3.Database('firmware.db'); +var child = cp.fork(__dirname +'/sub.js'); +var qcount = 0; +var cmd_list = []; +var resp_msg = {}; +var update_msg = {}; +var g_res; + +app.use(express.static('public')); +app.use(bodyParser.urlencoded({ extended: false })); + +app.get('/file_upload.html', function (req, res) { + res.sendFile( __dirname + "/" + "file_upload.html" ); +// res.sendFile( __dirname + "/" + "file_upload3.html" ); +}) + +/* +app.get('/monitoring.html', function (req, res) { + res.sendFile( __dirname + "/" + "monitoring.html" ); +// res.sendFile( __dirname + "/" + "file_upload3.html" ); +}) +*/ + +var server = app.listen(PORT, function () { + var host = host_ip.address(); + var port = server.address().port; + + console.log("content-server listening at http://%s:%s", host, port) +}) + +db.serialize(function() { + db.run("CREATE TABLE IF NOT EXISTS full_tbl (manufacturer TEXT, model TEXT, version TEXT, file TEXT, patch_version TEXT, patch_url TEXT, priority INT)"); + db.each("SELECT model, version, file FROM full_tbl", function(err, row) { + console.log(row.model, ",", row.version, ":", row.file); + }); +}); + + +var upload = multer({ dest: '/tmp/'}); + +// curl -v -X GET http://localhost:3000/firmware?manufacturer=samsung&model=tm1&version=1.0 +app.get('/firmware', function(req, res){ + console.log("url: [", req.url, "]"); + console.log("query: [", req.query, "]"); + var manufacturer = req.query.manufacturer; + var model = req.query.model; + var cur_ver = req.query.version; + console.log("manufacturer: [", manufacturer, "]"); + console.log("model: [", model, "]"); + + if (!(manufacturer || model || version)) { + console.log("bad request - manufacturer[", manufacturer, "], model[", model, "]"); + res.status(HTTP_BAD_REQUEST).json({errmsg: "missing parameters"}); + return; + } + + var ret = {}; + db.get("SELECT * FROM full_tbl WHERE manufacturer=? AND model=? AND version=?", manufacturer, model, cur_ver, function(err, row) { + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else if (!row) { + console.log('firmware not found'); + res.status(HTTP_BAD_REQUEST).json({errmsg:'firmware not found'}); + } + else { + console.log(row); + ret.old_version = cur_ver; + ret.new_verion = row.patch_version; + ret.url = row.patch_url; + ret.priority = row.priority; + res.json(ret); + } + }); +}); + + +app.post('/file_upload', upload.single('file'), function(req, res) { + var file = IMAGE_DIR + req.file.originalname; + var mf = req.body.manufacturer; + var model = req.body.model; + var ver = req.body.version; + var priority = req.body.priority; + console.log("req.file: ", file); + console.log("manufacturer: ", mf); + console.log("model: ", model); + console.log("version: ", ver); + console.log("priority: ", priority); + + if(!(file && mf && model && ver)) { + console.log("file[", file,"], manufacturer[",mf ,"], model[", model,"], version[",ver ,"]"); + res.status(HTTP_BAD_REQUEST).json({errmsg: "missing parameters"}); + return; + } + + + console.log("req.body:", req.body); + cmd_list = []; + resp_msg = {}; + resp_msg.results = []; + update_msg = {}; + update_msg.urls = []; + + if(req.body.upload) { + fs.rename(req.file.path, file, function(err) { + if (err) { + console.log("error: ", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } else { + db.get("SELECT file FROM full_tbl WHERE manufacturer=? and model=? and version=?", mf, model, ver, function(err, row) { + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else if (row) { + console.log("the same version already exists"); + res.status(HTTP_BAD_REQUEST).json({errmsg:'version duplicated'}); + } + else { + db.run("INSERT INTO full_tbl (manufacturer, model, version, file, patch_version, patch_url, priority) VALUES (?,?,?,?,?,?,?)", mf, model, ver, file, ver, req.file.originalname, priority, function(err) { + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else + res.json({'manufacturer':mf, 'model': model, 'version':ver, 'file':req.file.originalname, 'priority':priority}); + }); + } + }); + } + }); + } + else if(req.body.bsdiff) { + db.each("SELECT * FROM full_tbl WHERE manufacturer=? and model=?", mf, model, + function(err, row){ /* result callback */ + console.log("old version [" + row.version + "]"); + if(ver > row.version) { + var cmd = {}; + cmd.old_ver = row.version; + cmd.old_file = row.file; + cmd.new_file = file; + cmd.new_ver = ver; +// var cmd = __dirname + '/ss_bsdiff' + " " + old_file + " " + file + " "+ patch_file; + console.log("cmd:", cmd); + cmd_list.push(cmd); + } + }, function(err,row) { /* completion callback */ + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else if(row==0 || cmd_list.length == 0){ + res.status(HTTP_BAD_REQUEST).json({'errmsg':'no firmware available'}); + } + else { + update_msg.manufacturer = mf; + update_msg.model = model; +// update_msg.cmd = "WRITE"; + update_msg.priority = priority; + console.log("cmd list:", cmd_list, ", length:", cmd_list.length); + // send the first cmd to child process + child.send(cmd_list[0]); + qcount = 1; + g_res = res; // after processing the last command, g_res is used for response + } + }); + } + else if(req.body.diff) { + var old_ver = req.body.old_version; + if(!old_ver) { + console.log("old_version", old_ver,"]"); + res.status(HTTP_BAD_REQUEST).json({errmsg: "missing parameters: old_version"}); + return; + } + + fs.rename(req.file.path, file, function(err) { + if (err) { + console.log("error: ", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } else { + db.get("SELECT * FROM full_tbl WHERE manufacturer=? and model=? and version=?", mf, model, old_ver, function(err, row) { + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else if (!row) { + console.log("version not found"); + res.status(HTTP_BAD_REQUEST).json({errmsg:'version not found'}); + } + else { + var patch_url = "http://" + host_ip.address() + "/images/" + req.file.originalname; + db.run("UPDATE full_tbl SET patch_version=?, patch_url=?, priority=? WHERE manufacturer=? AND model=? AND version=?", ver, patch_url, priority, mf, model, old_ver, function(err) { + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else + res.json({'manufacturer':mf, 'model': model, 'old_version':old_ver, 'new_version':ver, 'url':patch_url ,'priority':priority, }); + }); + } + }); + } + }); + } +}); + + +child.on('message', function(m) { + console.log('return:', m); + console.log('qcount:', qcount, "qlength:", cmd_list.length); + + var resp = {}; + resp.version = m.old_ver; + resp.errmsg = m.errmsg; + resp_msg.results.push(resp); + + var update = {}; + update.old_version = m.old_ver; + update.new_version = m.new_ver; + update.url = "http://" + host_ip.address() + "/images/" + m.patch_name; + console.log("added:", update); + update_msg.urls.push(update); + + db.run("UPDATE full_tbl SET patch_version=?,patch_url=?,priority=? WHERE manufacturer=? AND model=? AND version=?", update.new_version, update.url, update_msg.priority, update_msg.manufacturer, update_msg.model, update.old_version, function(err) { + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else { + if (qcount == cmd_list.length) { + // the last command + console.log("diff done"); + console.log("update_msg:", update_msg); + g_res.json(resp_msg); + } + else { + // request the next command + console.log("cmd:", cmd_list[qcount]); + child.send(cmd_list[qcount]); + qcount++; + } + } + }); +}); + +/* else if(req.body.nodiff) { + db.get("SELECT file FROM full_tbl WHERE manufacturer=? and model=? and version=?", mf, model, ver, function(err, row) { + if (err){ + console.error("error", err); + res.status(HTTP_INTERNAL_ERROR).json(err); + } + else if (!row) { + console.log("firmware not found"); + res.status(HTTP_BAD_REQUEST).json({errmsg:'firmware not found'}); + } + else { + var resp = {}; + resp.old_ver = m.old_ver; + resp.new_ver = m.new_ver; + resp.errmsg = "success"; + resp.patch_name = patch_name; + console.log(resp); + update_msg.manufacturer = mf; + update_msg.model = model; + update_msg.cmd = "WRITE"; + + var options = { + uri: REST_SERVER_ADDR+"/devices/update", + method: 'POST', + json: update_msg + }; + request.post(options, function(error, response, body) { + if(error) { + console.log(error); + } + else { + console.log(body); + } + }); + } + }); + } */ diff --git a/content_server/file_upload.html b/content_server/file_upload.html new file mode 100644 index 0000000..be2cf65 --- /dev/null +++ b/content_server/file_upload.html @@ -0,0 +1,108 @@ +<html> +<head> +<title>Firmware Uploading Form</title> +</head> +<body> +<h3>Firmware Upload:</h3> +Select a file to upload: <br> +<!--<form action="file_upload" method="POST" enctype="multipart/form-data" onsubmit="myFunction()" onpagehide="foo()"> --> +<form action="/file_upload" method="POST" enctype="multipart/form-data" name="fooo"> +<input type="file" name="file" id="file" style="width:500px"><br> +Manufacturer:<br> +<input type="text" name="manufacturer"><br> +Model:<br> +<input type="text" name="model"> <br> +New Firmware Version:<br> +<input type="text" name="version" id="version"><br> +Priority:<br> +<select name="priority"> + <option value="1">Normal</option> + <option value="0">Urgent</option> +</select><br><br> +<input type="submit" onclick="return sendForm(this.form, 1);" name="upload" value="Full Upload"> +<input type="submit" onclick="return sendForm(this.form, 2);" name="bsdiff" value="Build Diff"><br><br> +Old Firmware Version:<br> +<input type="text" name="old_version" id="old_version"><br> +<input type="submit" onclick="return sendForm(this.form, 3);" name="diff" value="Diff Upload"> +</form> +<div> </div>RESULT<br> +<div id="message" style="background-color:#F5F5F5;width:600px;height:300px;OVERFLOW-Y:auto;word-wrap:break-word"></div> +<script> +function sendForm(form, formType) { + console.log("type:", formType); + var formData = new FormData(form); + var file_name = document.getElementById('file').value; + var version = document.getElementById('version').value; + console.log("file:", file_name); + var req_msg; + if(formType == 1) { + formData.append('upload', 1); // Append extra data before send. + req_msg = "> Uploading "+ file_name + " started. Please, wait for several minutes." +'\r\n'; + } + else if(formType == 2) { + formData.append('bsdiff', 1); // Append extra data before send. + req_msg = "> Building diff images based on version "+ version + " started. Please, wait for several minutes. It may takes long time depending on how large image is and how many previous versions are." +'\r\n'; + } + else if(formType == 3) { + formData.append('diff', 1); // Append extra data before send. + req_msg = "> Uploading "+ file_name + " started. Please, wait a minutes." +'\r\n'; + } + + var xhr = new XMLHttpRequest(); + xhr.open('POST', form.action, true); + + xhr.onload = function(e) { + var result = ""; + if (xhr.status == 200) { + console.log(this.responseText); + if(formType == 1) + result = "> Uploading Complete!"+'\r\n' + this.responseText+'\r\n'; + else if(formType == 2) + result = "> Building Diff Complete!"+'\r\n' + this.responseText+'\r\n'; + else if(formType == 3) + result = "> Uploading Complete!"+'\r\n' + this.responseText+'\r\n'; + } else { + if(formType == 1) + result = "> Error " + xhr.status + " occurred when trying to upload full image." + '\r\n' + this.responseText+'\r\n'; + else if(formType == 2) + result = "> Error " + xhr.status + " occurred when trying to build image diff." + '\r\n' + this.responseText+'\r\n'; + else if(formType == 3) + result = "> Error " + xhr.status + " occurred when trying to upload diff image." + '\r\n' + this.responseText+'\r\n'; + } + var div = document.getElementById('message'); + div.innerText += result; + div.scrollTop = div.scrollHeight; + }; + + var div = document.getElementById('message'); + div.innerText += req_msg; + div.scrollTop = div.scrollHeight; + + xhr.send(formData); + return false; // Prevent page from submitting. +} + +function sendDiff(form) { + var formData = new FormData(form); + var oOutput = document.querySelector("div"); + formData.append('bsdiff', 1); // Append extra data before send. + + var xhr = new XMLHttpRequest(); + xhr.open('POST', form.action, true); + xhr.onload = function(e) { + if (xhr.status == 200) { + console.log(this.responseText); + oOutput.innerHTML = "Build Diff Complete<br\/>" + this.responseText; + } else { + oOutput.innerHTML = "Error " + xhr.status + " occurred when trying to build image diff.<br \/>" + this.responseText; + } + }; + xhr.send(formData); + return false; // Prevent page from submitting. +} + +</script> + +<!--<div id="message" style="background-color:#F5F5F5;width:400px;height:200px;OVERFLOW-Y:auto;word-wrap:break-word"></div> --> +</body> +</html> diff --git a/content_server/install.sh b/content_server/install.sh new file mode 100755 index 0000000..76b4997 --- /dev/null +++ b/content_server/install.sh @@ -0,0 +1,12 @@ +#/bin/bash +sudo apt-get install nginx +echo "Configuring /etc/nginx/sites-available/default" +sudo chmod 777 /etc/nginx/sites-available/default +echo 'server { + location /images/ { + root /var/www; + } +}' >> /etc/nginx/sites-available/default +echo "mkdir & chmod /var/www/images" +sudo mkdir /var/www/images/ +sudo chmod 777 /var/www/images/ diff --git a/content_server/package.json b/content_server/package.json new file mode 100644 index 0000000..c7d2d96 --- /dev/null +++ b/content_server/package.json @@ -0,0 +1,17 @@ +{ + "name": "tizen-firmware-rest-api-server", + "version": "0.0.1", + "main": "apiserver.js", + "dependencies": { + "express": "4.14.x", + "body-parser": "1.16.x", + "sqlite3": "3.1.x", + "ref": "1.3.x", + "ffi": "2.2.x", + "hashmap": "2.0.x", + "child_process": "1.0.x", + "request" : "2.81.x", + "multer" : "1.3.x", + "ip" : "1.1.x" + } +} diff --git a/content_server/ss_bsdiff b/content_server/ss_bsdiff Binary files differnew file mode 100755 index 0000000..107ae6d --- /dev/null +++ b/content_server/ss_bsdiff diff --git a/content_server/ss_bspatch b/content_server/ss_bspatch Binary files differnew file mode 100755 index 0000000..956d75d --- /dev/null +++ b/content_server/ss_bspatch diff --git a/content_server/sub.js b/content_server/sub.js new file mode 100644 index 0000000..fd8146a --- /dev/null +++ b/content_server/sub.js @@ -0,0 +1,33 @@ +const webpath = "/var/www/images" +const exec = require('child_process').exec; +var errmsg; + +process.on('message', function(m) { + console.log("message:",m); + console.log("old_ver:",m.old_ver); + console.log("old_file:",m.old_file); + console.log("new_file:",m.new_file); + var patch_name = "patch_" + m.old_ver + "-" + m.new_ver; + var patch_file = webpath + "/" + patch_name; + console.log("patch:", patch_file); + var cmd = __dirname + "/ss_bsdiff" + " " + m.old_file + " " + m.new_file + " "+ patch_file; + var cmd2 = ";chmod 755 " + patch_file; + console.log(cmd); + exec(cmd+cmd2, function(error) { + if (error) { + console.log(error); + errmsg = error; + // res.sendStatus(500); + } else { + var resp = {}; + resp.old_ver = m.old_ver; + resp.new_ver = m.new_ver; + resp.errmsg = "success"; + resp.patch_name = patch_name; + console.log(resp); + process.send(resp); + // process.disconnect(); + } + }); +}); + diff --git a/inc/iotivity/AttributeValue.h b/inc/iotivity/AttributeValue.h new file mode 100644 index 0000000..3315356 --- /dev/null +++ b/inc/iotivity/AttributeValue.h @@ -0,0 +1,156 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the definition of the internally used type + * AttributeValue. + */ + +#ifndef OC_ATTRIBUTEVALUE_H_ +#define OC_ATTRIBUTEVALUE_H_ + +// These defines are required to get the boost::variant to hold more than 20 items. +// documentation requires that you use a power of 10 +#define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS +#define BOOST_MPL_LIMIT_LIST_SIZE 30 +#define BOOST_MPL_LIMIT_VECTOR_SIZE 30 +#include <boost/variant.hpp> +#include <iosfwd> +#include <OCUtilities.h> +namespace OC +{ + class OCRepresentation; + + struct NullType{}; + + // Since null needs to be encoded in a special fashion in JSON, the encoder + // needs to know the index of the NullType Sentinel Any time the code does a special + // case for the NullType, we use the AttributeValueNullIndex. This MUST be kept up to date + // with the variant's which() for NullType. + static const int AttributeValueNullIndex = 0; + typedef boost::variant< + NullType, // Note: this handles the null-type and must match the above static const + int, + double, + bool, + std::string, + OC::OCRepresentation, + OCByteString, + + // Sequences: + std::vector<int>, + std::vector<double>, + std::vector<bool>, + std::vector<std::string>, + std::vector<OC::OCRepresentation>, + std::vector<OCByteString>, + + // Nested sequences: + std::vector<std::vector<int>>, + std::vector<std::vector<std::vector<int>>>, + + std::vector<std::vector<double>>, + std::vector<std::vector<std::vector<double>>>, + + std::vector<std::vector<bool>>, + std::vector<std::vector<std::vector<bool>>>, + + std::vector<std::vector<std::string>>, + std::vector<std::vector<std::vector<std::string>>>, + + std::vector<std::vector<OC::OCRepresentation>>, + std::vector<std::vector<std::vector<OC::OCRepresentation>>>, + + std::vector<std::vector<OCByteString>>, + std::vector<std::vector<std::vector<OCByteString>>>, + + // used for binary data type + std::vector<uint8_t> + > AttributeValue; + + enum class AttributeType + { + Null, + Integer, + Double, + Boolean, + String, + OCRepresentation, + Vector, + Binary, + OCByteString + }; + + template<typename T> + struct AttributeTypeConvert{}; + + template<> + struct AttributeTypeConvert<NullType> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::Null; + }; + + template<> + struct AttributeTypeConvert<int> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::Integer; + }; + + template<> + struct AttributeTypeConvert<double> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::Double; + }; + + template<> + struct AttributeTypeConvert<bool> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::Boolean; + }; + + template<> + struct AttributeTypeConvert<std::string> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::String; + }; + + template<> + struct AttributeTypeConvert<OCRepresentation> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::OCRepresentation; + }; + + template<> + struct AttributeTypeConvert<OCByteString> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::OCByteString; + }; + + template<> + struct AttributeTypeConvert<std::vector<uint8_t>> + { + BOOST_STATIC_CONSTEXPR AttributeType type = AttributeType::Binary; + }; + + std::ostream& operator << (std::ostream& os, const AttributeType at); +} +#endif // OC_ATTRIBUTEVALUE_H_ diff --git a/inc/iotivity/CAManager.h b/inc/iotivity/CAManager.h new file mode 100644 index 0000000..3a19a07 --- /dev/null +++ b/inc/iotivity/CAManager.h @@ -0,0 +1,90 @@ +/* **************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef CA_MANAGER_H_ +#define CA_MANAGER_H_ + +#include <OCApi.h> + +namespace OC +{ + /** + * This namespace contains the main entrance/functionality to monitoring network changes. + * It may be used with OC::CAManager::functionName. To set a custom callback function, + * the implementer must make a call to CAManager::setNetworkMonitorHandler. + */ + namespace CAManager + { + // typedef to get adapter status changes from CA. + typedef std::function<void(const std::string&, OCConnectivityType, + bool)> ConnectionChangedCallback; + + // typedef to get connection status changes from CA. + typedef std::function<void(OCTransportAdapter, bool)> AdapterChangedCallback; + + /** + * Set network monitoring handler. + * @param adapterHandler adapter state change handler to handle changes for + * any transport types. + * @param connectionHandler connection state change handler to handle changes for + * connection with remote devices. + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult setNetworkMonitorHandler(AdapterChangedCallback adapterHandler, + ConnectionChangedCallback connectionHandler); + + /** + * Set port number to use. + * @param adapter transport adapter type to assign the specified port number. + * @param flag transport flag information. + * @param port the specified port number to use. + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult setPortNumberToAssign(OCTransportAdapter adapter, + OCTransportFlags flag, uint16_t port); + + /** + * Get the assigned port number. + * @param adapter transport adapter type to get the opened port number. + * @param flag transport flag information. + * @return Returns currently assigned port number. + */ + uint16_t getAssignedPortNumber(OCTransportAdapter adapter, OCTransportFlags flag); + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + /** + * Select the cipher suite for TLS/DTLS handshake. + * @param cipher cipher suite (Note : Make sure endianness). + * 0x35 : TLS_RSA_WITH_AES_256_CBC_SHA + * 0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA + * 0xC037 : TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * 0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 + * @param adapter transport adapter type. + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult setCipherSuite(const uint16_t cipher, OCTransportAdapter adapter); +#endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__) + } +} + +#endif // CA_MANAGER_H_ + + + diff --git a/inc/iotivity/IClientWrapper.h b/inc/iotivity/IClientWrapper.h new file mode 100644 index 0000000..b453068 --- /dev/null +++ b/inc/iotivity/IClientWrapper.h @@ -0,0 +1,158 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_I_CLIENT_WRAPPER_H_ +#define OC_I_CLIENT_WRAPPER_H_ + +#include <memory> +#include <string> +#include <OCApi.h> + +namespace OC +{ + class OCPlatform_impl; + + class IClientWrapper : public std::enable_shared_from_this<IClientWrapper> + { + protected: + + public: + typedef std::shared_ptr<IClientWrapper> Ptr; + + IClientWrapper() + {} + + virtual OCStackResult ListenForResource(const std::string& serviceUrl, + const std::string& resourceType, + OCConnectivityType connectivityType, + FindCallback& callback, + QualityOfService QoS) = 0; + + virtual OCStackResult ListenForResource2(const std::string& serviceUrl, + const std::string& resourceType, + OCConnectivityType connectivityType, + FindResListCallback& callback, + QualityOfService QoS) = 0; + + virtual OCStackResult ListenErrorForResource(const std::string& serviceUrl, + const std::string& resourceType, + OCConnectivityType connectivityType, + FindCallback& callback, + FindErrorCallback& errorCallback, + QualityOfService QoS) = 0; + + virtual OCStackResult ListenForDevice(const std::string& serviceUrl, + const std::string& deviceURI, + OCConnectivityType connectivityType, + FindDeviceCallback& callback, + QualityOfService QoS) = 0; + + virtual OCStackResult GetResourceRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const QueryParamsMap& queryParams, + const HeaderOptions& headerOptions, + OCConnectivityType connectivityType, + GetCallback& callback, QualityOfService QoS)=0; + + virtual OCStackResult PutResourceRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const OCRepresentation& rep, const QueryParamsMap& queryParams, + const HeaderOptions& headerOptions, + PutCallback& callback, QualityOfService QoS) = 0; + + virtual OCStackResult PostResourceRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const OCRepresentation& rep, const QueryParamsMap& queryParams, + const HeaderOptions& headerOptions, + OCConnectivityType connectivityType, + PostCallback& callback, QualityOfService QoS) = 0; + + virtual OCStackResult DeleteResource( + const OCDevAddr& devAddr, + const std::string& uri, + const HeaderOptions& headerOptions, + OCConnectivityType connectivityType, + DeleteCallback& callback, QualityOfService QoS) = 0; + + virtual OCStackResult ObserveResource( + ObserveType observeType, OCDoHandle* handle, + const OCDevAddr& devAddr, + const std::string& uri, + const QueryParamsMap& queryParams, + const HeaderOptions& headerOptions, ObserveCallback& callback, + QualityOfService QoS)=0; + + virtual OCStackResult CancelObserveResource( + OCDoHandle handle, + const std::string& host, + const std::string& uri, + const HeaderOptions& headerOptions, + QualityOfService QoS)=0; + + virtual OCStackResult SubscribePresence(OCDoHandle* handle, + const std::string& host, + const std::string& resourceType, + OCConnectivityType connectivityType, + SubscribeCallback& presenceHandler)=0; + + virtual OCStackResult UnsubscribePresence(OCDoHandle handle) =0; + +#ifdef WITH_CLOUD + virtual OCStackResult SubscribeDevicePresence(OCDoHandle* handle, + const std::string& host, + const std::vector<std::string>& di, + OCConnectivityType connectivityType, + ObserveCallback& callback) = 0; +#endif + + virtual OCStackResult GetDefaultQos(QualityOfService& qos) = 0; + + virtual OCStackResult FindDirectPairingDevices(unsigned short waittime, + GetDirectPairedCallback& callback) = 0; + + virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& callback) = 0; + + virtual OCStackResult DoDirectPairing(std::shared_ptr< OCDirectPairing > peer, + const OCPrm_t& pmSel, const std::string& pinNumber, + DirectPairingCallback& resultCallback) = 0; + +#ifdef WITH_MQ + virtual OCStackResult ListenForMQTopic( + const OCDevAddr& devAddr, + const std::string& resourceUri, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + MQTopicCallback& callback, QualityOfService QoS) = 0; + + virtual OCStackResult PutMQTopicRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const OCRepresentation& rep, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + MQTopicCallback& callback, QualityOfService QoS) = 0; +#endif + virtual ~IClientWrapper(){} + }; +} + +#endif + diff --git a/inc/iotivity/IServerWrapper.h b/inc/iotivity/IServerWrapper.h new file mode 100644 index 0000000..d49dc1b --- /dev/null +++ b/inc/iotivity/IServerWrapper.h @@ -0,0 +1,83 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_I_SERVER_WRAPPER_H_ +#define OC_I_SERVER_WRAPPER_H_ + +#include <memory> +#include <string> + +#include <OCResourceRequest.h> +#include <OCResourceResponse.h> +#include <OCException.h> +#include <OCApi.h> + +namespace OC +{ + class IServerWrapper + { + protected: + + public: + typedef std::shared_ptr<IServerWrapper> Ptr; + + IServerWrapper() + {} + + virtual ~IServerWrapper(){}; + + virtual OCStackResult registerResource( + OCResourceHandle& resourceHandle, + std::string& resourceURI, + const std::string& resourceTypeName, + const std::string& resourceInterface, + EntityHandler& entityHandler, + uint8_t resourceProperty) = 0; + + virtual OCStackResult registerDeviceInfo( + const OCDeviceInfo deviceInfo) = 0; + + virtual OCStackResult registerPlatformInfo( + const OCPlatformInfo PlatformInfo) = 0; + + virtual OCStackResult unregisterResource( + const OCResourceHandle& resourceHandle) = 0; + virtual OCStackResult bindTypeToResource( + const OCResourceHandle& resourceHandle, + const std::string& resourceTypeName) = 0; + + virtual OCStackResult bindInterfaceToResource( + const OCResourceHandle& resourceHandle, + const std::string& resourceInterfaceName) = 0; + + virtual OCStackResult startPresence(const unsigned int seconds) = 0; + + virtual OCStackResult stopPresence() = 0; + + virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler) = 0; + + virtual OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse) = 0; + + virtual OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value) = 0; + virtual OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value) = 0; + }; +} + +#endif diff --git a/inc/iotivity/InProcClientWrapper.h b/inc/iotivity/InProcClientWrapper.h new file mode 100644 index 0000000..bbf6a38 --- /dev/null +++ b/inc/iotivity/InProcClientWrapper.h @@ -0,0 +1,248 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_IN_PROC_CLIENT_WRAPPER_H_ +#define OC_IN_PROC_CLIENT_WRAPPER_H_ + +#include <thread> +#include <mutex> +#include <sstream> +#include <iostream> + +#include <OCApi.h> +#include <IClientWrapper.h> +#include <InitializeException.h> +#include <ResourceInitException.h> + +namespace OC +{ + namespace ClientCallbackContext + { + struct GetContext + { + GetCallback callback; + GetContext(GetCallback cb) : callback(cb){} + }; + + struct SetContext + { + PutCallback callback; + SetContext(PutCallback cb) : callback(cb){} + }; + + struct ListenContext + { + FindCallback callback; + std::weak_ptr<IClientWrapper> clientWrapper; + + ListenContext(FindCallback cb, std::weak_ptr<IClientWrapper> cw) + : callback(cb), clientWrapper(cw){} + }; + + struct ListenContext2 + { + FindResListCallback callback; + std::weak_ptr<IClientWrapper> clientWrapper; + + ListenContext2(FindResListCallback cb, std::weak_ptr<IClientWrapper> cw) + : callback(cb), clientWrapper(cw){} + }; + + struct ListenErrorContext + { + FindCallback callback; + FindErrorCallback errorCallback; + std::weak_ptr<IClientWrapper> clientWrapper; + + ListenErrorContext(FindCallback cb1, FindErrorCallback cb2, + std::weak_ptr<IClientWrapper> cw) + : callback(cb1), errorCallback(cb2), clientWrapper(cw){} + }; + + struct DeviceListenContext + { + FindDeviceCallback callback; + IClientWrapper::Ptr clientWrapper; + DeviceListenContext(FindDeviceCallback cb, IClientWrapper::Ptr cw) + : callback(cb), clientWrapper(cw){} + }; + + struct SubscribePresenceContext + { + SubscribeCallback callback; + SubscribePresenceContext(SubscribeCallback cb) : callback(cb){} + }; + + struct DeleteContext + { + DeleteCallback callback; + DeleteContext(DeleteCallback cb) : callback(cb){} + }; + + struct ObserveContext + { + ObserveCallback callback; + ObserveContext(ObserveCallback cb) : callback(cb){} + }; + + struct DirectPairingContext + { + DirectPairingCallback callback; + DirectPairingContext(DirectPairingCallback cb) : callback(cb){} + + }; + +#ifdef WITH_MQ + struct MQTopicContext + { + MQTopicCallback callback; + std::weak_ptr<IClientWrapper> clientWrapper; + MQTopicContext(MQTopicCallback cb, std::weak_ptr<IClientWrapper> cw) + : callback(cb), clientWrapper(cw){} + }; +#endif + } + + class InProcClientWrapper : public IClientWrapper + { + + public: + + InProcClientWrapper(std::weak_ptr<std::recursive_mutex> csdkLock, + PlatformConfig cfg); + virtual ~InProcClientWrapper(); + + virtual OCStackResult ListenForResource(const std::string& serviceUrl, + const std::string& resourceType, OCConnectivityType transportFlags, + FindCallback& callback, QualityOfService QoS); + + virtual OCStackResult ListenForResource2(const std::string& serviceUrl, + const std::string& resourceType, OCConnectivityType transportFlags, + FindResListCallback& callback, QualityOfService QoS); + + virtual OCStackResult ListenErrorForResource(const std::string& serviceUrl, + const std::string& resourceType, OCConnectivityType transportFlags, + FindCallback& callback, FindErrorCallback& errorCallback, QualityOfService QoS); + + virtual OCStackResult ListenForDevice(const std::string& serviceUrl, + const std::string& deviceURI, OCConnectivityType transportFlags, + FindDeviceCallback& callback, QualityOfService QoS); + + virtual OCStackResult GetResourceRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + OCConnectivityType connectivityType, + GetCallback& callback, QualityOfService QoS); + + virtual OCStackResult PutResourceRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const OCRepresentation& attributes, const QueryParamsMap& queryParams, + const HeaderOptions& headerOptions, PutCallback& callback, QualityOfService QoS); + + virtual OCStackResult PostResourceRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const OCRepresentation& attributes, const QueryParamsMap& queryParams, + const HeaderOptions& headerOptions, OCConnectivityType connectivityType, + PostCallback& callback, QualityOfService QoS); + + virtual OCStackResult DeleteResource( + const OCDevAddr& devAddr, + const std::string& uri, + const HeaderOptions& headerOptions, + OCConnectivityType connectivityType, + DeleteCallback& callback, QualityOfService QoS); + + virtual OCStackResult ObserveResource( + ObserveType observeType, OCDoHandle* handle, + const OCDevAddr& devAddr, + const std::string& uri, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + ObserveCallback& callback, QualityOfService QoS); + + virtual OCStackResult CancelObserveResource( + OCDoHandle handle, + const std::string& host, + const std::string& uri, + const HeaderOptions& headerOptions, QualityOfService QoS); + + virtual OCStackResult SubscribePresence( + OCDoHandle *handle, + const std::string& host, + const std::string& resourceType, + OCConnectivityType transportFlags, + SubscribeCallback& presenceHandler); + + virtual OCStackResult UnsubscribePresence(OCDoHandle handle); + +#ifdef WITH_CLOUD + virtual OCStackResult SubscribeDevicePresence(OCDoHandle* handle, + const std::string& host, + const std::vector<std::string>& di, + OCConnectivityType connectivityType, + ObserveCallback& callback); +#endif + + OCStackResult GetDefaultQos(QualityOfService& QoS); + + virtual OCStackResult FindDirectPairingDevices(unsigned short waittime, + GetDirectPairedCallback& callback); + + virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& callback); + + virtual OCStackResult DoDirectPairing(std::shared_ptr<OCDirectPairing> peer, const OCPrm_t& pmSel, + const std::string& pinNumber, DirectPairingCallback& resultCallback); + +#ifdef WITH_MQ + virtual OCStackResult ListenForMQTopic( + const OCDevAddr& devAddr, + const std::string& resourceUri, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + MQTopicCallback& callback, QualityOfService QoS); + + virtual OCStackResult PutMQTopicRepresentation( + const OCDevAddr& devAddr, + const std::string& uri, + const OCRepresentation& rep, + const QueryParamsMap& queryParams, const HeaderOptions& headerOptions, + MQTopicCallback& callback, QualityOfService QoS); +#endif + + private: + void listeningFunc(); + std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams); + std::string assembleSetResourceUri(std::string uri, const QueryParamsList& queryParams); + OCPayload* assembleSetResourcePayload(const OCRepresentation& attributes); + OCHeaderOption* assembleHeaderOptions(OCHeaderOption options[], + const HeaderOptions& headerOptions); + void convert(const OCDPDev_t *list, PairedDevices& dpList); + std::thread m_listeningThread; + bool m_threadRun; + std::weak_ptr<std::recursive_mutex> m_csdkLock; + + private: + PlatformConfig m_cfg; + }; +} + +#endif + diff --git a/inc/iotivity/InProcServerWrapper.h b/inc/iotivity/InProcServerWrapper.h new file mode 100644 index 0000000..0ea25e8 --- /dev/null +++ b/inc/iotivity/InProcServerWrapper.h @@ -0,0 +1,83 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_IN_PROC_SERVER_WRAPPER_H_ +#define OC_IN_PROC_SERVER_WRAPPER_H_ + +#include <thread> +#include <mutex> + +#include <IServerWrapper.h> + +namespace OC +{ + class InProcServerWrapper : public IServerWrapper + { + public: + InProcServerWrapper( + std::weak_ptr<std::recursive_mutex> csdkLock, + PlatformConfig cfg); + virtual ~InProcServerWrapper(); + + virtual OCStackResult registerResource( + OCResourceHandle& resourceHandle, + std::string& resourceURI, + const std::string& resourceTypeName, + const std::string& resourceInterface, + EntityHandler& entityHandler, + uint8_t resourceProperty); + + virtual OCStackResult registerDeviceInfo( + const OCDeviceInfo deviceInfo); + + virtual OCStackResult registerPlatformInfo( + const OCPlatformInfo PlatformInfo); + + virtual OCStackResult unregisterResource( + const OCResourceHandle& resourceHandle); + + virtual OCStackResult bindTypeToResource( + const OCResourceHandle& resourceHandle, + const std::string& resourceTypeName); + + virtual OCStackResult bindInterfaceToResource( + const OCResourceHandle& resourceHandle, + const std::string& resourceInterface); + + virtual OCStackResult startPresence(const unsigned int seconds); + + virtual OCStackResult stopPresence(); + + virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler); + + virtual OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse); + + virtual OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value); + virtual OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value); + + private: + void processFunc(); + std::thread m_processThread; + bool m_threadRun; + std::weak_ptr<std::recursive_mutex> m_csdkLock; + }; +} + +#endif diff --git a/inc/iotivity/InitializeException.h b/inc/iotivity/InitializeException.h new file mode 100644 index 0000000..ab5282f --- /dev/null +++ b/inc/iotivity/InitializeException.h @@ -0,0 +1,39 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_INITIALIZE_EXCEPTION_H_ +#define OC_INITIALIZE_EXCEPTION_H_ + +#include <stdexcept> +#include "StringConstants.h" + +namespace OC +{ + class InitializeException : public OC::OCException + { + public: + InitializeException(const std::string& msg, OCStackResult reasonCode): + OC::OCException(msg, reasonCode) + { + } + }; +} + +#endif diff --git a/inc/iotivity/OCAccountManager.h b/inc/iotivity/OCAccountManager.h new file mode 100644 index 0000000..11fa50b --- /dev/null +++ b/inc/iotivity/OCAccountManager.h @@ -0,0 +1,356 @@ +/* **************************************************************** + * + * Copyright 2016 Samsung Electronics All Rights Reserved. + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************/ + +#ifndef OC_ACCOUNT_MANAGER_H_ +#define OC_ACCOUNT_MANAGER_H_ + +#include <map> + +#include <OCApi.h> +#include <IClientWrapper.h> +#include <InProcClientWrapper.h> + +namespace OC +{ + class OCAccountManager + { + friend class OCPlatform_impl; + + public: + typedef std::shared_ptr<OCAccountManager> Ptr; + + OCAccountManager(OCAccountManager&&) = default; + OCAccountManager(const OCAccountManager&) = delete; + OCAccountManager& operator=(OCAccountManager&&) = delete; + OCAccountManager& operator=(const OCAccountManager&) = delete; + + virtual ~OCAccountManager(void); + + /** + * Function to get the host address of account server. + * + * @return std::string host address + */ + std::string host() const; + + /** + * Function to get the connectivity type for account server. + * + * @return enum connectivity type (flags and adapter) + */ + OCConnectivityType connectivityType() const; + + /** + * Function for account registration to account server. + * + * @param authProvider Provider name used for authentication. + * @param authCode The authorization code obtained by using an authorization server + * as an intermediary between the client and resource owner. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult signUp(const std::string& authProvider, + const std::string& authCode, + PostCallback cloudConnectHandler); + + /** + * Overload + * + * @param authProvider Provider name used for authentication. + * @param authCode The authorization code obtained by using an authorization server + * as an intermediary between the client and resource owner. + * @param options The option values depends on auth provider. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult signUp(const std::string& authProvider, + const std::string& authCode, + const QueryParamsMap& options, + PostCallback cloudConnectHandler); + + /** + * Function for sign-in to account server. + * + * @param userUuid Identifier of the user obtained by account registration. + * @param accessToken Identifier of the resource obtained by account registration. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult signIn(const std::string& userUuid, + const std::string& accessToken, + PostCallback cloudConnectHandler); + + /** + * Function for sign-out to account server. + * + * @param accessToken Identifier of the resource obtained by account registration. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult signOut(const std::string& accessToken, + PostCallback cloudConnectHandler); + + /** + * Function for refresh access token to account server. + * + * @param userUuid Identifier of the user obtained by account registration. + * @param refreshToken Refresh token used for access token refresh. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult refreshAccessToken(const std::string& userUuid, + const std::string& refreshToken, + PostCallback cloudConnectHandler); + + /** + * Function to get information of the user to account server. + * + * @param queryParams Map that has a query key and value for specific users. + * Account server can response information of more than one user. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult searchUser(const QueryParamsMap& queryParams, + GetCallback cloudConnectHandler); + + /** + * Function to delete the device registered on the account signed-in. + * + * @param accessToken Identifier of the resource obtained by account registration. + * @param deviceId Device ID to delete. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult deleteDevice(const std::string& accessToken, + const std::string& deviceId, + DeleteCallback cloudConnectHandler); + + /** + * Function to create a group on account server. + * + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult createGroup(PostCallback cloudConnectHandler); + + /** + * Overload + * + * @param queryParams Map that has optional properties and values to create a group. + * Defined properties on the OCF spec are [gname, parent] so far. + * (2016/10/19) + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult createGroup(const QueryParamsMap& queryParams, + PostCallback cloudConnectHandler); + + /** + * Function to delete the group from account server. + * + * @param groupId Group ID to delete. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult deleteGroup(const std::string& groupId, + DeleteCallback cloudConnectHandler); + + /** + * Function to get infomation of all your group from account server. + * + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + + OCStackResult getGroupInfoAll(GetCallback cloudConnectHandler); + + /** + * Function to get information of the specific group from account server. + * + * @param groupId Group ID to get information. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult getGroupInfo(const std::string& groupId, + GetCallback cloudConnectHandler); + + /** + * Function to add values for properties to the group on account server. + * + * @param groupId Group ID to add property values. + * @param propertyValue OCRepresentation info that has pairs of property and value. + * Defined properties on the OCF spec are [members, masters, devices, + * resources, links] so far. (2016/10/19) + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult addPropertyValueToGroup(const std::string& groupId, + const OCRepresentation propertyValue, + PostCallback cloudConnectHandler); + + /** + * Function to delete values for properties from the group on account server. + * + * @param groupId Group ID to delete information. + * @param propertyValue OCRepresentation info that has pairs of property and value. + * Defined properties on the OCF spec are [members, masters, devices, + * resources, links] so far. (2016/10/19) + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult deletePropertyValueFromGroup(const std::string& groupId, + const OCRepresentation propertyValue, + PostCallback cloudConnectHandler); + + /** + * Function to update values for properties on the group on account server. + * It completely replaces existing values for specific properties. + * + * @param groupId Group ID to add devices. + * @param propertyValue OCRepresentation info that has pairs of property and value. + * Defined properties on the OCF spec are [members, gname, owner, + * masters, devices, resources, latitude, longitude, radius, + * backgroundImage] so far. (2016/10/19) + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult updatePropertyValueOnGroup(const std::string& groupId, + const OCRepresentation propertyValue, + PostCallback cloudConnectHandler); + + /** + * Function to register observe to group resource on account server. + * You can receive a notify when any value of property get changed in the group you joined. + * + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult observeGroup(ObserveCallback cloudConnectHandler); + + /** + * Function to cancel observe to group resource on account server. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult cancelObserveGroup(); + + /** + * Function to register observe to invitation resource on account server. + * You can receive a notify when you send or receive a invitation. + * Sending a invitation will be notified as 'invite' and Receiving will be as 'invited'. + * If you receive a invitation from other user, you should call 'replyToInvitation' to + * delete the invitation on account server, otherwise it will remain on the server. + * + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult observeInvitation(ObserveCallback cloudConnectHandler); + + /** + * Function to cancel observe to invitation resource on account server. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult cancelObserveInvitation(); + + /** + * Function to send a invitation to invite a user into a group. + * + * @param groupId Group ID for inviting. + * @param userUuid Identifier of the user to invite. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult sendInvitation(const std::string& groupId, + const std::string& userUuid, + PostCallback cloudConnectHandler); + + /** + * Function to cancel a invitation you has sent on account server before the invited user + * replies. + * + * @param groupId Group ID to cancel a invitation. + * @param userUuid Identifier of the user to cancel a invitation. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult cancelInvitation(const std::string& groupId, + const std::string& userUuid, + DeleteCallback cloudConnectHandler); + + /** + * Function to reply to the invitation that you has received. + * If you set accept as true, you will join the group as a member and the invitation + * will be deleted on account server. + * If false, only the invitation will be deleted. + * + * @param groupId Group ID to delete a invitation. + * @param accept boolean whether to join the group or not. + * @param cloudConnectHandler Callback function that will get the result of the operation. + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult replyToInvitation(const std::string& groupId, + const bool accept, + DeleteCallback cloudConnectHandler); + + private: + std::weak_ptr<IClientWrapper> m_clientWrapper; + std::string m_deviceID; + std::string m_host; + std::string m_userUuid; + OCDoHandle m_invitationObserveHandle; + OCDoHandle m_groupObserveHandle; + OCConnectivityType m_connType; + QualityOfService m_defaultQos; + + private: + OCAccountManager(std::weak_ptr<IClientWrapper> clientWrapper, + const std::string& host, + OCConnectivityType connectivityType); + + OCStackResult signInOut(const std::string& userUuid, + const std::string& accessToken, + bool isSignIn, + PostCallback cloudConnectHandler); + }; +} // namespace OC + +#endif // OC_ACCOUNT_MANAGER_H_ + diff --git a/inc/iotivity/OCApi.h b/inc/iotivity/OCApi.h new file mode 100644 index 0000000..ff2d212 --- /dev/null +++ b/inc/iotivity/OCApi.h @@ -0,0 +1,306 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_OCAPI_H_ +#define OC_OCAPI_H_ + +#include <string> +#include <sstream> +#include <vector> +#include <map> +#include <memory> +#include <iterator> +#if defined(_MSC_VER) +#include <functional> +#endif + +#include "octypes.h" +#include "OCHeaderOption.h" +#include <OCException.h> +#include "StringConstants.h" +#include "oc_logger.hpp" + +#include <OCRepresentation.h> + +namespace OC +{ + class OCResource; + class OCResourceRequest; + class OCResourceResponse; + class OCDirectPairing; +} // namespace OC + +namespace OC +{ +#if defined(_MSC_VER) + extern std::ostream& oclog(); +#else + typedef boost::iostreams::stream<OC::oc_log_stream> log_target_t; + + namespace detail + { + /* We'll want to provide some sort of explicit hook for custom logging at some + point; until then, this should do nicely (note that since these are lambdas, + later a special target could be captured, allowing much flexibility): */ + auto oclog_target = []() -> log_target_t& + { + static OC::oc_log_stream ols(oc_make_ostream_logger); + static log_target_t os(ols); + + return os; + }; + } // namespace OC::detail + + auto oclog = []() -> boost::iostreams::stream<OC::oc_log_stream>& + { + return detail::oclog_target(); + }; +#endif +} // namespace OC + +namespace OC +{ + + enum class OCPlatformStatus + { + PlatformUp, + PlatformDown + }; + + enum class OCAdvertisementStatus + { + None + }; + + typedef std::string URI; + + enum class ServiceType + { + InProc, + OutOfProc + }; + + /** + * Host Mode of Operation. + */ + enum class ModeType + { + Server, + Client, + Both, + Gateway /**< Client server mode along with routing capabilities.*/ + }; + + /** + * Quality of Service attempts to abstract the guarantees provided by the underlying transport + * protocol. The precise definitions of each quality of service level depend on the + * implementation. In descriptions below are for the current implementation and may changed + * over time. + */ + enum class QualityOfService : uint8_t + { + /** Packet delivery is best effort. */ + LowQos = OC_LOW_QOS, + + /** Packet delivery is best effort. */ + MidQos = OC_MEDIUM_QOS, + + /** Acknowledgments are used to confirm delivery. */ + HighQos = OC_HIGH_QOS, + + /** No Quality is defined, let the stack decide. */ + NaQos = OC_NA_QOS + }; + + /** + * Data structure to provide the configuration. + */ + struct PlatformConfig + { + /** indicate InProc or OutOfProc. */ + ServiceType serviceType; + + /** indicate whether we want to do server, client or both. */ + ModeType mode; + + /** default flags for server. */ + OCConnectivityType serverConnectivity; + + /** default flags for client. */ + OCConnectivityType clientConnectivity; + + /** not used. */ + std::string ipAddress; + + /** not used. */ + uint16_t port; + + /** indicate Quality of Service : LowQos, MidQos,HighQos and NaQos(No quality Defined). */ + QualityOfService QoS; + + /** persistant storage Handler structure (open/read/write/close/unlink). */ + OCPersistentStorage *ps; + + public: + PlatformConfig() + : serviceType(ServiceType::InProc), + mode(ModeType::Both), + serverConnectivity(CT_DEFAULT), + clientConnectivity(CT_DEFAULT), + ipAddress("0.0.0.0"), + port(0), + QoS(QualityOfService::NaQos), + ps(nullptr) + {} + PlatformConfig(const ServiceType serviceType_, + const ModeType mode_, + OCConnectivityType serverConnectivity_, + OCConnectivityType clientConnectivity_, + const QualityOfService QoS_, + OCPersistentStorage *ps_ = nullptr) + : serviceType(serviceType_), + mode(mode_), + serverConnectivity(serverConnectivity_), + clientConnectivity(clientConnectivity_), + ipAddress(""), + port(0), + QoS(QoS_), + ps(ps_) + {} + // for backward compatibility + PlatformConfig(const ServiceType serviceType_, + const ModeType mode_, + const std::string& ipAddress_, + const uint16_t port_, + const QualityOfService QoS_, + OCPersistentStorage *ps_ = nullptr) + : serviceType(serviceType_), + mode(mode_), + serverConnectivity(CT_DEFAULT), + clientConnectivity(CT_DEFAULT), + ipAddress(ipAddress_), + port(port_), + QoS(QoS_), + ps(ps_) + {} + }; + + enum RequestHandlerFlag + { + RequestFlag = 1 << 1, + ObserverFlag = 1 << 2 + }; + + enum class ObserveType + { + Observe, + ObserveAll + }; + + // Typedef for list of resource handles. + typedef std::vector<OCResourceHandle> ResourceHandles; + + // Typedef for header option vector. + // OCHeaderOption class is in HeaderOption namespace. + typedef std::vector<HeaderOption::OCHeaderOption> HeaderOptions; + + // Typedef for query parameter map. + typedef std::map<std::string, std::string> QueryParamsMap; + + // Typedef for query parameter map with Vector + typedef std::map< std::string, std::vector<std::string> > QueryParamsList; + + // Typedef for list of observation IDs. + typedef std::vector<OCObservationId> ObservationIds; + + enum class ObserveAction + { + ObserveRegister, + ObserveUnregister + }; + + typedef struct + { + // Action associated with observation request + ObserveAction action; + // Identifier for observation being registered/unregistered + OCObservationId obsId; + + OCConnectivityType connectivityType; + std::string address; + uint16_t port; + } ObservationInfo; + + // const strings for different interfaces + + // Default interface + const std::string DEFAULT_INTERFACE = "oic.if.baseline"; + + // Used in discovering (GET) links to other resources of a collection. + const std::string LINK_INTERFACE = "oic.if.ll"; + + // Used in GET, PUT, POST, DELETE methods on links to other resources of a collection. + const std::string BATCH_INTERFACE = "oic.if.b"; + + // Used in GET, PUT, POST methods on links to other remote resources of a group. + const std::string GROUP_INTERFACE = "oic.mi.grp"; + + //Typedef for list direct paired devices + typedef std::vector<std::shared_ptr<OCDirectPairing>> PairedDevices; + + typedef std::function<void(std::shared_ptr<OCResource>)> FindCallback; + + typedef std::function<void(const std::string&, const int)> FindErrorCallback; + + typedef std::function<void(std::vector<std::shared_ptr<OCResource>>)> FindResListCallback; + + typedef std::function<void(const OCRepresentation&)> FindDeviceCallback; + + typedef std::function<void(const OCRepresentation&)> FindPlatformCallback; + + typedef std::function<OCEntityHandlerResult( + const std::shared_ptr<OCResourceRequest>)> EntityHandler; + + typedef std::function<void(OCStackResult, const unsigned int, + const std::string&)> SubscribeCallback; + + typedef std::function<void(const HeaderOptions&, + const OCRepresentation&, const int)> GetCallback; + + typedef std::function<void(const HeaderOptions&, + const OCRepresentation&, const int)> PostCallback; + + typedef std::function<void(const HeaderOptions&, + const OCRepresentation&, const int)> PutCallback; + + typedef std::function<void(const HeaderOptions&, const int)> DeleteCallback; + + typedef std::function<void(const HeaderOptions&, + const OCRepresentation&, const int, const int)> ObserveCallback; + + typedef std::function<void(std::shared_ptr<OCDirectPairing>, OCStackResult)> DirectPairingCallback; + + typedef std::function<void(const PairedDevices&)> GetDirectPairedCallback; + + typedef std::function<void(const int, const std::string&, + std::shared_ptr<OCResource>)> MQTopicCallback; +} // namespace OC + +#endif diff --git a/inc/iotivity/OCCloudProvisioning.hpp b/inc/iotivity/OCCloudProvisioning.hpp new file mode 100755 index 0000000..491f68a --- /dev/null +++ b/inc/iotivity/OCCloudProvisioning.hpp @@ -0,0 +1,139 @@ +//****************************************************************
+//
+// Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef OC_CLOUD_PROVISIONING_CXX_H_
+#define OC_CLOUD_PROVISIONING_CXX_H_
+
+#include <thread>
+
+#include "occloudprovisioning.h"
+#include "OCApi.h"
+#include "OCPlatform_impl.h"
+#include "CAManager.h"
+
+namespace OC
+{
+ typedef std::function<void(OCStackResult result, void *data)> ResponseCallBack;
+ typedef std::function<void(OCStackResult result, std::string aclId)> AclIdResponseCallBack;
+
+ /**
+ * Context to be passed to the underlying stack. This is passed back as argument
+ * to the callback function
+ */
+ struct CloudProvisionContext
+ {
+ ResponseCallBack callback;
+ CloudProvisionContext(ResponseCallBack cb) : callback(cb){}
+ };
+
+ struct AclIdContext
+ {
+ AclIdResponseCallBack callback;
+ AclIdContext(AclIdResponseCallBack cb) : callback(cb){}
+ };
+
+ class OCCloudProvisioning
+ {
+
+ private:
+ OCDevAddr m_devAddr;
+ public:
+
+ /**
+ * API to construct the CloudProvisioning
+ * @param ipAddr address of the cloud server
+ * @param port port of the cloud server
+ */
+ OCCloudProvisioning(std::string& ipAddr, uint16_t port);
+ ~OCCloudProvisioning();
+
+ void setIpAddr(std::string& ipAddr)
+ {
+ memcpy(m_devAddr.addr, ipAddr.c_str(), MAX_ADDR_STR_SIZE);
+ }
+
+ void setPort(uint16_t port)
+ {
+ m_devAddr.port = port;
+ }
+
+ /**
+ * API to Request a certificate from the cloud
+ * @param callback function called by the stack on completion of request
+ * @return ::OC_STACK_OK on Success and other values otherwise
+ */
+ OCStackResult requestCertificate(ResponseCallBack callback);
+
+ /**
+ * API to get ACL ID for the device
+ * @param deviceId device ID for which the Acl ID is requested
+ * @param callback function called by the stack on completion of request
+ * @return ::OC_STACK_OK on Success and other values otherwise
+ */
+ OCStackResult getAclIdByDevice(const std::string& deviceId, AclIdResponseCallBack callback);
+
+ /**
+ * API to get ACL information about the given Acl ID
+ * @param aclId ACL ID for which the Acl information is requested
+ * @param callback function called by the stack on completion of request
+ * @return ::OC_STACK_OK on Success and other values otherwise
+ */
+ OCStackResult getIndividualAclInfo(const std::string& aclId, ResponseCallBack callback);
+
+ /**
+ * API to get certificate revocation list
+ * @param callback function called by the stack on completion of request
+ * @return ::OC_STACK_OK on Success and other values otherwise
+ */
+ OCStackResult getCRL(ResponseCallBack callback);
+
+ /**
+ * API to post the certificate revocation list to cloud
+ * @param thisUpdate thisUpdate [mandatory param]
+ * @param nextUpdate nextUpdate [mandatory param]
+ * @param crl revocation list [optional]
+ * @param serialNumbers [optional]
+ * @param callback function called by the stack on completion of request
+ * @return ::OC_STACK_OK on Success and other values otherwise
+ */
+ OCStackResult postCRL(const std::string& thisUpdate,
+ const std::string& nextUpdate,
+ const OCByteString *crl,
+ const stringArray_t *serialNumbers,
+ ResponseCallBack callback);
+
+ /**
+ * Common callback wrapper for all the callback functions.
+ * @param ctx user context passed to the request API
+ * @param result result of the request performed
+ * @param data response data
+ */
+ static void callbackWrapper(void* ctx, OCStackResult result, void* data);
+
+ /**
+ * Callback wrapper for Acl ID get request
+ * @param ctx user context passed to the request API
+ * @param result result of the request performed
+ * @param data AclID for the device
+ */
+ static void aclIdResponseWrapper(void* ctx, OCStackResult result, void* data);
+ };
+}
+#endif //OC_CLOUD_PROVISIONING_CXX_H_
diff --git a/inc/iotivity/OCDirectPairing.h b/inc/iotivity/OCDirectPairing.h new file mode 100644 index 0000000..3f27b83 --- /dev/null +++ b/inc/iotivity/OCDirectPairing.h @@ -0,0 +1,69 @@ +//****************************************************************** +// +// Copyright 2016 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_DIRECT_PAIRING_H_ +#define OC_DIRECT_PAIRING_H_ +#include <OCApi.h> + +namespace OC +{ + class OCDirectPairing + { + public: + OCDirectPairing(OCDPDev_t *ptr); + /** + * Function to get the host address of direct pairing device. + * + * @return Returns host address in the format + * <coaps>:IP:securePort + */ + std::string getHost(); + + /** + * Function to get the device ID of the direct pairing device. + * + * @return Returns device ID (UUID) + */ + std::string getDeviceID(); + + /** + * Function to get the pairing methods supported by direct pairing device. + * + * @return Returns vector of pairing methods supported. + * DP_NOT_ALLOWED + * DP_PRE_CONFIGURED + * DP_RANDOM_PIN + */ + std::vector<OCPrm_t> getPairingMethods(); + + /** + * Function to get the connectivity Type. + * + * @return Returns connectivity Type + */ + OCConnectivityType getConnType(); + + OCDPDev_t* getDev(); + + private: + OCDPDev_t *m_devPtr; + }; +} +#endif //OC_DIRECT_PAIRING_H_ diff --git a/inc/iotivity/OCException.h b/inc/iotivity/OCException.h new file mode 100644 index 0000000..1d70e7d --- /dev/null +++ b/inc/iotivity/OCException.h @@ -0,0 +1,56 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_EXCEPTION_H_ +#define OC_EXCEPTION_H_ + +#include <stdexcept> +#include <string> +#include <octypes.h> + +namespace OC { + +class OCException : public std::runtime_error +{ + public: + OCException(const std::string& msg, OCStackResult reason = OC_STACK_ERROR) + : std::runtime_error(msg), + m_reason(reason) + {} + + static std::string reason(const OCStackResult sr); + + std::string reason() const + { + return reason(m_reason); + } + + OCStackResult code() const + { + return m_reason; + } + + private: + OCStackResult m_reason; +}; + +} // namespace OC + +#endif diff --git a/inc/iotivity/OCHeaderOption.h b/inc/iotivity/OCHeaderOption.h new file mode 100644 index 0000000..78f9029 --- /dev/null +++ b/inc/iotivity/OCHeaderOption.h @@ -0,0 +1,124 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the declaration of classes and its members related to + * OCHeaderOption. + */ + +#ifndef OC_HEADEROPTION_H_ +#define OC_HEADEROPTION_H_ + +#include <OCException.h> +#include <StringConstants.h> +namespace OC +{ + namespace HeaderOption + { + /** + * @brief OCHeaderOption class allows to create instances which comprises optionID + * and optionData as members. These are used in setting Header options. + * After creating instances of OCHeaderOptions, use setHeaderOptions API + * (in OCResource.h) to set header Options. + * NOTE: HeaderOptionID is an unsigned integer value which MUST be within + * range of 2048 to 3000 inclusive of lower and upper bound + * except for If-Match with empty(num : 1), If-None-Match(num : 5), + * Location-Path(num : 8), Location-Query(num : 20) option. + * HeaderOptions instance creation fails if above condition is not satisfied. + */ + const uint16_t MIN_HEADER_OPTIONID = 2048; + const uint16_t MAX_HEADER_OPTIONID = 3000; + const uint16_t IF_MATCH_OPTION_ID = 1; + const uint16_t IF_NONE_MATCH_OPTION_ID = 5; + const uint16_t LOCATION_PATH_OPTION_ID = 8; + const uint16_t LOCATION_QUERY_OPTION_ID = 20; + + class OCHeaderOption + { + private: + uint16_t m_optionID; + std::string m_optionData; + + public: + /** + * OCHeaderOption constructor + */ + OCHeaderOption(uint16_t optionID, std::string optionData): + m_optionID(optionID), + m_optionData(optionData) + { + if (!(optionID >= MIN_HEADER_OPTIONID && optionID <= MAX_HEADER_OPTIONID) + && optionID != IF_MATCH_OPTION_ID + && optionID != IF_NONE_MATCH_OPTION_ID + && optionID != LOCATION_PATH_OPTION_ID + && optionID != LOCATION_QUERY_OPTION_ID) + { + throw OCException(OC::Exception::OPTION_ID_RANGE_INVALID); + } + } + + virtual ~OCHeaderOption(){} + + OCHeaderOption(const OCHeaderOption&) = default; + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCHeaderOption(OCHeaderOption&& o) + { + std::memmove(this, &o, sizeof(o)); + } +#else + OCHeaderOption(OCHeaderOption&&) = default; +#endif + + OCHeaderOption& operator=(const OCHeaderOption&) = default; + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCHeaderOption& operator=(OCHeaderOption&& o) + { + std::memmove(this, &o, sizeof(o)); + } +#else + OCHeaderOption& operator=(OCHeaderOption&&) = default; +#endif + + /** + * API to get Option ID + * @return unsigned integer option ID + */ + uint16_t getOptionID() const + { + return m_optionID; + } + + /* + * API to get Option data + * @return std::string of option data + */ + std::string getOptionData() const + { + return m_optionData; + } + }; + } // namespace HeaderOption +} // namespace OC + +#endif // OC_HEADEROPTION_H_ diff --git a/inc/iotivity/OCPlatform.h b/inc/iotivity/OCPlatform.h new file mode 100644 index 0000000..9903611 --- /dev/null +++ b/inc/iotivity/OCPlatform.h @@ -0,0 +1,707 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the declaration of classes and its members related to + * OCPlatform. + */ + +#ifndef OC_PLATFORM_H_ +#define OC_PLATFORM_H_ +#include <OCApi.h> +#include <OCPlatform_impl.h> +namespace OC +{ + /** + * This namespace contains the main entrance/functionality of the product. + * It may be used with OC::OCPlatform::functionName. To set a custom configuration, + * the implementer must make a call to OCPlatform::Configure before the first usage + * of a function in this namespace. + */ + namespace OCPlatform + { + /** + * API for overwriting the default configuration of the OCPlatform object. + * @note Any calls made to this AFTER the first call to OCPlatform::Instance + * will have no affect + */ + void Configure(const PlatformConfig& config); + + // typedef for handle to cancel presence info with + typedef OCDoHandle OCPresenceHandle; + + /** + * API for notifying base that resource's attributes have changed. + * + * @param resourceHandle resource handle of the resource + * + * @return Returns ::OC_STACK_OK if success. + * @note This API is for server side only. + * @note OCResourceHandle is defined in ocstack.h + * @note OCStackResult is defined in ocstack.h. + * @see notifyAllObservers(OCResourceHandle, QualityOfService) + */ + OCStackResult notifyAllObservers(OCResourceHandle resourceHandle); + + /** + * @overload + * + * @param resourceHandle resource handle of the resource + * @param QoS the quality of communication + * @see notifyAllObservers(OCResourceHandle) + */ + OCStackResult notifyAllObservers(OCResourceHandle resourceHandle, QualityOfService QoS); + + /** + * API for notifying only specific clients that resource's attributes have changed. + * + * @param resourceHandle resource handle of the resource + * @param observationIds std vector of observationIds. These set of ids are ones which + * which will be notified upon resource change. + * @param responsePtr OCResourceResponse pointer used by app to fill the response for this + * resource change. + * + * @return Returns ::OC_STACK_OK if success. + * @note This API is for server side only. + * @note OCResourceHandle is defined in ocstack.h. + * @note OCStackResult is defined in ocstack.h. + * @see notifyListOfObservers(OCResourceHandle, ObservationIds&, const std::shared_ptr<OCResourceResponse>, QualityOfService) + */ + OCStackResult notifyListOfObservers( + OCResourceHandle resourceHandle, + ObservationIds& observationIds, + const std::shared_ptr<OCResourceResponse> responsePtr); + /** + * @overload + * + * @param resourceHandle resource handle of the resource + * @param observationIds std vector of observationIds. These set of ids are ones which + * which will be notified upon resource change. + * @param responsePtr OCResourceResponse pointer used by app to fill the response for this + * resource change. + * @param QoS the quality of communication + * @see notifyListOfObservers(OCResourceHandle, ObservationIds&, const std::shared_ptr<OCResourceResponse>) + */ + OCStackResult notifyListOfObservers( + OCResourceHandle resourceHandle, + ObservationIds& observationIds, + const std::shared_ptr<OCResourceResponse> responsePtr, + QualityOfService QoS); + + /** + * API for Service and Resource Discovery. + * @note This API applies to client side only. + * + * @param host Host IP Address of a service to direct resource discovery query. If null or + * empty, performs multicast resource discovery query + * @param resourceURI name of the resource. If null or empty, performs search for all + * resource names + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param resourceHandler Handles callbacks, success states and failure states. + * + * Four modes of discovery defined as follows: + * (NULL/Empty, NULL/Empty) - Performs ALL service discovery AND ALL resource + * discovery. + * (NULL/Empty, Not Empty) - Performs query for a filtered/scoped/particular + * resource(s) from ALL services. + * (Not Empty, NULL/Empty) - Performs ALL resource discovery on a particular service. + * (Not Empty, Not Empty) - Performs query for a filtered/scoped/particular + * resource(s) + * from a particular service. + * + * @return Returns ::OC_STACK_OK if success. + * @note First parameter 'host' currently represents an IP address. This will change in + * future and will refer to endpoint interface so that we can refer to other transports such + * as BTH etc. + * @note OCStackResult is defined in ocstack.h. + * @see findResource(const std::string&, const std::string&, OCConnectivityType, FindCallback, QualityOfService) + */ + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler); + /** + * @overload + * + * @param host Host IP Address of a service to direct resource discovery query. If null or + * empty, performs multicast resource discovery query + * @param resourceURI name of the resource. If null or empty, performs search for all + * resource names + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param resourceHandler Handles callbacks, success states and failure states. + * + * Four modes of discovery defined as follows: + * (NULL/Empty, NULL/Empty) - Performs ALL service discovery AND ALL resource + * discovery. + * (NULL/Empty, Not Empty) - Performs query for a filtered/scoped/particular + * resource(s) from ALL services. + * (Not Empty, NULL/Empty) - Performs ALL resource discovery on a particular service. + * (Not Empty, Not Empty) - Performs query for a filtered/scoped/particular + * resource(s) + * from a particular service. + * @param QoS QualityOfService the quality of communication + * @see findResource(const std::string&, const std::string&, OCConnectivityType, FindCallback) + */ + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler, + QualityOfService QoS); + + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler, + FindErrorCallback errorHandler); + + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler, + FindErrorCallback errorHandler, QualityOfService QoS); + + OCStackResult findResourceList(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindResListCallback resourceHandler, + QualityOfService QoS = QualityOfService::LowQos); + + OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value); + OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::vector<std::string>& value); + OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value); + OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::vector<std::string>& value); + /** + * API for Device Discovery + * + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param deviceURI Uri containing address to the virtual device in C Stack + ("/oic/d") + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param deviceInfoHandler device discovery callback + * + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + * @see getDeviceInfo(const std::string&, const std::string&, OCConnectivityType, FindDeviceCallback, QualityOfService) + */ + OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI, + OCConnectivityType connectivityType, FindDeviceCallback deviceInfoHandler); + /** + * @overload + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param deviceURI Uri containing address to the virtual device in C Stack + ("/oic/d") + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param deviceInfoHandler device discovery callback + * @param QoS the quality of communication + * @see getDeviceInfo(const std::string&, const std::string&, OCConnectivityType, FindDeviceCallback) + */ + OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI, + OCConnectivityType connectivityType, FindDeviceCallback deviceInfoHandler, + QualityOfService QoS); + + /** + * API for Platform Discovery + * + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param platformURI Uri containing address to the virtual platform in C Stack + ("/oic/p") + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param platformInfoHandler platform discovery callback + * + * @return Returns ::OC_STACK_OK if success. + * + * @note OCStackResult is defined in ocstack.h. + * @see getPlatformInfo(const std::string&, const std::string&, OCConnectivityType, FindPlatformCallback, QualityOfService) + */ + OCStackResult getPlatformInfo(const std::string& host, const std::string& platformURI, + OCConnectivityType connectivityType, FindPlatformCallback platformInfoHandler); + /** + * @overload + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param platformURI Uri containing address to the virtual platform in C Stack + ("/oic/p") + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param platformInfoHandler platform discovery callback + * @param QoS the quality of communication + * @see getPlatformInfo(const std::string&, const std::string&, OCConnectivityType, FindPlatformCallback) + */ + OCStackResult getPlatformInfo(const std::string& host, const std::string& platformURI, + OCConnectivityType connectivityType, FindPlatformCallback platformInfoHandler, + QualityOfService QoS); + + /** + * This API registers a resource with the server + * @note This API applies to server side only. + * + * @param resourceHandle Upon successful registration, resourceHandle will be filled + * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below + * @param resourceTypeName The resource type. Example: "light" + * @param resourceInterface The resource interface (whether it is collection etc). + * @param entityHandler entity handler callback. + * @param resourceProperty indicates the property of the resource. Defined in ocstack.h. + * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource + * setting resourceProperty as OC_OBSERVABLE will allow observation + * settings resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery and + * observation + * + * @return Returns ::OC_STACK_OK if success. + * @note "a/light" is a relative URI. + * Above relative URI will be prepended (by core) with a host IP + namespace "oic" + * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI" + * Example, a relative URI: 'a/light' will result in a fully qualified URI: + * //192.168.1.1/oic/a/light" + * First parameter can take a relative URI and core will take care of preparing the fully + * qualified URI OR + * first parameter can take fully qualified URI and core will take that as is for further + * operations + * @note OCStackResult is defined in ocstack.h. + * @note entity handler callback : + * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT, + * OC_EH_SLOW and etc in entity handler callback, + * ocstack will be not send response automatically to client + * except for error return value like OC_EH_ERROR + * If you want to send response to client with specific result, + * OCDoResponse API should be called with the result value. + */ + OCStackResult registerResource(OCResourceHandle& resourceHandle, + std::string& resourceURI, + const std::string& resourceTypeName, + const std::string& resourceInterface, + EntityHandler entityHandler, + uint8_t resourceProperty); + + /** + * This API registers a resource with the server + * @note This API applies to server & client side. + * + * @param resourceHandle Upon successful registration, resourceHandle will be filled + * @param resource The instance of OCResource that all data filled. + * + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult registerResource(OCResourceHandle& resourceHandle, + const std::shared_ptr< OCResource > resource); + + /** + * Register Device Info + * + * @param deviceInfo structure containing all the device specific information + * @return Returns ::OC_STACK_OK if no errors and ::OC_STACK_ERROR in case of stack process error + */ + OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo); + + /** + * Register Platform Info + * + * @param platformInfo structure containing all the platform specific information + * @return Returns ::OC_STACK_OK if no errors and ::OC_STACK_ERROR in case of stack process error + */ + OCStackResult registerPlatformInfo(const OCPlatformInfo platformInfo); + + /** + * Set default device entity handler + * + * @param entityHandler entity handler to handle requests for + * any undefined resources or default actions. + * if NULL is passed it removes the device default entity handler. + * @return Returns ::OC_STACK_OK if no errors and ::OC_STACK_ERROR in case of stack process error + * @note entity handler callback : + * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT, + * OC_EH_SLOW and etc in entity handler callback, + * ocstack will be not send response automatically to client + * except for error return value like OC_EH_ERROR + * If you want to send response to client with specific result, + * sendResponse API should be called with the result value. + */ + OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler); + + /** + * This API unregisters a resource with the server + * @note This API applies to server side only. + * + * @param resourceHandle This is the resource handle which we need to unregister from the + * server + * + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult unregisterResource(const OCResourceHandle& resourceHandle); + + /** + * Add a resource to a collection resource. + * + * @param collectionHandle handle to the collection resource + * @param resourceHandle handle to resource to be added to the collection resource + * + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + * @note bindResource must be used only after the both collection resource and + * resource to add under a collections are created and respective handles obtained + * + * @par Example: + * -# registerResource(homeResourceHandle, "a/home", "home", Link_Interface, + * entityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# registerResource(kitchenResourceHandle, "a/kitchen", "kitchen", Link_Interface, + * entityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# bindResource(homeResourceHandle, kitchenResourceHandle); + * @par + * At the end of Step 3, resource "a/home" will contain a reference to "a/kitchen". + */ + OCStackResult bindResource(const OCResourceHandle collectionHandle, + const OCResourceHandle resourceHandle); + + /** + * Add multiple resources to a collection resource. + * + * @param collectionHandle handle to the collection resource + * @param addedResourceHandleList reference to list of resource handles to be added to the + * collection resource + * + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + * @note bindResources must be used only after the both collection resource and + * list of resources to add under a collection are created and respective handles + * obtained. + * + * @par Example: + * -# registerResource(homeResourceHandle, "a/home", "home", Link_Interface, + * homeEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# registerResource(kitchenResourceHandle, "a/kitchen", "kitchen", Link_Interface, + * kitchenEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# registerResource(roomResourceHandle, "a/room", "room", Link_Interface, + * roomEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# std::vector<OCResourceHandle> rList; rList.push_back(kitchenResourceHandle); + * rList.push_back(roomResourceHandle); + * -# bindResource(homeResourceHandle, rList); + * @par + * At the end of Step 5, resource "a/home" will contain a references to "a/kitchen" and + * "a/room" + */ + OCStackResult bindResources(const OCResourceHandle collectionHandle, + const std::vector<OCResourceHandle>& addedResourceHandleList); + + /** + * Unbind a resource from a collection resource. + * + * @param collectionHandle handle to the collection resource + * @param resourceHandle resource handle to be unbound from the collection resource + * + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + * @note unbindResource must be used only after the both collection resource and + * resource to unbind from a collection are created and respective handles obtained + * + * @par Example: + * -# registerResource(homeResourceHandle, "a/home", "home", Link_Interface, + * entityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# registerResource(kitchenResourceHandle, "a/kitchen", "kitchen", Link_Interface, + * entityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# bindResource(homeResourceHandle, kitchenResourceHandle); + * -# unbindResource(homeResourceHandle, kitchenResourceHandle); + * @par + * At the end of Step 4, resource "a/home" will no longer reference "a/kitchen". + */ + OCStackResult unbindResource(const OCResourceHandle collectionHandle, + const OCResourceHandle resourceHandle); + + /** + * Unbind resources from a collection resource. + * + * @param collectionHandle handle to the collection resource + * @param resourceHandleList List of resource handles to be unbound from the collection + * resource + * + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + * @note unbindResources must be used only after the both collection resource and + * list of resources resource to unbind from a collection are created and respective handles + * obtained. + * + * @par Example: + * -# registerResource(homeResourceHandle, "a/home", "home", Link_Interface, + * homeEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# registerResource(kitchenResourceHandle, "a/kitchen", "kitchen", Link_Interface, + * kitchenEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# registerResource(roomResourceHandle, "a/room", "room", Link_Interface, + * roomEntityHandler, OC_DISCOVERABLE | OC_OBSERVABLE); + * -# std::vector<OCResourceHandle> rList; rList.push_back(kitchenResourceHandle); + * rList.push_back(roomResourceHandle); + * -# bindResource(homeResourceHandle, rList); + * -# unbindResources(homeResourceHandle, rList); + * @par + * At the end of Step 6, resource "a/home" will no longer reference to "a/kitchen" and + * "a/room" + */ + OCStackResult unbindResources(const OCResourceHandle collectionHandle, + const std::vector<OCResourceHandle>& resourceHandleList); + + /** + * Binds a type to a particular resource + * @param resourceHandle handle to the resource + * @param resourceTypeName new typename to bind to the resource + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult bindTypeToResource(const OCResourceHandle& resourceHandle, + const std::string& resourceTypeName); + + /** + * Binds an interface to a particular resource + * @param resourceHandle handle to the resource + * @param resourceInterfaceName new interface to bind to the resource + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult bindInterfaceToResource(const OCResourceHandle& resourceHandle, + const std::string& resourceInterfaceName); + + + /** + * Start Presence announcements. + * + * @param ttl time to live + * @par + * If ttl is '0', then the default stack value will be used (60 Seconds). + * If ttl is greater than OC_MAX_PRESENCE_TTL_SECONDS, then the ttl will be set to + * OC_MAX_PRESENCE_TTL_SECONDS. + * @par + * @return Returns ::OC_STACK_OK if success. + * + * Server can call this function when it comes online for the + * first time, or when it comes back online from offline mode, + * or when it re enters network. + * + */ + OCStackResult startPresence(const unsigned int ttl); + + /** + * Stop Presence announcements. + * + * @return Returns ::OC_STACK_OK if success. + * + * Server can call this function when it is terminating, + * going offline, or when going away from network. + * + */ + OCStackResult stopPresence(); + + /** + * subscribes to a server's presence change events. By making this subscription, + * every time a server adds/removes/alters a resource, starts or is intentionally + * stopped (potentially more to be added later). + * + * @param presenceHandle a handle object that can be used to identify this subscription + * request. It can be used to unsubscribe from these events in the future. + * It will be set upon successful return of this method. + * @param host The IP address/addressable name of the server to subscribe to. + * This should be in the format coap://address:port + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param presenceHandler callback function that will receive notifications/subscription + * events + * + * @return Returns ::OC_STACK_OK if success. + * @copydoc subscribePresence(OCPresenceHandle&, const std::string&, resourceType, OCConnectivityType, SubscribeCallback) + */ + OCStackResult subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host, + OCConnectivityType connectivityType, SubscribeCallback presenceHandler); + /** + * @overload + * + * @param presenceHandle a handle object that can be used to identify this subscription + * request. It can be used to unsubscribe from these events in the future. + * It will be set upon successful return of this method. + * @param host The IP address/addressable name of the server to subscribe to. + * This should be in the format coap://address:port + * @param resourceType a resource type specified as a filter for subscription callbacks. + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param presenceHandler callback function that will receive notifications/subscription + * events + * @see subscribePresence(OCPresenceHandle&, const std::string&, OCConnectivityType, SubscribeCallback) + */ + OCStackResult subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host, + const std::string& resourceType, OCConnectivityType connectivityType, + SubscribeCallback presenceHandler); + + /** + * unsubscribes from a previously subscribed server's presence events. Note that + * you may for a short time still receive events from the server since it may take time + * for the unsubscribe to take effect. + * + * @param presenceHandle the handle object provided by the subscribePresence call that + * identifies this subscription. + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle); + +#ifdef WITH_CLOUD + /** + * Subscribes to a server's device presence change events. + * + * @param presenceHandle a handle object that can be used to identify this subscription + * request. It can be used to unsubscribe from these events in the future. + * It will be set upon successful return of this method. + * @param host The IP address/addressable name of the server to subscribe to. + * This should be in the format coap://address:port + * @param di Vector which can have the devices id. + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * @param observeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this observe operation + * This will have error codes + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle, + const std::string& host, + const std::vector<std::string>& di, + OCConnectivityType connectivityType, + ObserveCallback callback); +#endif + + /** + * Creates a resource proxy object so that get/put/observe functionality + * can be used without discovering the object in advance. Note that the + * consumer of this method needs to provide all of the details required to + * correctly contact and observe the object. If the consumer lacks any of + * this information, they should discover the resource object normally. + * Additionally, you can only create this object if OCPlatform was initialized + * to be a Client or Client/Server. Otherwise, this will return an empty + * shared ptr. + * + * @param host a string containing a resolvable host address of the server + * holding the resource. Currently this should be in the format + * coap://address:port, though in the future, we expect this to + * change to //address:port + * + * @param uri the rest of the resource's URI that will permit messages to be + * properly routed. Example: /a/light + * + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * if you want to use a specific Flag like IPv4, + * you should apply OR operation for the flag in here. + * Example: static_cast<OCConnectivityType>(CT_ADAPTER_TCP + * | OC_IP_USE_V4) + * + * @param isObservable a boolean containing whether the resource supports observation + * + * @param resourceTypes a collection of resource types implemented by the resource + * + * @param interfaces a collection of interfaces that the resource supports/implements + * @return OCResource::Ptr a shared pointer to the new resource object + */ + OCResource::Ptr constructResourceObject(const std::string& host, + const std::string& uri, + OCConnectivityType connectivityType, bool isObservable, + const std::vector<std::string>& resourceTypes, + const std::vector<std::string>& interfaces); + + /** + * Allows application entity handler to send response to an incoming request. + * + * @param pResponse OCResourceResponse pointer that will permit to set values related + * to resource response. + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse); + + /** + * Find all the Direct Pairing capable devices. + * + * @param waittime timeoutbefore the callback is called + * @param callback function to callback with discovered devices after timeout + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult findDirectPairingDevices(unsigned short waittime, + GetDirectPairedCallback callback); + + /** + * Get all the Direct paired devices. + * + * @param callback function to callback with the list of paired devices + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult getDirectPairedDevices(GetDirectPairedCallback callback); + + /** + * Perform the Direct Pairing with the selected peer device + * + * @param peer device to direct pair with + * @param pmSel Selected pairing method + * @param pinNumber pin to validate peer & perform the direct pairing + * @param resultCallback callback function that will get the result of the operation + * + * @return Returns ::OC_STACK_OK if success + */ + OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel, + const std::string& pinNumber, + DirectPairingCallback resultCallback); +#ifdef WITH_CLOUD + /** + * Create an account manager object that can be used for doing request to account server. + * You can only create this object if OCPlatform was initialized to be a Client or + * Client/Server. Otherwise, this will return an empty shared ptr. + * + * @note For now, OCPlatform SHOULD be initialized to be a Client/Server(Both) for the + * methods of this object to work since device id is not generated on Client mode. + * + * @param host Host IP Address of a account server. + * @param connectivityType ::OCConnectivityType type of connectivity indicating the + * interface. Example: CT_DEFAULT, CT_ADAPTER_IP, CT_ADAPTER_TCP. + * if you want to use a specific Flag like IPv4, + * you should apply OR operation for the flag in here. + * Example: static_cast<OCConnectivityType>(CT_ADAPTER_TCP + * | OC_IP_USE_V4) + * + * @return OCAccountManager::Ptr a shared pointer to the new account manager object + */ + OCAccountManager::Ptr constructAccountManagerObject(const std::string& host, + OCConnectivityType connectivityType); +#endif // WITH_CLOUD + + /** + * gets the deviceId of the client + * + * @param deviceId pointer. + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult getDeviceId(OCUUIdentity *deviceId); + + /** + * sets the deviceId of the client + * + * @param deviceId pointer. + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult setDeviceId(const OCUUIdentity *deviceId); + } +} + +#endif // OC_PLATFORM_H_ diff --git a/inc/iotivity/OCPlatform_impl.h b/inc/iotivity/OCPlatform_impl.h new file mode 100644 index 0000000..6adefc7 --- /dev/null +++ b/inc/iotivity/OCPlatform_impl.h @@ -0,0 +1,305 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * Implementation of the OCPlatform functionality. It contains a singleton + * interface that is used only by the OCPlatform namespace and is the + * central entrance to the stack. + */ + +#ifndef OC_PLATFORM_IMPL_H_ +#define OC_PLATFORM_IMPL_H_ + +#include <map> + +#include "OCApi.h" +#include "OCResource.h" +#include "WrapperFactory.h" +#include "OCResourceRequest.h" +#include "OCResourceResponse.h" +#include "OCRepresentation.h" +#include "OCDirectPairing.h" + +#ifdef WITH_CLOUD +#include "OCAccountManager.h" +#endif + +#include "oc_logger.hpp" + +namespace OC +{ + class OCPlatform_impl + { + private: + static PlatformConfig& globalConfig(); + public: + static void Configure(const PlatformConfig& config); + + static OCPlatform_impl& Instance(); + + public: + // typedef for handle to cancel presence info with + typedef OCDoHandle OCPresenceHandle; + + virtual ~OCPlatform_impl(void); + + OCStackResult notifyAllObservers(OCResourceHandle resourceHandle); + + OCStackResult notifyAllObservers(OCResourceHandle resourceHandle, QualityOfService QoS); + + OCStackResult notifyListOfObservers( + OCResourceHandle resourceHandle, + ObservationIds& observationIds, + const std::shared_ptr<OCResourceResponse> responsePtr); + + OCStackResult notifyListOfObservers( + OCResourceHandle resourceHandle, + ObservationIds& observationIds, + const std::shared_ptr<OCResourceResponse> responsePtr, + QualityOfService QoS); + + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler); + + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler, + QualityOfService QoS); + + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler, + FindErrorCallback errorHandler); + + OCStackResult findResource(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindCallback resourceHandler, + FindErrorCallback errorHandler, QualityOfService QoS); + + OCStackResult findResourceList(const std::string& host, const std::string& resourceURI, + OCConnectivityType connectivityType, FindResListCallback resourceHandler, + QualityOfService QoS); + + OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI, + OCConnectivityType connectivityType, FindDeviceCallback deviceInfoHandler); + + OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI, + OCConnectivityType connectivityType, FindDeviceCallback deviceInfoHandler, + QualityOfService QoS); + + OCStackResult getPlatformInfo(const std::string& host, const std::string& platformURI, + OCConnectivityType connectivityType, FindPlatformCallback platformInfoHandler); + + OCStackResult getPlatformInfo(const std::string& host, const std::string& platformURI, + OCConnectivityType connectivityType, FindPlatformCallback platformInfoHandler, + QualityOfService QoS); + + /** + * API for Device Discovery + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param deviceURI Uri containing address to the virtual device in C Stack + * ("/oic/d") + * @param deviceInfoHandler device discovery callback + * @param QualityOfService the quality of communication + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI, + FindDeviceCallback deviceInfoHandler); + OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI, + FindDeviceCallback deviceInfoHandler, QualityOfService QoS); + + /** + * API for Platform Discovery + * + * @param host Host IP Address. If null or empty, Multicast is performed. + * @param platformURI Uri containing address to the virtual platform in C Stack + * ("/oic/p") + * @param platformInfoHandler platform discovery callback + * @param QualityOfService the quality of communication + * @return Returns ::OC_STACK_OK if success. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult getPlatformInfo(const std::string& host, const std::string& platformURI, + FindPlatformCallback platformInfoHandler); + OCStackResult getPlatformInfo(const std::string& host, const std::string& platformURI, + FindPlatformCallback platformInfoHandler, QualityOfService QoS); + + OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value); + OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::vector<std::string>& value); + OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value); + + /** + * This API registers a resource with the server + * @note This API applies to server side only. + * + * @param resourceHandle Upon successful registration, resourceHandle will be filled + * @param resourceURI The URI of the resource. Example: "a/light". See NOTE below + * @param resourceTypeName The resource type. Example: "light" + * @param resourceInterface The resource interface (whether it is collection etc). + * @param entityHandler entity handler callback. + * @param resourceProperty indicates the property of the resource. Defined in ocstack.h. + * setting resourceProperty as OC_DISCOVERABLE will allow Discovery of this resource + * setting resourceProperty as OC_OBSERVABLE will allow observation + * settings resourceProperty as OC_DISCOVERABLE | OC_OBSERVABLE will allow both discovery + * and observation + * + * @return Returns ::OC_STACK_OK if success. + * @note "a/light" is a relative URI. + * Above relative URI will be prepended (by core) with a host IP + namespace "oc" + * Therefore, fully qualified URI format would be //HostIP-Address/namespace/relativeURI" + * Example, a relative URI: 'a/light' will result in a fully qualified URI: + * //192.168.1.1/oic/a/light" + * First parameter can take a relative URI and core will take care of preparing the fully + * qualified URI OR + * first parameter can take fully qualified URI and core will take that as is for further + * operations + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult registerResource(OCResourceHandle& resourceHandle, + std::string& resourceURI, + const std::string& resourceTypeName, + const std::string& resourceInterface, + EntityHandler entityHandler, + uint8_t resourceProperty); + + OCStackResult registerResource(OCResourceHandle& resourceHandle, + const std::shared_ptr<OCResource> resource); + + /** + * This API registers all the device specific information + * + * @param deviceInfo Structure containing all the device related information + * + * @return Returns ::OC_STACK_OK if success + * @note OCDeviceInfo is defined in OCStack.h + */ + OCStackResult registerDeviceInfo(const OCDeviceInfo deviceInfo); + + /** + * This API registers all the platform specific information + * + * @param platformInfo Structure containing all the platform related information + * + * @return Returns ::OC_STACK_OK if success + * @note OCPlatformInfo is defined in OCStack.h + */ + OCStackResult registerPlatformInfo(const OCPlatformInfo platformInfo); + + OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler); + + OCStackResult unregisterResource(const OCResourceHandle& resourceHandle) const; + + OCStackResult bindResource(const OCResourceHandle collectionHandle, + const OCResourceHandle resourceHandle); + + OCStackResult bindResources(const OCResourceHandle collectionHandle, + const std::vector<OCResourceHandle>& addedResourceHandleList); + + OCStackResult unbindResource(const OCResourceHandle collectionHandle, + const OCResourceHandle resourceHandle); + + OCStackResult unbindResources(const OCResourceHandle collectionHandle, + const std::vector<OCResourceHandle>& resourceHandleList); + + OCStackResult bindTypeToResource(const OCResourceHandle& resourceHandle, + const std::string& resourceTypeName) const; + + OCStackResult bindInterfaceToResource(const OCResourceHandle& resourceHandle, + const std::string& resourceInterfaceName) const; + + OCStackResult startPresence(const unsigned int ttl); + + OCStackResult stopPresence(); + + OCStackResult subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host, + OCConnectivityType connectivityType, SubscribeCallback presenceHandler); + + OCStackResult subscribePresence(OCPresenceHandle& presenceHandle, const std::string& host, + const std::string& resourceType, OCConnectivityType connectivityType, + SubscribeCallback presenceHandler); + OCStackResult unsubscribePresence(OCPresenceHandle presenceHandle); + +#ifdef WITH_CLOUD + OCStackResult subscribeDevicePresence(OCPresenceHandle& presenceHandle, + const std::string& host, + const std::vector<std::string>& di, + OCConnectivityType connectivityType, + ObserveCallback callback); +#endif + + OCResource::Ptr constructResourceObject(const std::string& host, const std::string& uri, + OCConnectivityType connectivityType, bool isObservable, + const std::vector<std::string>& resourceTypes, + const std::vector<std::string>& interfaces); + OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse); + std::weak_ptr<std::recursive_mutex> csdkLock(); + + OCStackResult findDirectPairingDevices(unsigned short waittime, + GetDirectPairedCallback callback); + + OCStackResult getDirectPairedDevices(GetDirectPairedCallback callback); + + OCStackResult doDirectPairing(std::shared_ptr<OCDirectPairing> peer, OCPrm_t pmSel, + const std::string& pinNumber, + DirectPairingCallback resultCallback); +#ifdef WITH_CLOUD + OCAccountManager::Ptr constructAccountManagerObject(const std::string& host, + OCConnectivityType connectivityType); +#endif // WITH_CLOUD + + OCStackResult getDeviceId(OCUUIdentity *myUuid); + + OCStackResult setDeviceId(const OCUUIdentity *myUuid); + + private: + PlatformConfig m_cfg; + + private: + std::unique_ptr<WrapperFactory> m_WrapperInstance; + IServerWrapper::Ptr m_server; + IClientWrapper::Ptr m_client; + std::shared_ptr<std::recursive_mutex> m_csdkLock; + + private: + /** + * Constructor for OCPlatform_impl. Constructs a new OCPlatform_impl from a given + * PlatformConfig with appropriate fields + * @param config PlatformConfig struct which has details such as modeType + * (server/client/both), in-proc/out-of-proc etc. + */ + OCPlatform_impl(const PlatformConfig& config); + + /** + * Private function to initialize the platform + */ + void init(const PlatformConfig& config); + + /** + * Private constructor/operators to prevent copying + * of this object + */ + OCPlatform_impl(const OCPlatform_impl& other)= delete; + OCPlatform_impl& operator=(const OCPlatform_impl&) = delete; + OCPlatform_impl& operator=(const OCPlatform_impl&&) = delete; + }; +} + +#endif //__OCPLATFORM_IMPL_H diff --git a/inc/iotivity/OCProvisioningManager.hpp b/inc/iotivity/OCProvisioningManager.hpp new file mode 100644 index 0000000..dd60ced --- /dev/null +++ b/inc/iotivity/OCProvisioningManager.hpp @@ -0,0 +1,445 @@ +//**************************************************************** +// +// Copyright 2015 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_PROVISIONINGMANAGER_CXX_H_ +#define OC_PROVISIONINGMANAGER_CXX_H_ + +#include <thread> + +#include "pinoxmcommon.h" +#include "ocprovisioningmanager.h" +#include "OCApi.h" +#include "OCPlatform_impl.h" + +namespace OC +{ + class OCSecureResource; + + typedef std::vector<std::shared_ptr<OCSecureResource>> DeviceList_t; + typedef std::vector<OicUuid_t> UuidList_t; + typedef std::vector<OCProvisionResult_t> PMResultList_t; + typedef std::function<void(PMResultList_t *result, int hasError)> ResultCallBack; + typedef std::function<void(uint16_t credId, uint8_t *trustCertChain, + size_t chainSize)>CertChainCallBack; + + struct ProvisionContext + { + ResultCallBack callback; + ProvisionContext(ResultCallBack cb) : callback(cb){} + }; + + struct TrustCertChainContext + { + CertChainCallBack callback; + TrustCertChainContext(CertChainCallBack cb) : callback(cb){} + }; + /** + * This class is for credential's to be set to devices. + * The types supported are + * 0: no security mode + * 1: symmetric pair-wise key + * 2: symmetric group key + * 4: asymmetric key + * 8: signed asymmetric key (aka certificate) + * 16: PIN /password + */ + class Credential + { + OicSecCredType_t type; + size_t keySize; + public: + Credential() = default; + Credential(OicSecCredType_t type, size_t size) : type(type), keySize(size) + {} + + /** + * API to get credential type of device. + * @return credential type of device. + */ + OicSecCredType_t getCredentialType() const + { + return type; + } + + /** + * API to get size of credential key type. + * @return size of credential key type. + */ + size_t getCredentialKeySize() const + { + return keySize; + } + + /** + * API to set credential type of device. + * Device can have following credential types + * - symmetric pair-wise key + * - symmetric group key + * - asymmetric key + * - signed asymmetric key (aka certificate) + * - PIN /password + * @param type credential type. + */ + void setCredentialType(OicSecCredType_t type) + { + this->type = type; + } + + /** + * API to set size of credential key type. + * @param keySize credential key size. + * @note can be either 128 or 256 for symmetric pair-wise key + */ + void setCredentialKeySize(size_t keySize) + { + this->keySize = keySize; + } + }; + + class OCSecure + { + public: + /** + * The API is responsible for initialization of the provisioning manager. It will load + * provisioning database which have owned device's list and their linked status. + * + * @param dbPath file path of the sqlite3 database. + * + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult provisionInit(const std::string& dbPath); + + /** + * API is responsible for discovery of devices in it's subnet. It will list + * all the device in subnet which are not yet owned. + * + * @param timeout Timeout in seconds, time until which function will listen to + * responses from server before returning the list of devices. + * @param list List of candidate devices to be provisioned. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult discoverUnownedDevices(unsigned short timeout, + DeviceList_t &list); + + /** + * API is responsible for discovery of devices in it's subnet. It will list + * all the device in subnet which are already owned by calling provisioning client. + * + * @param timeout Timeout in seconds, time until which function will listen to + * responses from server before returning the list of devices. + * @param list List of owned devices. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult discoverOwnedDevices(unsigned short timeout, + DeviceList_t &list); + + /** + * API is responsible for discovery of devices in specified endpoint/deviceID. + * And this function will only return the specified device's response. + * + * @param timeout Timeout in seconds, time until which function will listen to + * responses from server before returning the specified device. + * @param deviceID deviceID of target device + * @param foundDevice OCSecureResource object of found device. + * @return ::OC_STACK_OK in case of success and other value otherwise.\n + * ::OC_STACK_INVALID_PARAM when deviceID is NULL or ppFoundDevice is not + * initailized. + */ + static OCStackResult discoverSingleDevice(unsigned short timeout, + const OicUuid_t* deviceID, + std::shared_ptr<OCSecureResource> &foundDevice); + + /** + * API for registering Ownership transfer methods for a particular transfer Type. + * + * @param oxm Ownership transfer method. + * @param callbackData CallbackData Methods for ownership transfer. + * @param inputPin Callback method to input pin for verification. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult setOwnerTransferCallbackData(OicSecOxm_t oxm, + OTMCallbackData_t* callbackData, InputPinCallback inputPin); + + /** + * API to get status of all the devices in current subnet. The status include endpoint + * information and doxm information which can be extracted during owned and unowned + * discovery. Along with this information, API will provide information about + * devices' status. + * Device can have following states + * - ON/OFF: Device is switched on or off. + * + * @param timeout Wait time for the API. + * @param ownedDevList List of owned devices. + * @param unownedDevList List of unowned devices. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult getDevInfoFromNetwork(unsigned short timeout, + DeviceList_t &ownedDevList, + DeviceList_t &unownedDevList); + /** + * Server API to register callback to display stack generated PIN. + * + * @param displayPin Callback Method to Display generated PIN. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult setDisplayPinCB(GeneratePinCallback displayPin); + + /** + * API to remove device credential and ACL from all devices in subnet. + * + * @param resultCallback Callback provided by API user, callback will be called when + * credential revocation is finished. + * @param uuid Device uuid to be revoked. + * @param waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device + * discovery in seconds. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult removeDeviceWithUuid(unsigned short waitTimeForOwnedDeviceDiscovery, + std::string uuid, + ResultCallBack resultCallback); + + /** + * API to save ACL which has several ACE into Acl of SVR. + * + * @param acl ACL to be saved in Acl of SVR. + * @return OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult saveACL(const OicSecAcl_t* acl); + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + /** + * API to save Trust certificate chain into Cred of SVR. + * + * @param[in] trustCertChain Trust certificate chain to be saved in Cred of SVR. + * @param[in] chainSize Size of trust certificate chain to be saved in Cred of SVR + * @param[in] encodingType Encoding type of trust certificate chain to be saved in Cred of SVR + * @param[out] credId CredId of saved trust certificate chain in Cred of SVR. + * @return OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize, + OicEncodingType_t encodingType, uint16_t *credId); + + /* + * API to read Trust certificate chain from SVR. + * Caller must free when done using the returned trust certificate + * @param[in] credId CredId of trust certificate chain in SVR. + * @param[out] trustCertChain Trust certificate chain. + * @param[out] chainSize Size of trust certificate chain + * @return OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult readTrustCertChain(uint16_t credId, uint8_t **trustCertChain, + size_t *chainSize); + + /** + * API to register Notifier for trustCertChain change. + * + * @param[in] TrustCertChainChangeCB trustCertChain Change will be + * notified asynchronously. User need to "delete[]" trustCertChain + * in the callback function. + * @return OC_STACK_OK in case of success and other value otherwise. + */ + static OCStackResult registerTrustCertChangeNotifier(CertChainCallBack); + + /** + * API to remove Already registered Notifier. + * + *@return OC_STACK_OK always, kept it for symmetry. + */ + static OCStackResult removeTrustCertChangeNotifier(); + + /** + * Notifier wrapper for trustCertChain change. + * + * @param[in] ctx User context returned in callback + * @param[in] credId trustCertChain changed for this ID + * @param[in] trustCertChain trustcertchain binary blob + * @param[in] chainSize size of trustCertChain + */ + static void certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain, + size_t chainSize); +#endif // __WITH_DTLS__ || __WITH_TLS__ + + }; + + /** + * This class represents a secure virtual device, which can be provisioned by the + * provisioning client. + */ + class OCSecureResource + { + private: + std::weak_ptr<std::recursive_mutex> m_csdkLock; + OCProvisionDev_t *devPtr; // pointer to device. + + public: + OCSecureResource(); + OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock, OCProvisionDev_t *dPtr); + + ~OCSecureResource(); + + /** + * API to provision credentials between two devices and ACLs for the devices who + * act as a server. + * + * @param cred Type of credentials & key size to be provisioned to the device. + * @param acl1 ACL for device 1. If this is not required set NULL. + * @param device2 Second device to be provisioned. + * @param acl2 ACL for device 2. If this is not required set NULL. + * @param resultCallback Callback will be called when provisioning request receives + * a response from first resource server. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult provisionPairwiseDevices(const Credential &cred, const OicSecAcl_t* acl1, + const OCSecureResource &device2, const OicSecAcl_t* acl2, + ResultCallBack resultCallback); + + /** + * API to do ownership transfer for un-owned device. + * + * @param resultCallback Result callback function to be invoked when + * ownership transfer finished. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult doOwnershipTransfer(ResultCallBack resultCallback); + + /** + * API to send ACL information to resource. + * + * @param acl ACL to provision. + * @param resultCallback Callback will be called when provisioning request + * receives a response from resource server. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult provisionACL(const OicSecAcl_t* acl, + ResultCallBack resultCallback); + + /** + * API to provision credential to devices. + * + * @param cred Type of credentials to be provisioned to the device. + * @param device2 Second device' instance, representing resource to be provisioned. + * @param resultCallback Callback will be called when provisioning request receives + * a response from first resource server. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult provisionCredentials(const Credential &cred, + const OCSecureResource &device2, + ResultCallBack resultCallback); + + /** + * API to remove the credential & relationship between the two devices. + * + * @param device2 Second device information to be unlinked. + * @param resultCallback Callback provided by API user, callback will be called when + * device unlink is finished. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult unlinkDevices(const OCSecureResource &device2, + ResultCallBack resultCallback); + + /** + * API to remove device credential from all devices in subnet. + * + * @param resultCallback Callback provided by API user, callback will be called when + * credential revocation is finished. + * @param waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device + * discovery in seconds. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery, + ResultCallBack resultCallback); + + /** + * API to provision DirectPairing to devices. + * + * @param pconf pointer to PCONF (Pairing Configuration). + * @param resultCallback Callback will be called when provisioning request receives + * a response from first resource server. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult provisionDirectPairing(const OicSecPconf_t *pconf, + ResultCallBack resultCallback); + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + /** + * API to provision cert. + * + * @param type type of cred. + * @param credId id of cert. + * @param resultCallback Callback will be called when provisioning request + * receives a response from resource server. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult provisionTrustCertChain(OicSecCredType_t type, uint16_t credId, + ResultCallBack resultCallback); + +#endif // __WITH_DTLS__ or __WITH_TLS__ + + /** + * This method is used to get linked devices' IDs. + * + * @param uuidList Information about the list of linked devices uuids. + * @return ::OC_STACK_OK in case of success and other value otherwise. + */ + OCStackResult getLinkedDevices(UuidList_t &uuidList); + + /** + * API to get the device ID of this resource. + * @return device ID. + */ + std::string getDeviceID(); + + /** + * API to get the information of device for provisioning. + * @return @ref OCProvisionDev_t Reference provides information of device for provisioning. + */ + OCProvisionDev_t* getDevPtr()const; + + /** + * This function returns the device's IP address. + * @return device address. + */ + std::string getDevAddr(); + + /** + * This function returns the device's Status. + * @return Device status (1 = ON and 2 = OFF). + */ + int getDeviceStatus(); + + /** + * This function provides the owned status of the device. + * @return Device owned status. + */ + bool getOwnedStatus(); + + + /** + * Common callback wrapper, which will be called from OC-APIs. + */ + static void callbackWrapper(void* ctx, int nOfRes, + OCProvisionResult_t *arr, bool hasError); + + private: + void validateSecureResource(); + }; + +} +#endif // OC_PROVISIONINGMANAGER_CXX_H_ diff --git a/inc/iotivity/OCRepresentation.h b/inc/iotivity/OCRepresentation.h new file mode 100644 index 0000000..309b3e5 --- /dev/null +++ b/inc/iotivity/OCRepresentation.h @@ -0,0 +1,512 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the declaration of classes and its members related + * to OCRepresentation. + */ + +#ifndef OC_REPRESENTATION_H_ +#define OC_REPRESENTATION_H_ + +#include <string> +#include <sstream> +#include <vector> +#include <map> + +#include <AttributeValue.h> +#include <StringConstants.h> + +#ifdef __ANDROID__ +#include "OCAndroid.h" +#endif + +#include <OCException.h> + +namespace OC +{ + + enum class InterfaceType + { + None, + LinkParent, + BatchParent, + DefaultParent, + LinkChild, + BatchChild, + DefaultChild + }; + + class MessageContainer + { + public: + void setPayload(const OCPayload* rep); + + void setPayload(const OCRepPayload* rep); + + OCRepPayload* getPayload() const; + + const std::vector<OCRepresentation>& representations() const; + + void addRepresentation(const OCRepresentation& rep); + + const OCRepresentation& operator[](int index) const + { + return m_reps[index]; + } + + const OCRepresentation& back() const + { + return m_reps.back(); + } + private: + std::vector<OCRepresentation> m_reps; + }; + class OCRepresentation + { + public: + friend bool operator==(const OC::OCRepresentation&, const OC::OCRepresentation&); + // Note: Implementation of all constructors and destructors + // are all placed in the same location due to a crash that + // was observed in Android, where merely constructing/destructing + // an OCRepresentation object was enough to cause an invalid 'free'. + // It is believed that this is a result of incompatible compiler + // options between the gradle JNI and armeabi scons build, however + // this fix will work in the meantime. + OCRepresentation(): m_interfaceType(InterfaceType::None){} + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCRepresentation(OCRepresentation&& o) + { + std::memmove(this, &o, sizeof(o)); + } +#else + OCRepresentation(OCRepresentation&&) = default; +#endif + + OCRepresentation(const OCRepresentation&) = default; + + OCRepresentation& operator=(const OCRepresentation&) = default; + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCRepresentation& operator=(OCRepresentation&& o) + { + std::memmove(this, &o, sizeof(o)); + return *this; + } +#else + OCRepresentation& operator=(OCRepresentation&&) = default; +#endif + + virtual ~OCRepresentation(){} + + void setDevAddr(const OCDevAddr addr); + + const std::string getHost() const; + + OCRepPayload* getPayload() const; + + void addChild(const OCRepresentation&); + + void clearChildren(); + + const std::vector<OCRepresentation>& getChildren() const; + + void setChildren(const std::vector<OCRepresentation>& children); + + void setUri(const char* uri); + + void setUri(const std::string& uri); + + std::string getUri() const; + + const std::vector<std::string>& getResourceTypes() const; + + const std::vector<std::string>& getDataModelVersions() const; + + void setResourceTypes(const std::vector<std::string>& resourceTypes); + + void addResourceType(const std::string& str); + + const std::vector<std::string>& getResourceInterfaces() const; + + void setResourceInterfaces(const std::vector<std::string>& resourceInterfaces); + + void addResourceInterface(const std::string& str); + + void addDataModelVersion(const std::string& str); + + bool emptyData() const; + + int numberOfAttributes() const; + + bool erase(const std::string& str); + + template <typename T> + void setValue(const std::string& str, const T& val) + { + m_values[str] = val; + } + + // using R-value(or universal ref depending) to move string and vector<uint8_t> + template <typename T> + void setValue(const std::string& str, T&& val) + { + m_values[str] = std::forward<T>(val); + } + + const std::map<std::string, AttributeValue>& getValues() const { + return m_values; + } + + /** + * Retrieve the attribute value associated with the supplied name + * + * @param str Name of the attribute + * @param val Value of the attribute + * @return The getValue method returns true if the attribute was + * found in the representation. Otherwise it returns false. + */ + template <typename T> + bool getValue(const std::string& str, T& val) const + { + auto x = m_values.find(str); + + if(x!= m_values.end()) + { + try + { + val = boost::get<T>(x->second); + return true; + } + catch (boost::bad_get& e) + { + val = T(); + return false; + } + } + else + { + val = T(); + return false; + } + } + + /** + * Return the attribute value associated with the supplied name + * + * @param str Name of the attribute + * @return When the representation contains the attribute, the + * the associated value is returned. Otherwise, getValue + * returns the default contructed value for the type. + */ + template <typename T> + T getValue(const std::string& str) const + { + T val = T(); + auto x = m_values.find(str); + if(x != m_values.end()) + { + try + { + val = boost::get<T>(x->second); + } + catch (boost::bad_get& e) + { + return val; + } + } + return val; + } + + /** + * Retrieve the attributevalue structure associated with the supplied name + * + * @param str Name of the attribute + * @param attrValue Attribute Value structure + * @return The getAttributeValue method returns true if the attribute was + * found in the representation. Otherwise it returns false. + */ + bool getAttributeValue(const std::string& str, AttributeValue& attrValue) const + { + auto x = m_values.find(str); + + if (x != m_values.end()) + { + attrValue = x->second; + return true; + } + else + { + return false; + } + } + + std::string getValueToString(const std::string& key) const; + bool hasAttribute(const std::string& str) const; + + void setNULL(const std::string& str); + + bool isNULL(const std::string& str) const; + + private: + std::string m_host; + + // STL Container stuff + public: + class iterator; + class const_iterator; + // Shim class to allow iterating and indexing of the OCRepresentation + // object. + class AttributeItem + { + friend class OCRepresentation; + friend class iterator; + friend class const_iterator; + public: + const std::string& attrname() const; + AttributeType type() const; + AttributeType base_type() const; + size_t depth() const; + template<typename T> + T getValue() const + { + try + { + return boost::get<T>(m_values[m_attrName]); + } + catch (boost::bad_get& e) + { + T val = T(); + return val; + } + } + + std::string getValueToString() const; + + template<typename T> + AttributeItem& operator=(T&& rhs) + { + m_values[m_attrName] = std::forward<T>(rhs); + return *this; + } + + AttributeItem& operator=(std::nullptr_t /*rhs*/) + { + NullType t; + m_values[m_attrName] = t; + return *this; + } + + // Enable-if required to prevent conversions to alternate types. This prevents + // ambigious conversions in the case where conversions can include a number of + // types, such as the string constructor. +#if (defined(_MSC_VER) ) || (defined(__GNUC__) && (__GNUC__ <= 5)) + template<typename T, typename std::enable_if< + std::is_same<T, int>::value || + std::is_same<T, double>::value || + std::is_same<T, bool>::value || + std::is_same<T, std::string>::value || + std::is_same<T, OCRepresentation>::value || + std::is_same<T, OCByteString>::value || + std::is_same<T, std::vector<int>>::value || + std::is_same<T, std::vector<std::vector<int>>>::value || + std::is_same<T, std::vector<std::vector<std::vector<int>>>>::value || + std::is_same<T, std::vector<double>>::value || + std::is_same<T, std::vector<std::vector<double>>>::value || + std::is_same<T, std::vector<std::vector<std::vector<double>>>>::value || + std::is_same<T, std::vector<bool>>::value || + std::is_same<T, std::vector<std::vector<bool>>>::value || + std::is_same<T, std::vector<std::vector<std::vector<bool>>>>::value || + std::is_same<T, std::vector<std::string>>::value || + std::is_same<T, std::vector<std::vector<std::string>>>::value || + std::is_same<T, std::vector<std::vector<std::vector<std::string>>>>::value || + std::is_same<T, std::vector<OCRepresentation>>::value || + std::is_same<T, std::vector<std::vector<OCRepresentation>>>::value || + std::is_same<T, std::vector<std::vector<std::vector<OCRepresentation>>>>::value || + std::is_same<T, std::vector<OCByteString>>::value || + std::is_same<T, std::vector<std::vector<OCByteString>>>::value || + std::is_same<T, std::vector<std::vector<std::vector<OCByteString>>>>::value + , int>::type = 0// enable_if + > +#else + template<typename T, typename std::enable_if< + is_component<T, + remove_first<AttributeValue>::type + >::value + , int>::type = 0 + > +#endif + operator T() const + { + return this->getValue<T>(); + } + + template<typename T, typename std::enable_if< + std::is_same<T, std::nullptr_t>::value + , int>::type = 0 + > + operator T() const + { + this->getValue<NullType>(); + return nullptr; + } + + private: + AttributeItem(const std::string& name, + std::map<std::string, AttributeValue>& vals); + AttributeItem(const AttributeItem&) = default; + std::string m_attrName; + std::map<std::string, AttributeValue>& m_values; + }; + + // Iterator to allow iteration via STL containers/methods + class iterator + { + friend class OCRepresentation; + public: + typedef iterator self_type; + typedef AttributeItem value_type; + typedef value_type& reference; + typedef value_type* pointer; + typedef std::forward_iterator_tag iterator_category; + typedef int difference_type; + + iterator(const iterator&) = default; + ~iterator() = default; + + bool operator ==(const iterator&) const; + bool operator !=(const iterator&) const; + + iterator& operator++(); + iterator operator++(int); + + reference operator*(); + pointer operator->(); + private: + iterator(std::map<std::string, AttributeValue>::iterator&& itr, + std::map<std::string, AttributeValue>& vals) + : m_iterator(std::move(itr)), + m_item(m_iterator != vals.end() ? m_iterator->first:"", vals){} + std::map<std::string, AttributeValue>::iterator m_iterator; + AttributeItem m_item; + }; + + class const_iterator + { + friend class OCRepresentation; + public: + typedef iterator self_type; + typedef const AttributeItem value_type; + typedef value_type& const_reference; + typedef value_type* const_pointer; + typedef std::forward_iterator_tag iterator_category; + typedef int difference_type; + + const_iterator(const iterator& rhs) + :m_iterator(rhs.m_iterator), m_item(rhs.m_item){} + const_iterator(const const_iterator&) = default; + ~const_iterator() = default; + + bool operator ==(const const_iterator&) const; + bool operator !=(const const_iterator&) const; + + const_iterator& operator++(); + const_iterator operator++(int); + + const_reference operator*() const; + const_pointer operator->() const; + private: + const_iterator(std::map<std::string, AttributeValue>::const_iterator&& itr, + std::map<std::string, AttributeValue>& vals) + : m_iterator(std::move(itr)), + m_item(m_iterator != vals.end() ? m_iterator->first: "", vals){} + std::map<std::string, AttributeValue>::const_iterator m_iterator; + AttributeItem m_item; + }; + + iterator begin(); + const_iterator begin() const; + const_iterator cbegin() const; + iterator end(); + const_iterator end() const; + const_iterator cend() const; + size_t size() const; + bool empty() const; + + AttributeItem operator[](const std::string& key); + const AttributeItem operator[](const std::string& key) const; + private: + friend class OCResourceResponse; + friend class MessageContainer; + + template<typename T> + void payload_array_helper(const OCRepPayloadValue* pl, size_t depth); + template<typename T> + T payload_array_helper_copy(size_t index, const OCRepPayloadValue* pl); + void setPayload(const OCRepPayload* payload); + void setPayloadArray(const OCRepPayloadValue* pl); + void getPayloadArray(OCRepPayload* payload, + const OCRepresentation::AttributeItem& item) const; + // the root node has a slightly different JSON version + // based on the interface type configured in ResourceResponse. + // This allows ResourceResponse to set it, so that the save function + // doesn't serialize things that it isn't supposed to serialize. + void setInterfaceType(InterfaceType ift) + { + m_interfaceType = ift; + } + + // class used to wrap the 'prop' feature of the save/load + class Prop + { + public: + Prop(std::vector<std::string>& resourceTypes, + std::vector<std::string>& interfaces) + : m_types(resourceTypes), m_interfaces(interfaces) + {} + + /* Prop(const std::vector<std::string>& resourceTypes, + const std::vector<std::string>& interfaces) + :m_types(resourceTypes), + m_interfaces(interfaces) + {}*/ + private: + std::vector<std::string>& m_types; + std::vector<std::string>& m_interfaces; + }; + private: + std::string m_uri; + std::vector<OCRepresentation> m_children; + mutable std::map<std::string, AttributeValue> m_values; + std::vector<std::string> m_resourceTypes; + std::vector<std::string> m_interfaces; + std::vector<std::string> m_dataModelVersions; + + InterfaceType m_interfaceType; + }; + + std::ostream& operator <<(std::ostream& os, const OCRepresentation::AttributeItem& ai); +} // namespace OC + + +#endif // OC_REPRESENTATION_H_ diff --git a/inc/iotivity/OCResource.h b/inc/iotivity/OCResource.h new file mode 100644 index 0000000..2167ba6 --- /dev/null +++ b/inc/iotivity/OCResource.h @@ -0,0 +1,691 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the declaration of classes and its members related to + * Resource. + */ + +#ifndef OC_RESOURCE_H_ +#define OC_RESOURCE_H_ + +#include <memory> +#include <random> +#include <algorithm> + +#include <OCApi.h> +#include <ResourceInitException.h> +#include <IClientWrapper.h> +#include <InProcClientWrapper.h> +#include <OCRepresentation.h> + +namespace OC +{ + class OCResource; + class OCResourceIdentifier; + std::ostream& operator <<(std::ostream& os, const OCResourceIdentifier& ri); + /** + * @brief OCResourceIdentifier represents the identity information for a server. This + * object combined with the OCResource's URI property uniquely identify an + * OCResource on or across networks. + * Equality operators are implemented. However, internal representation is subject + * to change and thus should not be accessed or depended on. + */ + class OCResourceIdentifier + { + friend class OCResource; + friend std::ostream& operator <<(std::ostream& os, const OCResourceIdentifier& ri); + + public: + OCResourceIdentifier() = delete; + + OCResourceIdentifier(const OCResourceIdentifier&) = default; + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCResourceIdentifier(OCResourceIdentifier&& o): + m_resourceUri(std::move(o.m_resourceUri)), + m_representation(o.m_representation) + { + } +#else + OCResourceIdentifier(OCResourceIdentifier&&) = default; +#endif + + OCResourceIdentifier& operator=(const OCResourceIdentifier&) = delete; + + OCResourceIdentifier& operator=(OCResourceIdentifier&&) = delete; + + bool operator==(const OCResourceIdentifier &other) const; + + bool operator!=(const OCResourceIdentifier &other) const; + + bool operator<(const OCResourceIdentifier &other) const; + + bool operator>(const OCResourceIdentifier &other) const; + + bool operator<=(const OCResourceIdentifier &other) const; + + bool operator>=(const OCResourceIdentifier &other) const; + + private: + + OCResourceIdentifier(const std::string& wireServerIdentifier, + const std::string& resourceUri ); + + private: + std::string m_representation; + const std::string& m_resourceUri; + }; + + /** + * @brief OCResource represents an OC resource. A resource could be a light controller, + * temperature sensor, smoke detector, etc. A resource comes with a well-defined + * contract or interface onto which you can perform different operations, such as + * turning on the light, getting the current temperature or subscribing for event + * notifications from the smoke detector. A resource can be composed of one or + * more resources. + */ + class OCResource + { + friend class OCPlatform_impl; + friend class ListenOCContainer; + public: + typedef std::shared_ptr<OCResource> Ptr; + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCResource(OCResource&& o): + m_clientWrapper(std::move(o.m_clientWrapper)), + m_uri(std::move(o.m_uri)), + m_resourceId(std::move(o.m_resourceId)), + m_devAddr(std::move(o.m_devAddr)), + m_useHostString(o.m_useHostString), + m_property(o.m_property), + m_isCollection(o.m_isCollection), + m_resourceTypes(std::move(o.m_resourceTypes)), + m_interfaces(std::move(o.m_interfaces)), + m_children(std::move(m_children)), + m_observeHandle(std::move(m_observeHandle)), + m_headerOptions(std::move(m_headerOptions)) + { + } +#else + OCResource(OCResource&&) = default; +#endif + // Explicitly delete the copy ctor since VS2013 would try to generate one, and + // the standard says that defaulting the move ctor should delete the copy ctor. + OCResource(const OCResource&) = delete; + + // We cannot support copy/move assigns since OCResourceIdentifier doesn't. + OCResource& operator=(OCResource&&) = delete; + OCResource& operator=(const OCResource&) = delete; + + /** + * Virtual destructor + */ + virtual ~OCResource(void); + + /** + * Function to get the attributes of a resource. + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Get operation + * This will have error codes + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult get(const QueryParamsMap& queryParametersMap, GetCallback attributeHandler); + /** + * Function to get the attributes of a resource. + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Get operation + * This will have error codes + * @param QoS the quality of communication + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult get(const QueryParamsMap& queryParametersMap, GetCallback attributeHandler, + QualityOfService QoS); + + /** + * Function to get the attributes of a resource. + * + * @param resourceType resourceType of the resource operate on + * @param resourceInterface interface type of the resource to operate on + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will be invoked with a list of URIs if 'get' is invoked on a + * resource container (list will be empty if not a container) + * The callback function will also have the result from this Get operation. This will + * have error codes + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * @par Example: + * Consider resource "a/home" (with link interface and resource type as home) contains links + * to "a/kitchen" and "a/room". + * -# get("home", Link_Interface, &onGet) + * @par + * Callback onGet will receive a) Empty attribute map because there are no attributes for + * a/home b) list with + * full URI of "a/kitchen" and "a/room" resources and their properties c) error code for GET + * operation + * @note A resource may contain single or multiple resource types. Also, a resource may + * contain single or multiple interfaces. + * Currently, single GET request is allowed to do operate on single resource type or resource + * interface. In future, a single GET + * can operate on multiple resource types and interfaces. + * @note A client can traverse a tree or graph by doing successive GETs on the returned + * resources at a node. + * + */ + OCStackResult get(const std::string& resourceType, const std::string& resourceInterface, + const QueryParamsMap& queryParametersMap, GetCallback attributeHandler); + /** + * Function to get the attributes of a resource. + * + * @param resourceType resourceType of the resource operate on + * @param resourceInterface interface type of the resource to operate on + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will be invoked with a list of URIs if 'get' is invoked on a + * resource container (list will be empty if not a container) + * The callback function will also have the result from this Get operation. This will + * have error codes + * @param QoS the quality of communication + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * note OCStackResult is defined in ocstack.h. + * @par Example: + * Consider resource "a/home" (with link interface and resource type as home) contains links + * to "a/kitchen" and "a/room". + * -# get("home", Link_Interface, &onGet) + * @par + * Callback onGet will receive a) Empty attribute map because there are no attributes for + * a/home b) list with + * full URI of "a/kitchen" and "a/room" resources and their properties c) error code for GET + * operation + * @note A resource may contain single or multiple resource types. Also, a resource may + * contain single or multiple interfaces. + * Currently, single GET request is allowed to do operate on single resource type or resource + * interface. In future, a single GET + * can operate on multiple resource types and interfaces. + * @note A client can traverse a tree or graph by doing successive GETs on the returned + * resources at a node. + * + */ + OCStackResult get(const std::string& resourceType, const std::string& resourceInterface, + const QueryParamsMap& queryParametersMap, GetCallback attributeHandler, + QualityOfService QoS); + + /** + * Function to set the representation of a resource (via PUT) + * + * @param representation which can either have all the attribute names and values + (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler attribute handler + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult put(const OCRepresentation& representation, + const QueryParamsMap& queryParametersMap, PutCallback attributeHandler); + /** + * Function to set the representation of a resource (via PUT) + * + * @param representation which can either have all the attribute names and values + (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler attribute handler + * @param QoS the quality of communication + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult put(const OCRepresentation& representation, + const QueryParamsMap& queryParametersMap, PutCallback attributeHandler, + QualityOfService QoS); + + /** + * Function to set the attributes of a resource (via PUT) + * + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param representation representation of the resource + * @param queryParametersMap Map which can have the query parameter name and value + * @param attributeHandler attribute handler + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes. + * The Representation parameter maps which can either have all the attribute names + * and values + * (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult put(const std::string& resourceType, const std::string& resourceInterface, + const OCRepresentation& representation, const QueryParamsMap& queryParametersMap, + PutCallback attributeHandler); + /** + * Function to set the attributes of a resource (via PUT) + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param representation representation of the resource + * @param queryParametersMap Map which can have the query parameter name and value + * @param attributeHandler attribute handler + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes. + * The Representation parameter maps which can either have all the attribute names + * and values + * (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * @param QoS the quality of communication + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult put(const std::string& resourceType, const std::string& resourceInterface, + const OCRepresentation& representation, const QueryParamsMap& queryParametersMap, + PutCallback attributeHandler, QualityOfService QoS); + + /** + * Function to post on a resource + * + * @param representation which can either have all the attribute names and values + * (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler attribute handler + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult post(const OCRepresentation& representation, + const QueryParamsMap& queryParametersMap, PostCallback attributeHandler); + /** + * Function to post on a resource + * + * @param representation which can either have all the attribute names and values + * (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler attribute handler + * @param QoS the quality of communication + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + */ + OCStackResult post(const OCRepresentation& representation, + const QueryParamsMap& queryParametersMap, PostCallback attributeHandler, + QualityOfService QoS); + + /** + * Function to post on a resource + * + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param representation representation of the resource + * @param queryParametersMap Map which can have the query parameter name and value + * @param attributeHandler attribute handler + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes. + * The Representation parameter maps which can either have all the attribute names + * and values + * (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult post(const std::string& resourceType, const std::string& resourceInterface, + const OCRepresentation& representation, const QueryParamsMap& queryParametersMap, + PostCallback attributeHandler); + /** + * Function to post on a resource + * + * @param resourceType resource type of the resource to operate on + * @param resourceInterface interface type of the resource to operate on + * @param representation representation of the resource + * @param queryParametersMap Map which can have the query parameter name and value + * @param attributeHandler attribute handler + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this Put operation + * This will have error codes. + * The Representation parameter maps which can either have all the attribute names + * and values + * (which will represent entire state of the resource) or a + * set of attribute names and values which needs to be modified + * @param QoS the quality of communication + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult post(const std::string& resourceType, const std::string& resourceInterface, + const OCRepresentation& representation, const QueryParamsMap& queryParametersMap, + PostCallback attributeHandler, QualityOfService QoS); + + /** + * Function to perform DELETE operation + * + * @param deleteHandler handles callback + * The callback function will have headerOptions and result from this Delete + * operation. This will have error codes + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult deleteResource(DeleteCallback deleteHandler); + OCStackResult deleteResource(DeleteCallback deleteHandler, QualityOfService QoS); + + /** + * Function to set observation on the resource + * + * @param observeType allows the client to specify how it wants to observe. + * @param queryParametersMap map which can have the query parameter name and value + * @param observeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this observe operation + * This will have error codes + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult observe(ObserveType observeType, const QueryParamsMap& queryParametersMap, + ObserveCallback observeHandler); + /** + * Function to set observation on the resource + * + * @param observeType allows the client to specify how it wants to observe. + * @param queryParametersMap map which can have the query parameter name and value + * @param observeHandler handles callback + * The callback function will be invoked with a map of attribute name and values. + * The callback function will also have the result from this observe operation + * This will have error codes + * @param qos the quality of communication + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult observe(ObserveType observeType, const QueryParamsMap& queryParametersMap, + ObserveCallback observeHandler, QualityOfService qos); + + /** + * Function to cancel the observation on the resource + * + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult cancelObserve(); + OCStackResult cancelObserve(QualityOfService qos); + + /** + * Function to set header information. + * @param headerOptions std::vector where header information(header optionID and optionData + * is passed + * + * @note Once the headers information is set, it will be applicable to GET, PUT and observe + * request. + * setHeaderOptions can be used multiple times if headers need to be modifed by the client. + * Latest headers will be used to send in the request. <br> + * @note Initial support is only for two headers. If headerMap consists of more than two + * header options, they will be ignored. <br> + * Use unsetHeaderOptions API to clear the header information. + */ + void setHeaderOptions(const HeaderOptions& headerOptions); + + /** + * Function to unset header options. + */ + void unsetHeaderOptions(); + + /** + * Function to get the host address of this resource + * @return std::string host address + * @note This might or might not be exposed in future due to security concerns + */ + std::string host() const; + + /** + * Function to get the URI for this resource + * @return std::string resource URI + */ + std::string uri() const; + + /** + * Function to get the connectivity type of this resource + * @return enum connectivity type (flags and adapter) + */ + OCConnectivityType connectivityType() const; + + /** + * Function to provide ability to check if this resource is observable or not + * @return bool true indicates resource is observable; false indicates resource is + * not observable. + */ + bool isObservable() const; + +#ifdef WITH_MQ + /** + * Function to provide ability to check if this resource is publisher or not + * @return bool true indicates resource is publisher; false indicates resource is + * not publisher. + */ + bool isPublish() const; +#endif + + /** + * Function to get the list of resource types + * @return vector of resource types + */ + std::vector<std::string> getResourceTypes() const; + + /** + * Function to get the list of resource interfaces + * @return vector of resource interface + */ + std::vector<std::string> getResourceInterfaces(void) const; + + // TODO-CA Revisit this since we are exposing two identifiers + /** + * Function to get a unique identifier for this + * resource across network interfaces. This will + * be guaranteed unique for every resource-per-server + * independent of how this was discovered. + * @return OCResourceIdentifier object, which can + * be used for all comparison and hashing. + */ + OCResourceIdentifier uniqueIdentifier() const; + + /** + * Function to get a string representation of the resource's server ID. + * This is unique per- server independent on how it was discovered. + * @note The format of the return value is subject to change and will + * likely change both in size and contents in the future. + */ + std::string sid() const; + +#ifdef WITH_MQ + /** + * Function to discovery Topics from MQ Broker. + * + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * @param qos the quality of communication + * + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult discoveryMQTopics(const QueryParamsMap& queryParametersMap, + MQTopicCallback attributeHandler, + QualityOfService qos); + /** + * Function to create Topic into MQ Broker. + * SubTopic is also created through this method. + * + * @param rep representation of the topic + * @param topicUri new uri of the topic which want to create + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * @param qos the quality of communication + * + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult createMQTopic(const OCRepresentation& rep, + const std::string& topicUri, + const QueryParamsMap& queryParametersMap, + MQTopicCallback attributeHandler, + QualityOfService qos); +#endif +#ifdef MQ_SUBSCRIBER + /** + * Function to subscribe Topic to MQ Broker. + * + * @param observeType allows the client to specify how it wants to observe. + * @param queryParametersMap map which can have the query parameter name and value + * @param observeHandler handles callback + * @param qos the quality of communication + * + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult subscribeMQTopic(ObserveType observeType, + const QueryParamsMap& queryParametersMap, + ObserveCallback observeHandler, + QualityOfService qos); + + /** + * Function to unsubscribe Topic to MQ Broker. + * + * @param qos the quality of communication + * + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult unsubscribeMQTopic(QualityOfService qos); + + /** + * Function to request publish to MQ publisher. + * Publisher can confirm the request message as key:"req_pub" and value:"true". + * + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * @param qos the quality of communication + * + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult requestMQPublish(const QueryParamsMap& queryParametersMap, + PostCallback attributeHandler, + QualityOfService qos); +#endif +#ifdef MQ_PUBLISHER + /** + * Function to publish Topic information into MQ Broker. + * + * @param rep representation of the topic + * @param queryParametersMap map which can have the query parameter name and value + * @param attributeHandler handles callback + * @param qos the quality of communication + * + * @return Returns ::OC_STACK_OK on success, some other value upon failure. + * @note OCStackResult is defined in ocstack.h. + * + */ + OCStackResult publishMQTopic(const OCRepresentation& rep, + const QueryParamsMap& queryParametersMap, + PostCallback attributeHandler, + QualityOfService qos); +#endif + // overloaded operators allow for putting into a 'set' + // the uniqueidentifier allows for putting into a hash + bool operator==(const OCResource &other) const; + + bool operator!=(const OCResource &other) const; + + bool operator<(const OCResource &other) const; + + bool operator>(const OCResource &other) const; + + bool operator<=(const OCResource &other) const; + + bool operator>=(const OCResource &other) const; + + private: + void setHost(const std::string& host); + std::weak_ptr<IClientWrapper> m_clientWrapper; + std::string m_uri; + OCResourceIdentifier m_resourceId; + OCDevAddr m_devAddr; + bool m_useHostString; + bool m_isCollection; + uint8_t m_property; + std::vector<std::string> m_resourceTypes; + std::vector<std::string> m_interfaces; + std::vector<std::string> m_children; + OCDoHandle m_observeHandle; + HeaderOptions m_headerOptions; + + private: + OCResource(std::weak_ptr<IClientWrapper> clientWrapper, + const OCDevAddr& devAddr, const std::string& uri, + const std::string& serverId, uint8_t property, + const std::vector<std::string>& resourceTypes, + const std::vector<std::string>& interfaces); + + OCResource(std::weak_ptr<IClientWrapper> clientWrapper, + const std::string& host, const std::string& uri, + const std::string& serverId, + OCConnectivityType connectivityType, uint8_t property, + const std::vector<std::string>& resourceTypes, + const std::vector<std::string>& interfaces); + }; + +} // namespace OC + +#endif // OC_RESOURCE_H + diff --git a/inc/iotivity/OCResourceRequest.h b/inc/iotivity/OCResourceRequest.h new file mode 100644 index 0000000..8c7e1dc --- /dev/null +++ b/inc/iotivity/OCResourceRequest.h @@ -0,0 +1,268 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the declaration of classes and its members related to + * ResourceRequest. + */ + +#ifndef OC_RESOURCEREQUEST_H_ +#define OC_RESOURCEREQUEST_H_ + +#include "OCApi.h" +#include "OCRepresentation.h" + +void formResourceRequest(OCEntityHandlerFlag, + OCEntityHandlerRequest*, + std::shared_ptr<OC::OCResourceRequest>); + + +namespace OC +{ + /** + * @brief OCResourceRequest provides APIs to extract details from a request URI + */ + class OCResourceRequest + { + public: + typedef std::shared_ptr<OCResourceRequest> Ptr; + + OCResourceRequest(): + m_requestType(""), + m_resourceUri(""), + m_queryParameters(QueryParamsMap()), + m_requestHandlerFlag(0), + m_messageID(0), + m_representation(OCRepresentation()), + m_headerOptions(HeaderOptions()), + m_requestHandle(0), + m_resourceHandle(nullptr) + { + m_observationInfo.action = ObserveAction::ObserveRegister; + m_observationInfo.obsId = 0; + m_observationInfo.connectivityType = OCConnectivityType::CT_DEFAULT; + m_observationInfo.address = ""; + m_observationInfo.port = 0; + } + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCResourceRequest(OCResourceRequest&& o): + m_requestType(std::move(o.m_requestType)), + m_resourceUri(std::move(o.m_resourceUri)), + m_queryParameters(std::move(o.m_queryParameters)), + m_requestHandlerFlag(o.m_requestHandlerFlag), + m_representation(std::move(o.m_representation)), + m_observationInfo(std::move(o.m_observationInfo)), + m_headerOptions(std::move(o.m_headerOptions)), + m_requestHandle(std::move(o.m_requestHandle)), + m_resourceHandle(std::move(o.m_resourceHandle)) + { + } + OCResourceRequest& operator=(OCResourceRequest&& o) + { + m_requestType = std::move(o.m_requestType); + m_resourceUri = std::move(o.m_resourceUri); + m_queryParameters = std::move(o.m_queryParameters); + m_requestHandlerFlag = o.m_requestHandlerFlag; + m_representation = std::move(o.m_representation); + m_observationInfo = std::move(o.m_observationInfo); + m_headerOptions = std::move(o.m_headerOptions); + m_requestHandle = std::move(o.m_requestHandle); + m_resourceHandle = std::move(o.m_resourceHandle); + } +#else + OCResourceRequest(OCResourceRequest&&) = default; + OCResourceRequest& operator=(OCResourceRequest&&) = default; +#endif + + /** + * Virtual destructor + */ + virtual ~OCResourceRequest(void) + { + } + + /** + * Retrieves the type of request string for the entity handler function to operate + * @return std::string request type. This could be 'GET'/'PUT'/'POST'/'DELETE' + */ + std::string getRequestType() const {return m_requestType;} + + /** + * Retrieves the query parameters from the request + * @return std::string query parameters in the request + */ + const QueryParamsMap& getQueryParameters() const {return m_queryParameters;} + + /** + * Retrieves the request handler flag type. This can be either INIT flag or + * REQUEST flag or OBSERVE flag. + * NOTE: + * INIT indicates that the vendor's entity handler should go and perform + * initialization operations + * REQUEST indicates that it is a request of certain type (GET/PUT/POST/DELETE) + * and entity handler needs to perform corresponding operations + * OBSERVE indicates that the request is of type Observe and entity handler + * needs to perform corresponding operations + * @return int type of request flag + */ + int getRequestHandlerFlag() const {return m_requestHandlerFlag;} + + /** + * Provides the entire resource attribute representation + * @return OCRepresentation reference containing the name value pairs + * representing the resource's attributes + */ + const OCRepresentation& getResourceRepresentation() const {return m_representation;} + + /** + * @return ObservationInfo reference provides observation information + */ + const ObservationInfo& getObservationInfo() const {return m_observationInfo;} + + /** + * sets resource uri + * @param resourceUri specifies the resource uri + */ + void setResourceUri(const std::string resourceUri) + { + m_resourceUri = resourceUri; + } + + /** + * gets resource uri + * @return std::string resource uri + */ + std::string getResourceUri(void) + { + return m_resourceUri; + } + + /** + * This API retrieves headerOptions which was sent from a client + * + * @return std::map HeaderOptions with the header options + */ + const HeaderOptions& getHeaderOptions() const + { + return m_headerOptions; + } + + /** + * This API retrieves the request handle + * + * @return OCRequestHandle + */ + const OCRequestHandle& getRequestHandle() const + { + return m_requestHandle; + } + + /** + * This API retrieves the resource handle + * + * return OCResourceHandle + */ + const OCResourceHandle& getResourceHandle() const + { + return m_resourceHandle; + } + + /** + * This API retrieves the request message ID + * + * @return int16_t value of message ID + */ + int16_t getMessageID() const {return m_messageID;} + + private: + std::string m_requestType; + std::string m_resourceUri; + QueryParamsMap m_queryParameters; + int m_requestHandlerFlag; + int16_t m_messageID; + OCRepresentation m_representation; + ObservationInfo m_observationInfo; + HeaderOptions m_headerOptions; + OCRequestHandle m_requestHandle; + OCResourceHandle m_resourceHandle; + + + private: + friend void (::formResourceRequest)(OCEntityHandlerFlag, OCEntityHandlerRequest*, + std::shared_ptr<OC::OCResourceRequest>); + void setRequestType(const std::string& requestType) + { + m_requestType = requestType; + } + + void setPayload(OCPayload* requestPayload); + + void setQueryParams(QueryParamsMap& queryParams) + { + m_queryParameters = queryParams; + } + + void setRequestHandlerFlag(int requestHandlerFlag) + { + m_requestHandlerFlag = requestHandlerFlag; + } + + void setMessageID(int16_t messageID) + { + m_messageID = messageID; + } + + void setObservationInfo(const ObservationInfo& observationInfo) + { + m_observationInfo = observationInfo; + } + + void setHeaderOptions(const HeaderOptions& headerOptions) + { + m_headerOptions = headerOptions; + } + + /** + * This API allows to set request handle + * @param requestHandle - OCRequestHandle type used to set the + * request handle + */ + void setRequestHandle(const OCRequestHandle& requestHandle) + { + m_requestHandle = requestHandle; + } + + /** + * This API allows to set the resource handle + * @param resourceHandle - OCResourceHandle type used to set the + * resource handle + */ + void setResourceHandle(const OCResourceHandle& resourceHandle) + { + m_resourceHandle = resourceHandle; + } + + }; + }// namespace OC + +#endif // OC_RESOURCEREQUEST_H_ diff --git a/inc/iotivity/OCResourceResponse.h b/inc/iotivity/OCResourceResponse.h new file mode 100644 index 0000000..754f1ac --- /dev/null +++ b/inc/iotivity/OCResourceResponse.h @@ -0,0 +1,303 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the declaration of classes and its members related to + * ResourceResponse. + */ + +#ifndef OC_RESOURCERESPONSE_H_ +#define OC_RESOURCERESPONSE_H_ + +#include "OCApi.h" +#include <IServerWrapper.h> +#include <ocstack.h> +#include <OCRepresentation.h> + +namespace OC +{ + class InProcServerWrapper; + + /** + * @brief OCResourceResponse provides APIs to set the response details + */ + class OCResourceResponse + { + public: + typedef std::shared_ptr<OCResourceResponse> Ptr; + + OCResourceResponse(): + m_newResourceUri{}, + m_errorCode{}, + m_headerOptions{}, + m_interface{}, + m_representation{}, + m_requestHandle{0}, + m_resourceHandle{nullptr}, + m_responseResult{} + { + } + +#if defined(_MSC_VER) && (_MSC_VER < 1900) + OCResourceResponse(OCResourceResponse&& o): + m_newResourceUri(std::move(o.m_newResourceUri)), + m_errorCode(o.m_errorCode), + m_headerOptions(std::move(o.m_headerOptions)), + m_interface(std::move(o.m_interface)), + m_representation(std::move(o.m_representation)), + m_requestHandle(std::move(o.m_requestHandle)), + m_resourceHandle(std::move(o.m_resourceHandle)), + m_responseResult(std::move(o.m_responseResult)) + { + } + OCResourceResponse& operator=(OCResourceResponse&& o) + { + m_newResourceUri = std::move(o.m_newResourceUri); + m_errorCode = o.m_errorCode; + m_headerOptions = std::move(o.m_headerOptions); + m_interface = std::move(o.m_interface); + m_representation = std::move(o.m_representation); + m_requestHandle = std::move(o.m_requestHandle); + m_resourceHandle = std::move(o.m_resourceHandle); + m_responseResult = std::move(o.m_responseResult); + } +#else + OCResourceResponse(OCResourceResponse&&) = default; + OCResourceResponse& operator=(OCResourceResponse&&) = default; +#endif + virtual ~OCResourceResponse(void) {} + + /** + * This API sets the error code for this response + * @param eCode error code to set + */ + void setErrorCode(const int eCode) { m_errorCode = eCode; } + + /** + * gets new resource uri + * @return std::string new resource uri + */ + std::string getNewResourceUri(void) + { + return m_newResourceUri; + } + + /** + * sets new resource uri + * @param newResourceUri specifies the resource uri of the resource created + */ + void setNewResourceUri(const std::string newResourceUri) + { + m_newResourceUri = newResourceUri; + } + + /** + * This API allows to set headerOptions in the response + * @param headerOptions HeaderOptions vector consisting of OCHeaderOption objects + */ + void setHeaderOptions(const HeaderOptions& headerOptions) + { + m_headerOptions = headerOptions; + } + + /** + * This API allows to set request handle + * + * @param requestHandle - OCRequestHandle type used to set the request handle + */ + void setRequestHandle(const OCRequestHandle& requestHandle) + { + m_requestHandle = requestHandle; + } + + /** + * This API allows to set the resource handle + * + * @param resourceHandle - OCResourceHandle type used to set the resource handle + */ + void setResourceHandle(const OCResourceHandle& resourceHandle) + { + m_resourceHandle = resourceHandle; + } + + /** + * This API allows to set the EntityHandler response result + * + * @param responseResult - OCEntityHandlerResult type to set the result value + */ + void setResponseResult(const OCEntityHandlerResult& responseResult) + { + m_responseResult = responseResult; + } + + /** + * API to set the entire resource attribute representation + * @param rep reference to the resource's representation + * @param interface specifies the interface + */ + void setResourceRepresentation(OCRepresentation& rep, std::string iface) { + m_interface = iface; + m_representation = rep; + } + + /** + * API to set the entire resource attribute representation + * @param rep rvalue reference to the resource's representation + * @param interface specifies the interface + */ + void setResourceRepresentation(OCRepresentation&& rep, std::string iface) { + setResourceRepresentation(rep, iface); + } + + /** + * API to set the entire resource attribute representation + * @param rep reference to the resource's representation + */ + void setResourceRepresentation(OCRepresentation& rep) { + // Call the default + m_interface = DEFAULT_INTERFACE; + m_representation = rep; + } + + /** + * API to set the entire resource attribute representation + * @param rep rvalue reference to the resource's representation + */ + void setResourceRepresentation(OCRepresentation&& rep) { + // Call the above function + setResourceRepresentation(rep); + } + private: + std::string m_newResourceUri; + int m_errorCode; + HeaderOptions m_headerOptions; + std::string m_interface; + OCRepresentation m_representation; + OCRequestHandle m_requestHandle; + OCResourceHandle m_resourceHandle; + OCEntityHandlerResult m_responseResult; + + private: + friend class InProcServerWrapper; + + OCRepPayload* getPayload() const + { + MessageContainer inf; + OCRepresentation first(m_representation); + + if(m_interface==LINK_INTERFACE) + { + first.setInterfaceType(InterfaceType::LinkParent); + } + else if(m_interface==BATCH_INTERFACE) + { + first.setInterfaceType(InterfaceType::BatchParent); + } + else + { + first.setInterfaceType(InterfaceType::DefaultParent); + } + + inf.addRepresentation(first); + + for(const OCRepresentation& rep : m_representation.getChildren()) + { + OCRepresentation cur(rep); + + if(m_interface==LINK_INTERFACE) + { + cur.setInterfaceType(InterfaceType::LinkChild); + } + else if(m_interface==BATCH_INTERFACE) + { + cur.setInterfaceType(InterfaceType::BatchChild); + } + else + { + cur.setInterfaceType(InterfaceType::DefaultChild); + } + + inf.addRepresentation(cur); + + } + + return inf.getPayload(); + } + public: + + /** + * Get error code + */ + int getErrorCode() const + { + return m_errorCode; + } + + /** + * Get the Response Representation + */ + const OCRepresentation& getResourceRepresentation() const + { + return m_representation; + } + /** + * This API allows to retrieve headerOptions from a response + */ + const HeaderOptions& getHeaderOptions() const + { + return m_headerOptions; + } + + /** + * This API retrieves the request handle + * + * @return OCRequestHandle value + */ + const OCRequestHandle& getRequestHandle() const + { + return m_requestHandle; + } + + /** + * This API retrieves the resource handle + * + * @return OCResourceHandle value + */ + const OCResourceHandle& getResourceHandle() const + { + return m_resourceHandle; + } + + /** + * This API retrieves the entity handle response result + * + * @return OCEntityHandler result value + */ + OCEntityHandlerResult getResponseResult() const + { + return m_responseResult; + } + }; + +} // namespace OC + +#endif // OC_RESOURCERESPONSE_H_ diff --git a/inc/iotivity/OCSerialization.h b/inc/iotivity/OCSerialization.h new file mode 100644 index 0000000..b7ba781 --- /dev/null +++ b/inc/iotivity/OCSerialization.h @@ -0,0 +1,164 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include <StringConstants.h> +#include "ocpayload.h" +#include "ocrandom.h" +#include "oic_string.h" + +namespace OC +{ + class ListenOCContainer + { + private: + static std::vector<std::string> StringLLToVector(OCStringLL* ll) + { + std::vector<std::string> strs; + while(ll) + { + strs.push_back(ll->value); + ll = ll->next; + } + return strs; + } + + public: + ListenOCContainer(std::weak_ptr<IClientWrapper> cw, + OCDevAddr& devAddr, OCDiscoveryPayload* payload) + : m_clientWrapper(cw), m_devAddr(devAddr) + { + while (payload) + { + OCResourcePayload* res = payload->resources; + while (res) + { + if (res->secure) + { + m_devAddr.flags = + (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags); + } + + if (res->port != 0) + { + m_devAddr.port = res->port; + } + + if (payload->baseURI) + { + OCDevAddr rdPubAddr = m_devAddr; + + std::string baseURI = std::string(payload->baseURI); + size_t len = baseURI.length(); + int addressLen = baseURI.find_first_of(":"); + std::string ipaddress = baseURI.substr(0, addressLen); + int port = atoi(baseURI.substr(addressLen + 1, len).c_str()); + OICStrcpy(rdPubAddr.addr, addressLen + 1, ipaddress.c_str()); + rdPubAddr.port = port; + m_resources.push_back(std::shared_ptr<OC::OCResource>( + new OC::OCResource(m_clientWrapper, rdPubAddr, + std::string(res->uri), + std::string(payload->sid), + res->bitmap, + StringLLToVector(res->types), + StringLLToVector(res->interfaces) + ))); + } + else + { + m_resources.push_back(std::shared_ptr<OC::OCResource>( + new OC::OCResource(m_clientWrapper, m_devAddr, + std::string(res->uri), + std::string(payload->sid), + res->bitmap, + StringLLToVector(res->types), + StringLLToVector(res->interfaces) + ))); + +#ifdef TCP_ADAPTER + if (res->tcpPort != 0) + { + OCDevAddr tcpDevAddr = m_devAddr; + tcpDevAddr.port = res->tcpPort; + tcpDevAddr.adapter = OC_ADAPTER_TCP; + m_resources.push_back(std::shared_ptr<OC::OCResource>( + new OC::OCResource(m_clientWrapper, tcpDevAddr, + std::string(res->uri), + std::string(payload->sid), + res->bitmap, + StringLLToVector(res->types), + StringLLToVector(res->interfaces) + ))); + } +#endif + } + res = res->next; + } + payload = payload->next; + } + } + +#ifdef WITH_MQ + ListenOCContainer(std::weak_ptr<IClientWrapper> cw, + OCDevAddr& devAddr, OCRepPayload* payload) + : m_clientWrapper(cw), m_devAddr(devAddr) + { + if (payload) + { + char**topicList = nullptr; + size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0}; + OCRepPayloadGetStringArray(payload, "topiclist", &topicList, dimensions); + + for(size_t idx = 0; idx < dimensions[0]; idx++) + { + m_resources.push_back(std::shared_ptr<OC::OCResource>( + new OC::OCResource(m_clientWrapper, m_devAddr, + std::string(topicList[idx]), + "", + OC_OBSERVABLE, + {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC}, + {DEFAULT_INTERFACE}))); + } + } + } + + ListenOCContainer(std::weak_ptr<IClientWrapper> cw, + OCDevAddr& devAddr, const std::string& topicUri) + : m_clientWrapper(cw), m_devAddr(devAddr) + { + m_resources.push_back(std::shared_ptr<OC::OCResource>( + new OC::OCResource(m_clientWrapper, m_devAddr, + topicUri, + "", + OC_OBSERVABLE, + {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC}, + {DEFAULT_INTERFACE}))); + } +#endif + + const std::vector<std::shared_ptr<OCResource>>& Resources() const + { + return m_resources; + } + private: + std::vector<std::shared_ptr<OC::OCResource>> m_resources; + std::weak_ptr<IClientWrapper> m_clientWrapper; + OCDevAddr& m_devAddr; + }; +} diff --git a/inc/iotivity/OCUtilities.h b/inc/iotivity/OCUtilities.h new file mode 100644 index 0000000..85039d0 --- /dev/null +++ b/inc/iotivity/OCUtilities.h @@ -0,0 +1,148 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_UTILITIES_H_ +#define OC_UTILITIES_H_ + +#include <map> +#include <vector> +#include <memory> +#include <utility> +#include <exception> + +#include <OCException.h> +#include <StringConstants.h> + +namespace OC { + namespace Utilities { + + typedef std::map<std::string, std::string> QueryParamsKeyVal; + + /* + * @brief helper function that parses the query parameters component + * of a URI into a key-value map. This function expects the uri + * parameter to contain the query parameters component of a URI + * (everything after the '?', excluding anything anchors). + * + * Note that output will not perform URL decoding + */ + QueryParamsKeyVal getQueryParams(const std::string& uri); + } +} + +/* The C++11 standard unfortunately forgot to provide make_unique<>! However, if we're +using C++14 or later, we want to take the standard library's implementation: */ +namespace OC { +#if defined(__cplusplus) && __cplusplus < 201300 + + template<typename T, typename ...XS> + std::unique_ptr<T> make_unique(XS&& ...xs) + { + return std::unique_ptr<T>(new T(std::forward<XS>(xs)...)); + } + +#else + using std::make_unique; +#endif +} // namespace OC + +namespace OC { + + /* Examine an OCStackResult, and either forward its value or raise an exception: */ + OCStackResult result_guard(const OCStackResult r); + + /* Check for a nullptr, and throw an exception if we see one; otherwise, return the + result of the function call: */ + template <typename PtrT, typename FnT, typename ...ParamTs> + auto nil_guard(PtrT&& p, FnT&& fn, ParamTs&& ...params) -> OCStackResult + { + if(nullptr == p) + { + throw OCException(OC::Exception::NIL_GUARD_NULL, OC_STACK_INVALID_PARAM); + } + + // Note that the parameters are being passed by reference to std::bind. This is not an + // issue, as it is this function's parameters that are being passed by reference. So, + // unless the parameters are being passed by reference to here (or to checked_guard), + // they won't be modified. + return std::bind(fn, p, std::ref(params)...)(); + } + + /* Check for nullptr and forward the result of an OC function call on success; raise + an exception on failure or exceptional result: */ + template <typename PtrT, typename FnT, typename ...ParamTs> + auto checked_guard(PtrT&& p, FnT&& fn, ParamTs&& ...params) -> OCStackResult + { + return result_guard(nil_guard(p, fn, std::forward<ParamTs>(params)...)); + } + +} // namespace OC + +namespace OC +{ + template<typename T, typename = void> + struct is_vector + { + BOOST_STATIC_CONSTEXPR bool value = false; + }; + + template<typename T> + struct is_vector<T, + typename std::enable_if< + std::is_same<T, std::vector<typename T::value_type, typename T::allocator_type> >::value + >::type + > + { + BOOST_STATIC_CONSTEXPR bool value = true; + }; + + // type trait to remove the first type from a parameter-packed list + template <typename T> + struct remove_first; + + // specialization that does all the work + template<template <typename...> class Base, typename T, typename ...Rest> + struct remove_first< Base<T, Rest...> > + { + typedef Base<Rest...> type; + }; + + // type trait that will only pass if ToTest is in the parameter pack of T2 + template<typename ToTest, typename T2> + struct is_component; + + // specialization to handle the single-item case + template<typename ToTest, template <typename...> class Base, typename T> + struct is_component<ToTest, Base<T> > + { + BOOST_STATIC_CONSTEXPR bool value = std::is_same<ToTest, T>::value; + }; + + // Recursive specialization to handle cases with multiple values + template<typename ToTest, template <typename...> class Base, typename T, typename ...Rest> + struct is_component<ToTest, Base<T, Rest...> > + { + BOOST_STATIC_CONSTEXPR bool value = std::is_same<ToTest, T>::value + || is_component<ToTest, Base<Rest...> >::value; + }; +} // namespace OC + +#endif + diff --git a/inc/iotivity/OutOfProcClientWrapper.h b/inc/iotivity/OutOfProcClientWrapper.h new file mode 100644 index 0000000..c32656c --- /dev/null +++ b/inc/iotivity/OutOfProcClientWrapper.h @@ -0,0 +1,179 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_OUT_OF_PROC_CLIENT_WRAPPER_H_ +#define OC_OUT_OF_PROC_CLIENT_WRAPPER_H_ + +#include <OCApi.h> + +namespace OC +{ + class OutOfProcClientWrapper : public IClientWrapper + { + public: + OutOfProcClientWrapper(std::weak_ptr<std::recursive_mutex> /*csdkLock*/, + PlatformConfig /*cfg*/) + {} + + virtual OCStackResult ListenForResource(const std::string& /*servUrl*/, + const std::string& /*rsrcType*/, + OCConnectivityType /*connType*/, + FindCallback& /*callback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult ListenForResource2(const std::string& /*servUrl*/, + const std::string& /*rsrcType*/, + OCConnectivityType /*connType*/, + FindResListCallback& /*callback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult ListenErrorForResource(const std::string& /*servUrl*/, + const std::string& /*rsrcType*/, + OCConnectivityType /*connType*/, + FindCallback& /*callback*/, + FindErrorCallback& /*errorCallback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult ListenForDevice(const std::string& /*serviceUrl*/, + const std::string& /*deviceURI*/, + OCConnectivityType /*connType*/, + FindDeviceCallback& /*callback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult ListenForDevice(const std::string& /*serviceUrl*/, + const std::string& /*deviceURI*/, + FindDeviceCallback& /*callback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult GetResourceRepresentation( + const OCDevAddr& /*devAddr*/, + const std::string& /*uri*/, + const QueryParamsMap& /*queryParams*/, + const HeaderOptions& /*headerOptions*/, + OCConnectivityType /*connectivityType*/, + GetCallback& /*callback*/, QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult PutResourceRepresentation( + const OCDevAddr& /*devAddr*/, + const std::string& /*uri*/, + const OCRepresentation& /*attributes*/, + const QueryParamsMap& /*queryParams*/, + const HeaderOptions& /*headerOptions*/, + PutCallback& /*callback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult PostResourceRepresentation( + const OCDevAddr& /*devAddr*/, + const std::string& /*uri*/, + const OCRepresentation& /*attributes*/, + const QueryParamsMap& /*queryParams*/, + const HeaderOptions& /*headerOptions*/, + OCConnectivityType /*connectivityType*/, + PostCallback& /*callback*/, QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult DeleteResource( + const OCDevAddr& /*devAddr*/, + const std::string& /*uri*/, + const HeaderOptions& /*headerOptions*/, + OCConnectivityType /*connectivityType*/, + DeleteCallback& /*callback*/, QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult ObserveResource( + ObserveType /*observeType*/, OCDoHandle* /*handle*/, + const OCDevAddr& /*devAddr*/, + const std::string& /*uri*/, + const QueryParamsMap& /*queryParams*/, + const HeaderOptions& /*headerOptions*/, + ObserveCallback& /*callback*/, QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult CancelObserveResource( + OCDoHandle /*handle*/, + const std::string& /*host*/, + const std::string& /*uri*/, + const HeaderOptions& /*headerOptions*/, QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult SubscribePresence( + OCDoHandle* /*handle*/, + const std::string& /*host*/, + const std::string& /*resourceType*/, + OCConnectivityType /*connectivityType*/, + SubscribeCallback& /*presenceHandler*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult UnsubscribePresence(OCDoHandle /*handle*/) + {return OC_STACK_NOTIMPL;} +#ifdef WITH_CLOUD + virtual OCStackResult SubscribeDevicePresence( + OCDoHandle* /*handle*/, + const std::string& /*host*/, + const std::vector<std::string>& /*di*/, + OCConnectivityType /*connectivityType*/, + ObserveCallback& /*callback*/) + {return OC_STACK_NOTIMPL;} +#endif + + virtual OCStackResult GetDefaultQos(QualityOfService& /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult FindDirectPairingDevices(unsigned short /*waittime*/, + GetDirectPairedCallback& /*callback*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult GetDirectPairedDevices(GetDirectPairedCallback& /*callback*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult DoDirectPairing(std::shared_ptr<OCDirectPairing> /*peer*/, + const OCPrm_t& /*pmSel*/, + const std::string& /*pinNumber*/, DirectPairingCallback& /*resultCallback*/) + {return OC_STACK_NOTIMPL;} + +#ifdef WITH_MQ + virtual OCStackResult ListenForMQTopic(const OCDevAddr& /*devAddr*/, + const std::string& /*resourceUri*/, + const QueryParamsMap& /*queryParams*/, + const HeaderOptions& /*headerOptions*/, + MQTopicCallback& /*callback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} + + virtual OCStackResult PutMQTopicRepresentation(const OCDevAddr& /*devAddr*/, + const std::string& /*uri*/, + const OCRepresentation& /*rep*/, + const QueryParamsMap& /*queryParams*/, + const HeaderOptions& /*headerOptions*/, + MQTopicCallback& /*callback*/, + QualityOfService /*QoS*/) + {return OC_STACK_NOTIMPL;} +#endif + }; +} + +#endif diff --git a/inc/iotivity/OutOfProcServerWrapper.h b/inc/iotivity/OutOfProcServerWrapper.h new file mode 100644 index 0000000..05d79e4 --- /dev/null +++ b/inc/iotivity/OutOfProcServerWrapper.h @@ -0,0 +1,124 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_OUT_OF_PROC_SERVER_WRAPPER_H_ +#define OC_OUT_OF_PROC_SERVER_WRAPPER_H_ + +#include <OCApi.h> + +namespace OC +{ + class OutOfProcServerWrapper : public IServerWrapper + { + public: + OutOfProcServerWrapper(PlatformConfig /*cfg*/) + {} + + virtual OCStackResult registerResource( + OCResourceHandle& /*resourceHandle*/, + std::string& /*resourceURI*/, + const std::string& /*resourceTypeName*/, + const std::string& /*resourceInterface*/, + EntityHandler& /*entityHandler*/, + uint8_t /*resourceProperty*/) + { + // Not implemented + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult registerDeviceInfo( + const OCDeviceInfo /*deviceInfo*/) + { + // Not implemented + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult registerPlatformInfo( + const OCPlatformInfo /*deviceInfo*/) + { + // Not implemented + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult registerResourceWithHost( + OCResourceHandle& /*resourceHandle*/, + std::string& /*resourceHOST*/, + std::string& /*resourceURI*/, + const std::string& /*resourceTypeName*/, + const std::string& /*resourceInterface*/, + EntityHandler& /*entityHandler*/, + uint8_t /*resourceProperty*/) + { + // Not implemented + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult unregisterResource( + const OCResourceHandle& /*resourceHandle*/) + { + //Not implemented yet + return OC_STACK_ERROR; + } + + virtual OCStackResult bindTypeToResource( + const OCResourceHandle& /*resourceHandle*/, + const std::string& /*resourceTypeName*/) + { + //Not implemented yet + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult bindInterfaceToResource( + const OCResourceHandle& /*resourceHandle*/, + const std::string& /*resourceInterfaceName*/) + { + //Not implemented yet + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult startPresence(const unsigned int /*seconds*/) + { + //Not implemented yet + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult stopPresence() + { + //Not implemented yet + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult setDefaultDeviceEntityHandler( + EntityHandler /*entityHandler*/) + { + //Not implemented yet + return OC_STACK_NOTIMPL; + } + + virtual OCStackResult sendResponse( + const std::shared_ptr<OCResourceResponse> /*pResponse*/) + { + //Not implemented yet + return OC_STACK_NOTIMPL; + } + }; +} + +#endif diff --git a/inc/iotivity/RDClient.h b/inc/iotivity/RDClient.h new file mode 100644 index 0000000..2f48e01 --- /dev/null +++ b/inc/iotivity/RDClient.h @@ -0,0 +1,118 @@ +//****************************************************************** +// +// Copyright 2015 Samsung Electronics All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include "OCRepresentation.h" +#include "OCApi.h" +#include "octypes.h" + +typedef std::function<void(const OC::OCRepresentation&, const int)> PublishResourceCallback; +typedef std::function<void(const int)> DeleteResourceCallback; + +using namespace OC; + +namespace ServerCallbackContext +{ + struct PublishContext + { + PublishResourceCallback callback; + PublishContext(PublishResourceCallback cb) : callback(cb){} + }; + + struct DeleteContext + { + DeleteResourceCallback callback; + DeleteContext(DeleteResourceCallback cb) : callback(cb){} + }; +} + +class RDClient +{ +private: + OCQualityOfService m_qos; + std::shared_ptr<std::recursive_mutex> _csdkLock; + std::weak_ptr<std::recursive_mutex> m_csdkLock; + +public: + RDClient(OCQualityOfService qos = OC_NA_QOS) + : m_qos(qos), + _csdkLock{ std::make_shared<std::recursive_mutex>() } + { + m_csdkLock = _csdkLock; + } + + static RDClient& Instance() + { + static RDClient client; + return client; + } + + /** + * API for Virtual Resource("/oic/d" and "/oic/p") Publish to Resource Directory. + * @note This API applies to resource server side only. + * + * @param host Host IP Address of a service to direct resource publish query. + * @param connectivityType ::OCConnectivityType type of connectivity. + * @param callback Handles callbacks, success states and failure states. + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult publishResourceToRD(const std::string& host, + OCConnectivityType connectivityType, + OC::ResourceHandles& resourceHandles, + PublishResourceCallback callback); + + OCStackResult publishResourceToRD(const std::string& host, + OCConnectivityType connectivityType, + PublishResourceCallback callback, + QualityOfService qos); + + OCStackResult publishResourceToRD(const std::string& host, + OCConnectivityType connectivityType, + OC::ResourceHandles& resourceHandles, + PublishResourceCallback callback, + QualityOfService qos); + + /** + * API for published resource delete from Resource Directory. + * @note This API applies to resource server side only. + * + * @param host Host IP Address of a service to direct resource delete query. + * @param connectivityType ::OCConnectivityType type of connectivity. + * @param callback Handles callbacks, success states and failure states. + * + * @return Returns ::OC_STACK_OK if success. + */ + OCStackResult deleteResourceFromRD(const std::string& host, + OCConnectivityType connectivityType, + OC::ResourceHandles& resourceHandles, + DeleteResourceCallback callback); + + OCStackResult deleteResourceFromRD(const std::string& host, + OCConnectivityType connectivityType, + DeleteResourceCallback callback, + QualityOfService qos); + + OCStackResult deleteResourceFromRD(const std::string& host, + OCConnectivityType connectivityType, + OC::ResourceHandles &resourceHandles, + DeleteResourceCallback callback, + QualityOfService qos); + +}; diff --git a/inc/iotivity/ResourceInitException.h b/inc/iotivity/ResourceInitException.h new file mode 100644 index 0000000..e700739 --- /dev/null +++ b/inc/iotivity/ResourceInitException.h @@ -0,0 +1,126 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_RESOURCE_INIT_EXCEPTION_H_ +#define OC_RESOURCE_INIT_EXCEPTION_H_ + +#include <stdexcept> +#include "StringConstants.h" + +namespace OC +{ + class ResourceInitException : public std::exception + { + public: + ResourceInitException( + bool missingUri, + bool missingType, + bool missingInterface, + bool missingClientWrapper, + bool invalidPort, + bool invalidIp) + : m_missingUri(missingUri), + m_missingType(missingType), + m_missingInterface(missingInterface), + m_missingClientWrapper(missingClientWrapper), + m_invalidPort(invalidPort), + m_invalidIp(invalidIp) + { + } + + bool isInvalidPort() const + { + return m_invalidPort; + } + + bool isInvalidIp() const + { + return m_invalidIp; + } + + bool isClientWrapperMissing() const + { + return m_missingClientWrapper; + } + + bool isUriMissing() const + { + return m_missingUri; + } + + bool isTypeMissing() const + { + return m_missingType; + } + + bool isInterfaceMissing() const + { + return m_missingInterface; + } + + virtual const char* what() const BOOST_NOEXCEPT + { + std::string ret; + + if(isUriMissing()) + { + ret += OC::InitException::MISSING_URI; + } + + if(isTypeMissing()) + { + ret += OC::InitException::MISSING_TYPE; + } + + if(isInterfaceMissing()) + { + ret += OC::InitException::MISSING_INTERFACE; + } + + if(isClientWrapperMissing()) + { + ret += OC::InitException::MISSING_CLIENT_WRAPPER; + } + + if(isInvalidPort()) + { + ret += OC::InitException::INVALID_PORT; + } + + if(isInvalidIp()) + { + ret += OC::InitException::INVALID_IP; + } + + return ret.c_str(); + } + + private: + + bool m_missingUri; + bool m_missingType; + bool m_missingInterface; + bool m_missingClientWrapper; + bool m_invalidPort; + bool m_invalidIp; + }; +} + +#endif diff --git a/inc/iotivity/StringConstants.h b/inc/iotivity/StringConstants.h new file mode 100644 index 0000000..4f856c2 --- /dev/null +++ b/inc/iotivity/StringConstants.h @@ -0,0 +1,166 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_STRING_CONSTANTS_H_ +#define OC_STRING_CONSTANTS_H_ + +#include <string> + +namespace OC +{ + +#if defined(_WIN32) +/** @todo: Remove temporary hacks to solve error C2059: syntax error: 'constant'*/ +#ifdef NO_ERROR +#undef NO_ERROR +#endif +#ifdef DELETE +#undef DELETE +#endif +#endif + + namespace InitException + { + static const char NO_ERROR[] = "No Error"; + static const char INVALID_URI[] = "Invalid URI"; + static const char INVALID_PORT[] = "Invalid Port"; + static const char INVALID_IP[] = "Invalid IP"; + static const char INVALID_CB[] = "Invalid Callback"; + static const char INVALID_METHOD[] = "Invalid Method"; + static const char GENERAL_FAULT[] = "General Fault"; + static const char UNKNOWN_ERROR[] = "Unknown Error"; + + static const char STACK_INIT_ERROR[] = "Error Initializing Stack"; + static const char NOT_CONFIGURED_AS_SERVER[] = + "Cannot static construct a Server when configured as a client"; + static const char INVALID_PARAM[] = "Invalid Param"; + static const char MISSING_URI[] = "Missing URI;"; + static const char MISSING_TYPE[] = "Missing Resource Type;"; + static const char MISSING_INTERFACE[] = "Missing Interface;"; + static const char MISSING_CLIENT_WRAPPER[] = "Missing ClientWrapper;"; + } + + namespace Exception // Not To Be Confused With 'InitException' + { + static const char SVCTYPE_OUTOFPROC[] = "ServiceType::OutOfProc"; + static const char BIND_TYPE_FAILED[] = "Bind Type to resource failed"; + static const char BIND_INTERFACE_FAILED[] = "Bind Interface to resource failed"; + static const char START_PRESENCE_FAILED[] = "startPresence failed"; + static const char END_PRESENCE_FAILED[] = "stopPresence failed"; + static const char INVALID_ARRAY[] = "Array type should have at least []"; + static const char STR_NULL_RESPONSE[] = "Response is NULL"; + static const char STR_PAYLOAD_OVERFLOW[] = "Payload overflow"; + static const char NIL_GUARD_NULL[] = "nullptr at nil_guard()"; + static const char GENERAL_JSON_PARSE_FAILED[] = "JSON Parser Error"; + static const char RESOURCE_UNREG_FAILED[] = "Unregistering resource failed"; + static const char OPTION_ID_RANGE_INVALID[] = + "Error: OptionID valid only If-Match(1), If-None-Match(5)," + "Location-Path(8), Location-Query(20)," + "and from 2048 to 3000 inclusive."; + static const char NO_ERROR[] = "No Error"; + static const char RESOURCE_CREATED[] = "Resource Created"; + static const char RESOURCE_CHANGED[] = "Resource Changed"; + static const char RESOURCE_DELETED[] = "Resource Deleted"; + static const char INVALID_URI[] = "Invalid URI"; + static const char INVALID_IP[] = "Invalid IP"; + static const char INVALID_PORT[] = "Invalid Port"; + static const char INVALID_CB[] = "Invalid Callback"; + static const char INVALID_METHOD[] = "Invalid Method"; + static const char INVALID_QUERY[] = "Invalid Query"; + static const char INVALID_PARAM[] = "Invalid Param"; + static const char INVALID_OBESERVE[] = "Invalid Observe Param"; + static const char NO_MEMORY[] = "No Memory"; + static const char COMM_ERROR[] = "Communication Error"; + static const char TIMEOUT[] = "Timeout"; + static const char ADAPTER_NOT_ENABLED[] = "Adapter Not Enabled"; + static const char NOT_IMPL[] = "Not Implemented"; + static const char NOT_FOUND[] = "Resource Not Found"; + static const char RESOURCE_ERROR[] = "Resource Error"; + static const char SLOW_RESOURCE[] = "Slow Resource"; + static const char DUPLICATE_REQUEST[] = "Duplicate Request"; + static const char NO_OBSERVERS[] = "No Observers"; + static const char OBSV_NO_FOUND[] = "Stack observer not found"; + static const char OBSV_NOT_ADDED[] = "Stack observer not added"; + static const char OBSV_NOT_REMOVED[] = "Stack observer not removed"; + static const char STACK_RESOURCE_DELETED[] = "The specified resource has been deleted"; + static const char PRESENCE_STOPPED[] = "Stack presence stopped"; + static const char PRESENCE_TIMEOUT[] = "Stack presence timed out"; + static const char PRESENCE_NOT_HANDLED[] = "Stack presence should not be handled"; + static const char INVALID_OPTION[] = "Invalid option"; + static const char GENERAL_FAULT[] = "General Fault"; + static const char MALFORMED_STACK_RESPONSE[] = "Response from OC_STACK is malformed"; + static const char VIRTUAL_DO_NOT_HANDLE[] = "Virtual Do Not Handle"; + static const char PERSISTENT_BUFFER_REQUIRED[] = "Persistent response buffer required"; + static const char STACK_CONTINUE[] = "Stack continue"; + static const char INVALID_REQUEST_HANDLE[] = "Invalid request handle"; + static const char UNKNOWN_ERROR[] = "Unknown Error"; + static const char INVALID_REPRESENTATION[] = "Invalid Payload JSON"; + static const char INVALID_JSON_TYPE[] = "Unrecognized JSON Type "; + static const char INVALID_JSON_NUMERIC[] = "Unrecognized JSON Numeric "; + static const char INVALID_JSON_ARRAY_DEPTH[] = "Max JSON Array Depth exceeded"; + static const char INVALID_JSON_TYPE_TAG[] = "Invalid JSON Type Tag"; + static const char INVALID_ATTRIBUTE[] = "Invalid Attribute: "; + static const char INVALID_DEVICE_INFO[] = "Invalid Device Information"; + static const char UNAUTHORIZED_REQUEST[] = "Unauthorized Request"; + static const char TOO_LARGE_REQ[] = "Request Too Large"; + static const char PDM_DB_NOT_INITIALIZED[] = "Provisioning DB is not initialized"; + static const char DUPLICATE_UUID[] = "Duplicate UUID in DB"; + static const char INCONSISTENT_DB[] = "Data in provisioning DB is inconsistent"; + static const char AUTHENTICATION_FAILURE[] = "Authentication failure"; + static const char NOT_ALLOWED_OXM[] = "Not allowed ownership transfer method"; + static const char PUBLISH_RESOURCE_FAILED[] = "Publish Resource failure"; + static const char FORBIDDEN_REQ[] = "Forbidden request"; + static const char INTERNAL_SERVER_ERROR[] = "Internal server error"; + } + + namespace Error + { + static const char INVALID_IP[] = "Invalid IP"; + } + + namespace PlatformCommands + { + static const std::string GET = "GET"; + static const std::string PUT = "PUT"; + static const std::string POST = "POST"; + static const std::string DELETE = "DELETE"; + } + + namespace Key + { + static const std::string OCKEY = "oic"; + static const std::string URIKEY = "href"; + static const std::string POLICYKEY = "p"; + static const std::string BMKEY = "bm"; + static const std::string RESOURCETYPESKEY = "rt"; + static const std::string INTERFACESKEY = "if"; + static const std::string PROPERTYKEY = "prop"; + static const std::string REPKEY = "rep"; + static const std::string SECUREKEY = "sec"; + static const std::string PORTKEY = "port"; + static const std::string DEVICEIDKEY = "di"; + static const std::string LINKS = "links"; + + } + +} + +#endif // OC_STRING_CONSTANTS_H_ + diff --git a/inc/iotivity/WrapperFactory.h b/inc/iotivity/WrapperFactory.h new file mode 100644 index 0000000..1b31142 --- /dev/null +++ b/inc/iotivity/WrapperFactory.h @@ -0,0 +1,89 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_WRAPPER_FACTORY_H_ +#define OC_WRAPPER_FACTORY_H_ + +#include <memory> +#include <OCApi.h> +#include "IClientWrapper.h" +#include "IServerWrapper.h" +#include <OutOfProcClientWrapper.h> +#include <InProcClientWrapper.h> +#include <OutOfProcServerWrapper.h> +#include <InProcServerWrapper.h> +#include "StringConstants.h" + +namespace OC +{ + // Interface to permit easier mocking/unit testing later + class IWrapperFactory + { + public: + typedef std::shared_ptr<IWrapperFactory> Ptr; + + virtual IClientWrapper::Ptr CreateClientWrapper( + std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg) =0; + virtual IServerWrapper::Ptr CreateServerWrapper( + std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg) =0; + virtual ~IWrapperFactory(){} + }; + + // Class to create the client/server object! + class WrapperFactory : public IWrapperFactory + { + public: + WrapperFactory(){} + + virtual IClientWrapper::Ptr CreateClientWrapper( + std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg) + { + switch(cfg.serviceType) + { + case ServiceType::InProc: + return std::make_shared<InProcClientWrapper>(csdkLock, cfg); + break; + case ServiceType::OutOfProc: + return std::make_shared<OutOfProcClientWrapper>(csdkLock, cfg); + break; + } + return nullptr; + } + + virtual IServerWrapper::Ptr CreateServerWrapper( + std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg) + { + switch(cfg.serviceType) + { + case ServiceType::InProc: + return std::make_shared<InProcServerWrapper>(csdkLock, cfg); + break; + case ServiceType::OutOfProc: + throw OC::OCException(OC::Exception::SVCTYPE_OUTOFPROC, OC_STACK_NOTIMPL); + break; + } + return nullptr; + } + + virtual ~WrapperFactory(){} + }; +} + +#endif diff --git a/inc/iotivity/iotivity_config.h b/inc/iotivity/iotivity_config.h new file mode 100755 index 0000000..668018c --- /dev/null +++ b/inc/iotivity/iotivity_config.h @@ -0,0 +1,63 @@ + +/* **************************************************************************** + * iotivity_config.h - IoTivity platform-specific configuration header. + * + * Auto-generated code for the linux x86_64 platform. + * + * Generated at 2017-04-07 05:23:17.816607 + * + *************************************************************************** */ + +#ifndef IOTIVITY_CONFIG_H__ +#define IOTIVITY_CONFIG_H__ + +#define HAVE_ARPA_INET_H 1 + +#define HAVE_FCNTL_H 1 + +#define HAVE_GRP_H 1 + +#define HAVE_LINUX_LIMITS_H 1 + +#define HAVE_MEMORY_H 1 + +#define HAVE_NETDB_H 1 + +#define HAVE_NETINET_IN_H 1 + +#define HAVE_PTHREAD_H 1 + +#define HAVE_PWD_H 1 + +#define HAVE_STDLIB_H 1 + +#define HAVE_STRING_H 1 + +#define HAVE_STRINGS_H 1 + +#define HAVE_SYS_SOCKET_H 1 + +#define HAVE_SYS_STAT_H 1 + +#define HAVE_SYS_TIME_H 1 + +#define HAVE_SYS_TIMEB_H 1 + +#define HAVE_SYS_TYPES_H 1 + +#define HAVE_SYS_UNISTD_H 1 + +#define HAVE_SYSLOG_H 1 + +#define HAVE_TIME_H 1 + +#define HAVE_UNISTD_H 1 + +#define HAVE_UUID_UUID_H 1 + + + +#include "platform_features.h" + +#endif // IOTIVITY_CONFIG_H__ + diff --git a/inc/iotivity/logger.h b/inc/iotivity/logger.h new file mode 100644 index 0000000..2bd6087 --- /dev/null +++ b/inc/iotivity/logger.h @@ -0,0 +1,251 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#define IOTIVITY_VERSION "1.2.1" + +#include <stdint.h> +#include <stdio.h> +#include <stdarg.h> +#include "logger_types.h" + +#ifdef __ANDROID__ +#include <android/log.h> +#elif defined(__TIZEN__) +#include <dlog.h> +#elif defined(ARDUINO) +#include "Arduino.h" +#include "avr/pgmspace.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** +* Helper for unused warning. +*/ +#define UNUSED(x) (void)(x) + +// Use the PCF macro to wrap strings stored in FLASH on the Arduino +// Example: OIC_LOG(INFO, TAG, PCF("Entering function")); +#ifdef ARDUINO +#ifdef __cplusplus +#define PCF(str) ((PROGMEM const char *)(F(str))) +#else +#define PCF(str) ((PROGMEM const char *)(PSTR(str))) +#endif //__cplusplus +#else + #define PCF(str) str +#endif + +// Max buffer size used in variable argument log function +#define MAX_LOG_V_BUFFER_SIZE (256) + +// Log levels +#ifdef __TIZEN__ +typedef enum { + DEBUG = DLOG_DEBUG, + INFO = DLOG_INFO, + WARNING = DLOG_WARN, + ERROR = DLOG_ERROR, + FATAL = DLOG_ERROR +} LogLevel; +#else + +/** @todo temporary work-around until better names with prefixes are used for the enum values. */ +#ifdef ERROR +#undef ERROR +#endif + +typedef enum { + DEBUG = 0, + INFO, + WARNING, + ERROR, + FATAL +} LogLevel; +#endif + +#ifdef __TIZEN__ +/** + * Output the contents of the specified buffer (in hex) with the specified priority level. + * + * @param[in] level DEBUG, INFO, WARNING, ERROR, FATAL + * @param[in] tag Module name + * @param[in] buffer pointer to buffer of bytes + * @param[in] bufferSize max number of byte in buffer + */ +void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize); + +#define OCLog(level,tag,mes) LOG_(LOG_ID_MAIN, (level), (tag), mes) +#define OCLogv(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, (level),tag,fmt,##args) +#elif !defined(ARDUINO) + /** + * Configure logger to use a context that defines a custom logger function + * + * @param ctx - pointer to oc_log_ctx_t struct that defines custom logging functions + */ + void OCLogConfig(oc_log_ctx_t *ctx); + + /** + * Initialize the logger. Optional on Android and Linux. Configures serial port on Arduino + */ + void OCLogInit(); + + /** + * Called to Free dyamically allocated resources used with custom logging. + * Not necessary if default logging is used + * + */ + void OCLogShutdown(); + + /** + * Output a variable argument list log string with the specified priority level. + * Only defined for Linux and Android + * + * @param level - DEBUG, INFO, WARNING, ERROR, FATAL + * @param tag - Module name + * @param format - variadic log string + */ + void OCLogv(LogLevel level, const char * tag, const char * format, ...) +#if defined(__GNUC__) + __attribute__ ((format(printf, 3, 4))) +#endif + ; + + /** + * Output a log string with the specified priority level. + * Only defined for Linux and Android + * + * @param level - DEBUG, INFO, WARNING, ERROR, FATAL + * @param tag - Module name + * @param logStr - log string + */ + void OCLog(LogLevel level, const char * tag, const char * logStr); + + /** + * Output the contents of the specified buffer (in hex) with the specified priority level. + * + * @param level - DEBUG, INFO, WARNING, ERROR, FATAL + * @param tag - Module name + * @param buffer - pointer to buffer of bytes + * @param bufferSize - max number of byte in buffer + */ + void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize); +#else // For arduino platforms + /** + * Initialize the serial logger for Arduino + * Only defined for Arduino + */ + void OCLogInit(); + + /** + * Output a log string with the specified priority level. + * Only defined for Arduino. Uses PROGMEM strings + * + * @param level - DEBUG, INFO, WARNING, ERROR, FATAL + * @param tag - Module name + * @param lineNum- line Number + * @param logStr - log string + */ + void OCLog(LogLevel level, PROGMEM const char *tag, const int lineNum, + PROGMEM const char *logStr); + + /** + * Output the contents of the specified buffer (in hex) with the specified priority level. + * + * @param level - DEBUG, INFO, WARNING, ERROR, FATAL + * @param tag - Module name + * @param buffer - pointer to buffer of bytes + * @param bufferSize - max number of byte in buffer + */ + void OCLogBuffer(LogLevel level, const char *tag, const uint8_t *buffer, size_t bufferSize); + + /** + * Output a variable argument list log string with the specified priority level. + * + * @param level - DEBUG, INFO, WARNING, ERROR, FATAL + * @param tag - Module name + * @param lineNum- line Number + * @param format - variadic log string + */ + void OCLogv(LogLevel level, PROGMEM const char *tag, const int lineNum, + PROGMEM const char *format, ...) +#if defined(__GNUC__) + __attribute__ ((format(printf, 4, 5))) +#endif +; +#endif + +#ifdef TB_LOG + +#ifdef __TIZEN__ + +#define OIC_LOG(level,tag,mes) LOG_(LOG_ID_MAIN, (level), (tag), mes) +#define OIC_LOG_V(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, level, tag, fmt, ##args) +#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)\ + OCLogBuffer((level), (tag), (buffer), (bufferSize)) + +#else // These macros are defined for Linux, Android, Win32, and Arduino + +#define OIC_LOG_INIT() OCLogInit() + +#ifdef ARDUINO + +#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) OCLogBuffer((level), PCF(tag), (buffer), (bufferSize)) +// Don't define variable argument log function for Arduino +#define OIC_LOG_V(level, tag, format, ...) OCLogv((level), PCF(tag), __LINE__, PCF(format),__VA_ARGS__) + +#define OIC_LOG_CONFIG(ctx) +#define OIC_LOG_SHUTDOWN() +#define OIC_LOG(level, tag, logStr) OCLog((level), PCF(tag), __LINE__, PCF(logStr)) +#define OIC_LOG_V(level, tag, ...) + +#else + +#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) OCLogBuffer((level), (tag), (buffer), (bufferSize)) +#define OIC_LOG_CONFIG(ctx) OCLogConfig((ctx)) +#define OIC_LOG_SHUTDOWN() OCLogShutdown() +#define OIC_LOG(level, tag, logStr) OCLog((level), (tag), (logStr)) +// Define variable argument log function for Linux, Android, and Win32 +#define OIC_LOG_V(level, tag, ...) OCLogv((level), (tag), __VA_ARGS__) + +#endif //ARDUINO +#endif //__TIZEN__ + +#else //TB_LOG + +#define OIC_LOG_CONFIG(ctx) +#define OIC_LOG_SHUTDOWN() +#define OIC_LOG(level, tag, logStr) +#define OIC_LOG_V(level, tag, ...) +#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) +#define OIC_LOG_INIT() +#endif + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif /* LOGGER_H_ */ diff --git a/inc/iotivity/logger_types.h b/inc/iotivity/logger_types.h new file mode 100644 index 0000000..69496bb --- /dev/null +++ b/inc/iotivity/logger_types.h @@ -0,0 +1,85 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_LOGGER_TYPES_H_ +#define OC_LOGGER_TYPES_H_ + +#include <stddef.h> + +#ifdef __cplusplus + extern "C" { +#endif + +typedef enum +{ + OC_LOG_MIN_VAL__ = -1, + OC_LOG_ALL = 0, + OC_LOG_FATAL, + OC_LOG_ERROR, + OC_LOG_WARNING, + OC_LOG_INFO, + OC_LOG_DEBUG, + OC_LOG_DISABLED, + OC_LOG_MAX_VAL__ +} oc_log_level; + +typedef struct _oc_log_ctx +{ + void* ctx; + + oc_log_level log_level; + + char* module_name; + + /* Required interface: */ + int (*init) (struct _oc_log_ctx *, void *); + void (*destroy) (struct _oc_log_ctx *); + void (*flush) (struct _oc_log_ctx *); + void (*set_level) (struct _oc_log_ctx *, const int); + size_t (*write_level) (struct _oc_log_ctx *, const int, const char *); + int (*set_module) (struct _oc_log_ctx *, const char *); + + /* Optional interface (if one is implemented, all must be implemented): */ + int (*lock) (struct _oc_log_ctx *); + int (*unlock) (struct _oc_log_ctx *); + int (*try_lock) (struct _oc_log_ctx *); + int (*locked_destroy) (struct _oc_log_ctx *); +} oc_log_ctx_t; + +/* Notice that these are all passed the /top level/ ctx-- it's "public" with respect to +these functions, they have full access to fiddle with the structure all they want (but, +generally should avoid doing that); I could certainly be convinced to go the other direction, +and have most functions only take the inner context: */ +typedef int (*oc_log_init_t) (oc_log_ctx_t *, void *); +typedef void (*oc_log_destroy_t) (oc_log_ctx_t *); +typedef void (*oc_log_flush_t) (oc_log_ctx_t *); +typedef void (*oc_log_set_level_t) (oc_log_ctx_t *, const int); +typedef size_t (*oc_log_write_level_t) (oc_log_ctx_t *, const int, const char *); +typedef int (*oc_log_set_module_t) (oc_log_ctx_t *, const char *); +typedef int (*oc_log_lock_t) (oc_log_ctx_t *); +typedef int (*oc_log_unlock_t) (oc_log_ctx_t *); +typedef int (*oc_log_try_lock_t) (oc_log_ctx_t *); + +#ifdef __cplusplus + } // extern "C" +#endif + +#endif + diff --git a/inc/iotivity/oc_log_stream.hpp b/inc/iotivity/oc_log_stream.hpp new file mode 100644 index 0000000..e6c8c2c --- /dev/null +++ b/inc/iotivity/oc_log_stream.hpp @@ -0,0 +1,80 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_LOG_STREAM_HPP_ +#define OC_LOG_STREAM_HPP_ + +#include <iosfwd> +#include <memory> +#include <cassert> +#include <iostream> + +#include <boost/config.hpp> +#include <boost/iostreams/stream.hpp> +#include <boost/iostreams/categories.hpp> +#include <boost/iostreams/detail/ios.hpp> + +#include "oc_logger.h" + +namespace OC { + +class oc_log_stream : boost::iostreams::sink +{ + std::shared_ptr<oc_log_ctx_t> m_log; + + public: + typedef char char_type; + typedef boost::iostreams::sink_tag category; + + public: + template <class ContextCtor> + oc_log_stream(ContextCtor& c) + : m_log { c(), oc_log_destroy } + {} + + template <class ContextCtor> + oc_log_stream(ContextCtor& c, void *world) + : m_log { c(world), oc_log_destroy } + {} + + public: + inline void flush() BOOST_NOEXCEPT { return oc_log_flush(m_log.get()); } + inline void set_level(const oc_log_level new_level) BOOST_NOEXCEPT { return oc_log_set_level(m_log.get(), new_level); } + inline int set_module(const std::string& module_name) BOOST_NOEXCEPT { return oc_log_set_module(m_log.get(), module_name.c_str()); } + + public: + std::streamsize write(const char_type *s, std::streamsize n) + { + /* It may seem strange to do this here, but it's a consequence of the + underlying library not supporting ptr+len style buffers at this time: */ + std::string s2(s, n + s); + + oc_log_write(m_log.get(), s2.c_str()); + + return n; + } + + private: + oc_log_stream operator=(const oc_log_stream&) = delete; +}; + +} // namespace OC + +#endif diff --git a/inc/iotivity/oc_logger.h b/inc/iotivity/oc_logger.h new file mode 100644 index 0000000..9fd3878 --- /dev/null +++ b/inc/iotivity/oc_logger.h @@ -0,0 +1,54 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_LOGGER_H_ +#define OC_LOGGER_H_ + +#include "oc_logger_types.h" + +#ifdef __cplusplus + extern "C" { +#endif + +/* Basic interface: */ +oc_log_ctx_t *oc_log_make_ctx( + void* world, + const oc_log_level level, + oc_log_init_t init, + oc_log_destroy_t destroy, + oc_log_flush_t flush, + oc_log_set_level_t set_level, + oc_log_write_level_t write_level, + oc_log_set_module_t set_module + ); + +void oc_log_destroy(oc_log_ctx_t *ctx); + +void oc_log_flush(oc_log_ctx_t *ctx); +void oc_log_set_level(oc_log_ctx_t *ctx, const oc_log_level ll); +size_t oc_log_write(oc_log_ctx_t *ctx, const char *msg); +size_t oc_log_write_level(oc_log_ctx_t *ctx, const oc_log_level ll, const char *msg); +int oc_log_set_module(oc_log_ctx_t *ctx, const char *module_name); + +#ifdef __cplusplus + } // extern "C" +#endif + +#endif diff --git a/inc/iotivity/oc_logger.hpp b/inc/iotivity/oc_logger.hpp new file mode 100644 index 0000000..3ddb762 --- /dev/null +++ b/inc/iotivity/oc_logger.hpp @@ -0,0 +1,31 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_LOGGER_HPP_ +#define OC_LOGGER_HPP_ + +#include "oc_logger.h" + +#include "oc_log_stream.hpp" + +#include "targets/oc_console_logger.h" +#include "targets/oc_ostream_logger.h" + +#endif diff --git a/inc/iotivity/oc_logger_types.h b/inc/iotivity/oc_logger_types.h new file mode 100644 index 0000000..83b6b3e --- /dev/null +++ b/inc/iotivity/oc_logger_types.h @@ -0,0 +1,86 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_LOGGER_TYPES_H_ +#define OC_LOGGER_TYPES_H_ + +#include <stddef.h> + +#ifdef __cplusplus + extern "C" { +#endif + + typedef enum + { + OC_LOG_MIN_VAL__ = -1, + OC_LOG_ALL = 0, + OC_LOG_FATAL, + OC_LOG_ERROR, + OC_LOG_WARNING, + OC_LOG_INFO, + OC_LOG_DEBUG, + OC_LOG_DISABLED, + OC_LOG_MAX_VAL__ + } oc_log_level; + +typedef struct _oc_log_ctx +{ + void* ctx; + + oc_log_level log_level; + + char* module_name; + + /* Required interface: */ + int (*init) (struct _oc_log_ctx *, void *); + void (*destroy) (struct _oc_log_ctx *); + void (*flush) (struct _oc_log_ctx *); + void (*set_level) (struct _oc_log_ctx *, const int); + size_t (*write_level) (struct _oc_log_ctx *, const int, const char *); + int (*set_module) (struct _oc_log_ctx *, const char *); + + /* Optional interface (if one is implemented, all must be implemented): */ + int (*lock) (struct _oc_log_ctx *); + int (*unlock) (struct _oc_log_ctx *); + int (*try_lock) (struct _oc_log_ctx *); + int (*locked_destroy) (struct _oc_log_ctx *); + +} oc_log_ctx_t; + +/* Notice that these are all passed the /top level/ ctx-- it's "public" with respect to +these functions, they have full access to fiddle with the structure all they want (but, +generally should avoid doing that); I could certainly be convinced to go the other direction, +and have most functions only take the inner context: */ +typedef int (*oc_log_init_t) (oc_log_ctx_t *, void *); +typedef void (*oc_log_destroy_t) (oc_log_ctx_t *); +typedef void (*oc_log_flush_t) (oc_log_ctx_t *); +typedef void (*oc_log_set_level_t) (oc_log_ctx_t *, const int); +typedef size_t (*oc_log_write_level_t) (oc_log_ctx_t *, const int, const char *); +typedef int (*oc_log_set_module_t) (oc_log_ctx_t *, const char *); +typedef int (*oc_log_lock_t) (oc_log_ctx_t *); +typedef int (*oc_log_unlock_t) (oc_log_ctx_t *); +typedef int (*oc_log_try_lock_t) (oc_log_ctx_t *); + +#ifdef __cplusplus + } // extern "C" +#endif + +#endif + diff --git a/inc/iotivity/ocpayload.h b/inc/iotivity/ocpayload.h new file mode 100644 index 0000000..204af4f --- /dev/null +++ b/inc/iotivity/ocpayload.h @@ -0,0 +1,291 @@ +//****************************************************************** +// +// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OCPAYLOAD_H_ +#define OCPAYLOAD_H_ + +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif + +#include <stdbool.h> +#include <inttypes.h> +#include "octypes.h" + +#if defined(__WITH_TLS__) || defined(__WITH_DTLS__) +#include "securevirtualresourcetypes.h" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * Macro to verify the validity of cbor operation. + */ +#define VERIFY_CBOR_SUCCESS(log_tag, err, log_message) \ + if ((CborNoError != (err)) && (CborErrorOutOfMemory != (err))) \ + { \ + if ((log_tag) && (log_message)) \ + { \ + OIC_LOG_V(ERROR, (log_tag), "%s with cbor error: \'%s\'.", \ + (log_message), (cbor_error_string(err))); \ + } \ + goto exit; \ + } \ + +#define VERIFY_PARAM_NON_NULL(log_tag, err, log_message) \ + if (NULL == (err)) \ + { \ + OIC_LOG_V(FATAL, (log_tag), "%s", (log_message)); \ + goto exit;\ + } \ + + +typedef struct OCResource OCResource; + +void OCPayloadDestroy(OCPayload* payload); + +// Representation Payload +OCRepPayload* OCRepPayloadCreate(); + +size_t calcDimTotal(const size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +OCRepPayload* OCRepPayloadClone(const OCRepPayload* payload); + +OCRepPayload* OCRepPayloadBatchClone(const OCRepPayload* repPayload); + +void OCRepPayloadAppend(OCRepPayload* parent, OCRepPayload* child); + +bool OCRepPayloadSetUri(OCRepPayload* payload, const char* uri); + +bool OCRepPayloadAddResourceType(OCRepPayload* payload, const char* resourceType); +bool OCRepPayloadAddInterface(OCRepPayload* payload, const char* iface); +bool OCRepPayloadAddModelVersion(OCRepPayload* payload, const char* dmv); + +bool OCRepPayloadAddResourceTypeAsOwner(OCRepPayload* payload, char* resourceType); +bool OCRepPayloadAddInterfaceAsOwner(OCRepPayload* payload, char* iface); + +bool OCRepPayloadIsNull(const OCRepPayload* payload, const char* name); +bool OCRepPayloadSetNull(OCRepPayload* payload, const char* name); + +bool OCRepPayloadSetPropInt(OCRepPayload* payload, const char* name, int64_t value); +bool OCRepPayloadGetPropInt(const OCRepPayload* payload, const char* name, int64_t* value); + +bool OCRepPayloadSetPropDouble(OCRepPayload* payload, const char* name, double value); +bool OCRepPayloadGetPropDouble(const OCRepPayload* payload, const char* name, double* value); + +/** + * This function allocates memory for the byte string and sets it in the payload. + * + * @param payload Pointer to the payload to which byte string needs to be added. + * @param name Name of the byte string. + * @param value Byte string and it's length. + * + * @return true on success, false upon failure. + */ +bool OCRepPayloadSetPropByteString(OCRepPayload* payload, const char* name, OCByteString value); + +/** + * This function sets the byte string in the payload. + * + * @param payload Pointer to the payload to which byte string needs to be added. + * @param name Name of the byte string. + * @param value Byte string and it's length. + * + * @return true on success, false upon failure. + */ +bool OCRepPayloadSetPropByteStringAsOwner(OCRepPayload* payload, const char* name, + OCByteString* value); + +/** + * This function gets the byte string from the payload. + * + * @param payload Pointer to the payload from which byte string needs to be retrieved. + * @param name Name of the byte string. + * @param value Byte string and it's length. + * + * @note: Caller needs to invoke OCFree on value.bytes after it is finished using the byte string. + * + * @return true on success, false upon failure. + */ +bool OCRepPayloadGetPropByteString(const OCRepPayload* payload, const char* name, + OCByteString* value); + +bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value); +bool OCRepPayloadSetPropStringAsOwner(OCRepPayload* payload, const char* name, char* value); +bool OCRepPayloadGetPropString(const OCRepPayload* payload, const char* name, char** value); + +bool OCRepPayloadSetPropBool(OCRepPayload* payload, const char* name, bool value); +bool OCRepPayloadGetPropBool(const OCRepPayload* payload, const char* name, bool* value); + +bool OCRepPayloadSetPropObject(OCRepPayload* payload, const char* name, const OCRepPayload* value); +bool OCRepPayloadSetPropObjectAsOwner(OCRepPayload* payload, const char* name, OCRepPayload* value); +bool OCRepPayloadGetPropObject(const OCRepPayload* payload, const char* name, OCRepPayload** value); + +#ifdef __WITH_TLS__ +bool OCRepPayloadSetPropPubDataType(OCRepPayload *payload, const char *name, const OicSecKey_t *value); +bool OCRepPayloadSetPropPubDataTypeAsOwner(OCRepPayload *payload, const char *name, const OicSecKey_t *value); +bool OCRepPayloadGetPropPubDataType(const OCRepPayload *payload, const char *name, OicSecKey_t *value); +#endif + +/** + * This function allocates memory for the byte string array and sets it in the payload. + * + * @param payload Pointer to the payload to which byte string array needs to be added. + * @param name Name of the byte string. + * @param array Byte string array. + * @param dimensions Number of byte strings in above array. + * + * @return true on success, false upon failure. + */ +bool OCRepPayloadSetByteStringArrayAsOwner(OCRepPayload* payload, const char* name, + OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +/** + * This function sets the byte string array in the payload. + * + * @param payload Pointer to the payload to which byte string array needs to be added. + * @param name Name of the byte string. + * @param array Byte string array. + * @param dimensions Number of byte strings in above array. + * + * @return true on success, false upon failure. + */ +bool OCRepPayloadSetByteStringArray(OCRepPayload* payload, const char* name, + const OCByteString* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +/** + * This function gets the byte string array from the payload. + * + * @param payload Pointer to the payload from which byte string array needs to be retrieved. + * @param name Name of the byte string array. + * @param value Byte string array. + * @param dimensions Number of byte strings in above array. + * + * @note: Caller needs to invoke OICFree on 'bytes' field of all array elements after it is + * finished using the byte string array. + * + * @return true on success, false upon failure. + */ +bool OCRepPayloadGetByteStringArray(const OCRepPayload* payload, const char* name, + OCByteString** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +bool OCRepPayloadSetIntArrayAsOwner(OCRepPayload* payload, const char* name, + int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadSetIntArray(OCRepPayload* payload, const char* name, + const int64_t* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadGetIntArray(const OCRepPayload* payload, const char* name, + int64_t** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +bool OCRepPayloadSetDoubleArrayAsOwner(OCRepPayload* payload, const char* name, + double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadSetDoubleArray(OCRepPayload* payload, const char* name, + const double* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadGetDoubleArray(const OCRepPayload* payload, const char* name, + double** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +bool OCRepPayloadSetStringArrayAsOwner(OCRepPayload* payload, const char* name, + char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadSetStringArray(OCRepPayload* payload, const char* name, + const char** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadGetStringArray(const OCRepPayload* payload, const char* name, + char*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +bool OCRepPayloadSetBoolArrayAsOwner(OCRepPayload* payload, const char* name, + bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadSetBoolArray(OCRepPayload* payload, const char* name, + const bool* array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadGetBoolArray(const OCRepPayload* payload, const char* name, + bool** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +bool OCRepPayloadSetPropObjectArrayAsOwner(OCRepPayload* payload, const char* name, + OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadSetPropObjectArray(OCRepPayload* payload, const char* name, + const OCRepPayload** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); +bool OCRepPayloadGetPropObjectArray(const OCRepPayload* payload, const char* name, + OCRepPayload*** array, size_t dimensions[MAX_REP_ARRAY_DEPTH]); + +void OCRepPayloadDestroy(OCRepPayload* payload); + +// Discovery Payload +OCDiscoveryPayload* OCDiscoveryPayloadCreate(); + +OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size); +void OCSecurityPayloadDestroy(OCSecurityPayload* payload); + +#ifndef TCP_ADAPTER +void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, + uint16_t securePort); +#else +void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res, + uint16_t securePort, uint16_t tcpPort); +#endif +void OCDiscoveryPayloadAddNewResource(OCDiscoveryPayload* payload, OCResourcePayload* res); +bool OCResourcePayloadAddStringLL(OCStringLL **payload, const char* type); + +size_t OCDiscoveryPayloadGetResourceCount(OCDiscoveryPayload* payload); +OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, size_t index); + +void OCDiscoveryResourceDestroy(OCResourcePayload* payload); +void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload); + +// Presence Payload +OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge, + OCPresenceTrigger trigger, const char* resourceType); +void OCPresencePayloadDestroy(OCPresencePayload* payload); + +// Helper API +OCStringLL* CloneOCStringLL (OCStringLL* ll); +void OCFreeOCStringLL(OCStringLL* ll); + +/** + * This function creates a list from a string (with separated contents if several) + * @param text single string or CSV text fields + * @return newly allocated linked list + * @note separator is ',' (according to rfc4180, ';' is not valid) + **/ +OCStringLL* OCCreateOCStringLL(const char* text); + +/** + * This function creates a string from a list (with separated contents if several) + * @param ll Pointer to list + * @return newly allocated string. Caller takes ownership and must later free this memory with OICFree. + * @note separator is ',' (according to rfc4180) + **/ +char* OCCreateString(const OCStringLL* ll); + +/** + * This function copies contents (and allocates if necessary) + * @param dest existing bytestring (or null to allocate here) + * @param source existing bytestring + * @return true of success false on any errors + **/ +bool OCByteStringCopy(OCByteString *dest, const OCByteString *source); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/inc/iotivity/ocpresence.h b/inc/iotivity/ocpresence.h new file mode 100644 index 0000000..8213152 --- /dev/null +++ b/inc/iotivity/ocpresence.h @@ -0,0 +1,45 @@ +//****************************************************************** +// +// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OCPRESENCE_H_ +#define OCPRESENCE_H_ + +#ifdef WITH_PRESENCE + +/** + * The OCPresenceTrigger enum delineates the three spec-compliant modes for + * "Trigger." These enum values are then mapped to strings + * "create", "change", "delete", respectively, before getting encoded into + * the payload. + */ +typedef enum +{ + /** The creation of a resource is associated with this invocation. */ + OC_PRESENCE_TRIGGER_CREATE = 0, + + /** The change/update of a resource is associated this invocation. */ + OC_PRESENCE_TRIGGER_CHANGE = 1, + + /** The deletion of a resource is associated with this invocation.*/ + OC_PRESENCE_TRIGGER_DELETE = 2 +} OCPresenceTrigger; +#endif + +#endif diff --git a/inc/iotivity/ocstack.h b/inc/iotivity/ocstack.h new file mode 100644 index 0000000..6769fc1 --- /dev/null +++ b/inc/iotivity/ocstack.h @@ -0,0 +1,737 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains APIs for OIC Stack to be implemented. + */ + +#ifndef OCSTACK_H_ +#define OCSTACK_H_ + +#include <stdio.h> +#include <stdint.h> +#include "octypes.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** Macro to use Random port.*/ +#define USE_RANDOM_PORT (0) + +/* + * Function prototypes + */ + +/** + * This function Initializes the OC Stack. Must be called prior to starting the stack. + * + * @param mode OCMode Host device is client, server, or client-server. + * @param serverFlags OCTransportFlags Default server transport flags. + * @param clientFlags OCTransportFlags Default client transport flags. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags); + +/** + * This function Initializes the OC Stack. Must be called prior to starting the stack. + * + * @param ipAddr IP Address of host device. Deprecated parameter. + * @param port Port of host device. Deprecated parameter. + * @param mode OCMode Host device is client, server, or client-server. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode); + +#ifdef RA_ADAPTER +/** + * @brief Set Remote Access information for XMPP Client. + * @param raInfo [IN] remote access info. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCSetRAInfo(const OCRAInfo_t *raInfo); +#endif + +/** + * This function Stops the OC stack. Use for a controlled shutdown. + * + * @note: OCStop() performs operations similar to OCStopPresence(), as well as OCDeleteResource() on + * all resources this server is hosting. OCDeleteResource() performs operations similar to + * OCNotifyAllObservers() to notify all client observers that the respective resource is being + * deleted. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCStop(); + +/** + * This function starts receiving the multicast traffic. This can be only called + * when stack is in OC_STACK_INITIALIZED state but device is not receiving multicast + * traffic. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCStartMulticastServer(); + +/** + * This function stops receiving the multicast traffic. The rest of the stack + * keeps working and no resource are deleted. Device can still receive the unicast + * traffic. Once this is set, no response to multicast /oic/res will be sent by the + * device. This is to be used for devices that uses other entity to push resources. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCStopMulticastServer(); + +/** + * This function is Called in main loop of OC client or server. + * Allows low-level processing of stack services. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCProcess(); + +/** + * This function discovers or Perform requests on a specified resource + * (specified by that Resource's respective URI). + * + * @param handle To refer to the request sent out on behalf of + * calling this API. This handle can be used to cancel this operation + * via the OCCancel API. + * @note: This reference is handled internally, and should not be free'd by + * the consumer. A NULL handle is permitted in the event where the caller + * has no use for the return value. + * @param method To perform on the resource. + * @param requestUri URI of the resource to interact with. (Address prefix is deprecated in + * favor of destination.) + * @param destination Complete description of destination. + * @param payload Encoded request payload. + * @param connectivityType Modifier flags when destination is not given. + * @param qos Quality of service. Note that if this API is called on a uri with the + * well-known multicast IP address, the qos will be forced to ::OC_LOW_QOS + * since it is impractical to send other QOS levels on such addresses. + * @param cbData Asynchronous callback function that is invoked by the stack when + * discovery or resource interaction is received. The discovery could be + * related to filtered/scoped/particular resource. The callback is + * generated for each response received. + * @param options The address of an array containing the vendor specific header options + * to be sent with the request. + * @param numOptions Number of header options to be included. + * + * @note: Presence subscription amendments (i.e. adding additional resource type filters by calling + * this API again) require the use of the same base URI as the original request to successfully + * amend the presence filters. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCDoResource(OCDoHandle *handle, + OCMethod method, + const char *requestUri, + const OCDevAddr *destination, + OCPayload* payload, + OCConnectivityType connectivityType, + OCQualityOfService qos, + OCCallbackData *cbData, + OCHeaderOption *options, + uint8_t numOptions); +/** + * This function cancels a request associated with a specific @ref OCDoResource invocation. + * + * @param handle Used to identify a specific OCDoResource invocation. + * @param qos Used to specify Quality of Service(read below). + * @param options Used to specify vendor specific header options when sending + * explicit observe cancellation. + * @param numOptions Number of header options to be included. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCCancel(OCDoHandle handle, + OCQualityOfService qos, + OCHeaderOption * options, + uint8_t numOptions); + +/** + * Register Persistent storage callback. + * @param persistentStorageHandler Pointers to open, read, write, close & unlink handlers. + * + * @return + * OC_STACK_OK No errors; Success. + * OC_STACK_INVALID_PARAM Invalid parameter. + */ +OCStackResult OCRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler); + +#ifdef WITH_PRESENCE +/** + * When operating in OCServer or OCClientServer mode, + * this API will start sending out presence notifications to clients via multicast. + * Once this API has been called with a success, clients may query for this server's presence and + * this server's stack will respond via multicast. + * + * Server can call this function when it comes online for the first time, or when it comes back + * online from offline mode, or when it re enters network. + * + * @param ttl Time To Live in seconds. + * @note: If ttl is '0', then the default stack value will be used (60 Seconds). + * If ttl is greater than ::OC_MAX_PRESENCE_TTL_SECONDS, then the ttl will be + * set to ::OC_MAX_PRESENCE_TTL_SECONDS. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCStartPresence(const uint32_t ttl); + +/** + * When operating in OCServer or OCClientServer mode, this API will stop sending + * out presence notifications to clients via multicast. + * Once this API has been called with a success this server's stack will not respond to clients + * querying for this server's presence. + * + * Server can call this function when it is terminating, going offline, or when going + * away from network. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ + +OCStackResult OCStopPresence(); +#endif + + +/** + * This function sets default device entity handler. + * + * @param entityHandler Entity handler function that is called by ocstack to handle requests + * for any undefined resources or default actions.If NULL is passed it + * removes the device default entity handler. + * @param callbackParameter Parameter passed back when entityHandler is called. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCSetDefaultDeviceEntityHandler(OCDeviceEntityHandler entityHandler, void* callbackParameter); + +/** + * This function sets device information. + * + * Upon call to OCInit, the default Device Type (i.e. "rt") has already been set to the default + * Device Type "oic.wk.d". You do not have to specify "oic.wk.d" in the OCDeviceInfo.types linked + * list. The default Device Type is mandatory and always specified by this Device as the first + * Device Type. + * + * @param deviceInfo Structure passed by the server application containing the device + * information. + * + * @return + * ::OC_STACK_OK no errors. + * ::OC_STACK_INVALID_PARAM invalid parameter. + * ::OC_STACK_ERROR stack process error. + */ +OCStackResult OCSetDeviceInfo(OCDeviceInfo deviceInfo); + +/** + * This function sets platform information. + * + * @param platformInfo Structure passed by the server application containing + * the platform information. + * + * + * @return + * ::OC_STACK_OK no errors. + * ::OC_STACK_INVALID_PARAM invalid parameter. + * ::OC_STACK_ERROR stack process error. + */ +OCStackResult OCSetPlatformInfo(OCPlatformInfo platformInfo); + +/** + * This function creates a resource. + * + * @param handle Pointer to handle to newly created resource. Set by ocstack and + * used to refer to resource. + * @param resourceTypeName Name of resource type. Example: "core.led". + * @param resourceInterfaceName Name of resource interface. Example: "core.rw". + * @param uri URI of the resource. Example: "/a/led". + * @param entityHandler Entity handler function that is called by ocstack to handle + * requests, etc. + * NULL for default entity handler. + * @param callbackParam parameter passed back when entityHandler is called. + * @param resourceProperties Properties supported by resource. + * Example: ::OC_DISCOVERABLE|::OC_OBSERVABLE. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCCreateResource(OCResourceHandle *handle, + const char *resourceTypeName, + const char *resourceInterfaceName, + const char *uri, + OCEntityHandler entityHandler, + void* callbackParam, + uint8_t resourceProperties); + +/** + * This function adds a resource to a collection resource. + * + * @param collectionHandle Handle to the collection resource. + * @param resourceHandle Handle to resource to be added to the collection resource. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCBindResource(OCResourceHandle collectionHandle, OCResourceHandle resourceHandle); + +/** + * This function removes a resource from a collection resource. + * + * @param collectionHandle Handle to the collection resource. + * @param resourceHandle Handle to resource to be removed from the collection resource. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCUnBindResource(OCResourceHandle collectionHandle, OCResourceHandle resourceHandle); + +/** + * This function binds a resource type to a resource. + * + * @param handle Handle to the resource. + * @param resourceTypeName Name of resource type. Example: "core.led". + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCBindResourceTypeToResource(OCResourceHandle handle, + const char *resourceTypeName); +/** + * This function binds a resource interface to a resource. + * + * @param handle Handle to the resource. + * @param resourceInterfaceName Name of resource interface. Example: "core.rw". + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCBindResourceInterfaceToResource(OCResourceHandle handle, + const char *resourceInterfaceName); + +/** + * This function binds an entity handler to the resource. + * + * @param handle Handle to the resource that the contained resource is to be bound. + * @param entityHandler Entity handler function that is called by ocstack to handle requests. + * @param callbackParameter Context parameter that will be passed to entityHandler. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCBindResourceHandler(OCResourceHandle handle, + OCEntityHandler entityHandler, + void *callbackParameter); + +/** + * This function gets the number of resources that have been created in the stack. + * + * @param numResources Pointer to count variable. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCGetNumberOfResources(uint8_t *numResources); + +/** + * This function gets a resource handle by index. + * + * @param index Index of resource, 0 to Count - 1. + * + * @return Found resource handle or NULL if not found. + */ +OCResourceHandle OCGetResourceHandle(uint8_t index); + +/** + * This function deletes resource specified by handle. Deletes resource and all + * resource type and resource interface linked lists. + * + * @note: OCDeleteResource() performs operations similar to OCNotifyAllObservers() to notify all + * client observers that "this" resource is being deleted. + * + * @param handle Handle of resource to be deleted. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCDeleteResource(OCResourceHandle handle); + +/** + * Get a string representation the server instance ID. + * The memory is managed internal to this function, so freeing externally will result + * in a runtime error. + * Note: This will NOT seed the RNG, so it must be called after the RNG is seeded. + * This is done automatically during the OCInit process, + * so ensure that this call is done after that. + * + * @return A string representation the server instance ID. + */ +const char* OCGetServerInstanceIDString(void); + +/** + * This function gets the URI of the resource specified by handle. + * + * @param handle Handle of resource. + * + * @return URI string if resource found or NULL if not found. + */ +const char *OCGetResourceUri(OCResourceHandle handle); + +/** + * This function gets the properties of the resource specified by handle. + * + * @param handle Handle of resource. + * + * @return OCResourceProperty Bitmask or -1 if resource is not found. + * + * @note that after a resource is created, the OC_ACTIVE property is set for the resource by the + * stack. + */ +OCResourceProperty OCGetResourceProperties(OCResourceHandle handle); + +/** + * This function gets the number of resource types of the resource. + * + * @param handle Handle of resource. + * @param numResourceTypes Pointer to count variable. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCGetNumberOfResourceTypes(OCResourceHandle handle, uint8_t *numResourceTypes); + +/** + * This function gets name of resource type of the resource. + * + * @param handle Handle of resource. + * @param index Index of resource, 0 to Count - 1. + * + * @return Resource type name if resource found or NULL if resource not found. + */ +const char *OCGetResourceTypeName(OCResourceHandle handle, uint8_t index); + +/** + * This function gets the number of resource interfaces of the resource. + * + * @param handle Handle of resource. + * @param numResourceInterfaces Pointer to count variable. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCGetNumberOfResourceInterfaces(OCResourceHandle handle, + uint8_t *numResourceInterfaces); + +/** + * This function gets name of resource interface of the resource. + * + * @param handle Handle of resource. + * @param index Index of resource, 0 to Count - 1. + * + * @return Resource interface name if resource found or NULL if resource not found. + */ +const char *OCGetResourceInterfaceName(OCResourceHandle handle, uint8_t index); + +/** + * This function gets methods of resource interface of the resource. + * + * @param handle Handle of resource. + * @param index Index of resource, 0 to Count - 1. + * + * @return Allowed methods if resource found or NULL if resource not found. + */ +uint8_t OCGetResourceInterfaceAllowedMethods(OCResourceHandle handle, uint8_t index); + +/** + * This function gets resource handle from the collection resource by index. + * + * @param collectionHandle Handle of collection resource. + * @param index Index of contained resource, 0 to Count - 1. + * + * @return Handle to contained resource if resource found or NULL if resource not found. + */ +OCResourceHandle OCGetResourceHandleFromCollection(OCResourceHandle collectionHandle, + uint8_t index); + +/** + * This function gets the entity handler for a resource. + * + * @param handle Handle of resource. + * + * @return Entity handler if resource found or NULL resource not found. + */ +OCEntityHandler OCGetResourceHandler(OCResourceHandle handle); + +/** + * This function notify all registered observers that the resource representation has + * changed. If observation includes a query the client is notified only if the query is valid after + * the resource representation has changed. + * + * @param handle Handle of resource. + * @param qos Desired quality of service for the observation notifications. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCNotifyAllObservers(OCResourceHandle handle, OCQualityOfService qos); + +/** + * Notify specific observers with updated value of representation. + * Before this API is invoked by entity handler it has finished processing + * queries for the associated observers. + * + * @param handle Handle of resource. + * @param obsIdList List of observation IDs that need to be notified. + * @param numberOfIds Number of observation IDs included in obsIdList. + * @param payload Object representing the notification + * @param qos Desired quality of service of the observation notifications. + * + * @note: The memory for obsIdList and payload is managed by the entity invoking the API. + * The maximum size of the notification is 1015 bytes for non-Arduino platforms. For Arduino + * the maximum size is 247 bytes. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult +OCNotifyListOfObservers (OCResourceHandle handle, + OCObservationId *obsIdList, + uint8_t numberOfIds, + const OCRepPayload *payload, + OCQualityOfService qos); + + +/** + * This function sends a response to a request. + * The response can be a normal, slow, or block (i.e. a response that + * is too large to be sent in a single PDU and must span multiple transmissions). + * + * @param response Pointer to structure that contains response parameters. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCDoResponse(OCEntityHandlerResponse *response); + +//#ifdef DIRECT_PAIRING +/** + * The function is responsible for discovery of direct-pairing device is current subnet. It will list + * all the device in subnet which support direct-pairing. + * Caller must NOT free returned constant pointer + * + * @param[in] timeout Timeout in seconds, value till which function will listen to responses from + * client before returning the list of devices. + * @return OCDirectPairingDev_t pointer in case of success and NULL otherwise. + */ +const OCDPDev_t* OCDiscoverDirectPairingDevices(unsigned short waittime); + +/** + * The function is responsible for return of paired device list via direct-pairing. It will list + * all the device which is previousely paired with client. + * Caller must NOT free returned constant pointer + * + * @return OCDirectPairingDev_t pointer in case of success and NULL otherwise. + */ +const OCDPDev_t* OCGetDirectPairedDevices(); + +/** + * The function is responsible for establishment of direct-pairing. It will proceed mode negotiation + * and connect PIN based dtls session. + * + * @param[in] peer Target device to establish direct-pairing. + * @param[in] pmSel Selected mode of pairing. + * @param[in] pinNumber PIN number for authentication, pin lenght is defined DP_PIN_LENGTH(8). + * @param[in] resultCallback Callback fucntion to event status of process. + * @return OTM_SUCCESS in case of success and other value otherwise. + */ +OCStackResult OCDoDirectPairing(void *ctx, OCDPDev_t* peer, OCPrm_t pmSel, char *pinNumber, + OCDirectPairingCB resultCallback); + +#ifdef WITH_CHPROXY +/** + * This function sets uri being used for proxy. + * + * @param uri NULL terminated resource uri for CoAP-HTTP Proxy. + */ +OCStackResult OCSetProxyURI(const char *uri); +#endif + +#if defined(RD_CLIENT) || defined(RD_SERVER) +/** + * This function binds an resource unique id to the resource. + * + * @param handle Handle to the resource that the contained resource is to be bound. + * @param ins Unique ID for resource. + * + * @return ::OC_STACK_OK on success, some other value upon failure. + */ +OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins); + +/** + * This function gets the resource unique id for a resource. + * + * @param handle Handle of resource. + * @param ins Unique ID for resource. + * + * @return Ins if resource found or 0 resource not found. + */ +OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins); + +#endif + +/** +* This function gets a resource handle by resource uri. +* +* @param uri Uri of Resource to get Resource handle. +* +* @return Found resource handle or NULL if not found. +*/ +OCResourceHandle OCGetResourceHandleAtUri(const char *uri); + + +#ifdef RD_SERVER +/** +* Search the RD database for queries. +* +* @param interfaceType is the interface type that is queried. +* @param resourceType is the resource type that is queried. +* @param discPayload is NULL if no resource found or else OCDiscoveryPayload with the details +* about the resource. +* +* @return ::OC_STACK_OK in case of success or else other value. +*/ +OCStackResult OCRDDatabaseCheckResources(const char *interfaceType, const char *resourceType, + OCDiscoveryPayload *discPayload); +#endif +//#endif // DIRECT_PAIRING + +/** + * Add a header option to the given header option array. + * + * @param ocHdrOpt Pointer to existing options. + * @param numOptions Number of existing options. + * @param optionID COAP option ID. + * @param optionData Option data value. + * @param optionDataLength Size of Option data value. + * + * @return ::OC_STACK_OK on success and other value otherwise. + */ +OCStackResult +OCSetHeaderOption(OCHeaderOption* ocHdrOpt, + size_t* numOptions, + uint16_t optionID, + void* optionData, + size_t optionDataLength); + +/** + * Get data value of the option with specified option ID from given header option array. + * + * @param ocHdrOpt Pointer to existing options. + * @param numOptions Number of existing options. + * @param optionID COAP option ID. + * @param optionData Pointer to option data. + * @param optionDataLength Size of option data value. + * @param receivedDatalLength Pointer to the actual length of received data. + * + * @return ::OC_STACK_OK on success and other value otherwise. + */ +OCStackResult +OCGetHeaderOption(OCHeaderOption* ocHdrOpt, + size_t numOptions, + uint16_t optionID, + void* optionData, + size_t optionDataLength, + uint16_t* receivedDatalLength); + +/** + * gets the deviceId of the client + * + * @param deviceId pointer. + * @return Returns ::OC_STACK_OK if success. + */ +OCStackResult OCGetDeviceId(OCUUIdentity *deviceId); + +/** + * sets the deviceId of the client + * + * @param deviceId pointer. + * @return Returns ::OC_STACK_OK if success. + */ +OCStackResult OCSetDeviceId(const OCUUIdentity *deviceId); + +/** + * Encode an address string to match RFC 6874. + * + * @param outputAddress a char array to be written with the encoded string. + * + * @param outputSize size of outputAddress buffer. + * + * @param inputAddress a char array of size <= CA_MAX_URI_LENGTH + * containing a valid IPv6 address string. + * + * @return ::OC_STACK_OK on success and other value otherwise. + */ +OCStackResult OCEncodeAddressForRFC6874(char* outputAddress, + size_t outputSize, + const char* inputAddress); + +/** + * Decode an address string according to RFC 6874. + * + * @param outputAddress a char array to be written with the decoded string. + * + * @param outputSize size of outputAddress buffer. + * + * @param inputAddress a valid percent-encoded address string. + * + * @param end NULL if the entire entire inputAddress is a null-terminated percent- + * encoded address string. Otherwise, a pointer to the first byte that + * is not part of the address string (e.g., ']' in a URI). + * + * @return ::OC_STACK_OK on success and other value otherwise. + */ +OCStackResult OCDecodeAddressForRFC6874(char* outputAddress, + size_t outputSize, + const char* inputAddress, + const char* end); + +/** + * Set the value of /oic/d and /oic/p properties. This function is a generic function that sets for + * all OCF defined properties. + * + * @param type the payload type for device and platform as defined in @ref OCPayloadType. + * @param propName the pre-defined property as per OCF spec. + * @param value the value of the property to be set. + * + * @return ::OC_STACK_OK on success and other value otherwise. + */ +OCStackResult OCSetPropertyValue(OCPayloadType type, const char *propName, const void *value); + +/** + * Get the value of /oic/d and /oic/p properties. This function is a generic function that get value + * for all OCF defined properties. + * + * @param type the payload type for device and platform as defined in @ref OCPayloadType. + * @param propName the pre-defined as per OCF spec. + * @param value this holds the return value. In case of error will be set to NULL. + * + * @return ::OC_STACK_OK on success and other value otherwise. + */ +OCStackResult OCGetPropertyValue(OCPayloadType type, const char *propName, void **value); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif /* OCSTACK_H_ */ diff --git a/inc/iotivity/ocstackconfig.h b/inc/iotivity/ocstackconfig.h new file mode 100644 index 0000000..d71c096 --- /dev/null +++ b/inc/iotivity/ocstackconfig.h @@ -0,0 +1,114 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains all the variables which can be configured/modified as + * per platform or specific product usage scenarios. + */ + +#ifndef OCSTACK_CONFIG_H_ +#define OCSTACK_CONFIG_H_ + +/** + * Maximum length of the URI supported by client/server while processing + * REST requests/responses. + */ +#ifdef ARDUINO +#define MAX_URI_LENGTH (64) +#else +#define MAX_URI_LENGTH (256) +#endif + +/** + * Maximum length of the query supported by client/server while processing + * REST requests/responses. + */ +#ifdef ARDUINO +#define MAX_QUERY_LENGTH (64) +#else +#define MAX_QUERY_LENGTH (256) +#endif + + +/** + * Maximum length of the Manufacturer name supported by the server + * for manufacturer name. + * @deprecated use MAX_PLATFORM_NAME_LENGTH instead. + */ +#define MAX_MANUFACTURER_NAME_LENGTH (64) + +/** + * Maximum length of the URL to the Manufacturer details supported by + * the server. + * @deprecated use MAX_PLATFORM_URL_LENGTH instead. + */ +#define MAX_MANUFACTURER_URL_LENGTH (256) + +/** + * Maximum length of the value supported by the server + * for platform property of type string. + */ +#define MAX_PLATFORM_NAME_LENGTH (64) + +/** + * Maximum length of the URL supported by the server + * for platform property of type url. + */ +#define MAX_PLATFORM_URL_LENGTH (256) + +/** + * Maximum number of resources which can be contained inside collection + * resource. + */ +#define MAX_CONTAINED_RESOURCES (5) + +/** + * Maximum number of vendor specific header options an application can set or receive + * in PDU + */ +#ifdef ARDUINO +#define MAX_HEADER_OPTIONS (2) +#else +#define MAX_HEADER_OPTIONS (50) +#endif + +/** + * Maximum Length of the vendor specific header option + */ +#ifdef ARDUINO +#define MAX_HEADER_OPTION_DATA_LENGTH (20) +#else +#define MAX_HEADER_OPTION_DATA_LENGTH (1024) +#endif + +/** + * Sets the time to live (TTL) for response callback(s). + * The callback(s) will be up for deletion after such time but are not guaranteed + * to be deleted immediately and you may get responses even after timeout. + * This timeout will NOT apply to OBSERVE requests. OBSERVE needs an explicit cancel using OCCancel(). + * @note: Changing the setting to a very long duration may lead to unsupported and untested + * operation. Setting this to as small a value as reasonable will reclaim memory faster. + */ +#define MAX_CB_TIMEOUT_SECONDS (2 * 60 * 60) // 2 hours = 7200 seconds. + +#endif //OCSTACK_CONFIG_H_ diff --git a/inc/iotivity/octypes.h b/inc/iotivity/octypes.h new file mode 100755 index 0000000..2117fc3 --- /dev/null +++ b/inc/iotivity/octypes.h @@ -0,0 +1,1716 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains the definition, types and APIs for resource(s) be implemented. + */ + +#ifndef OCTYPES_H_ +#define OCTYPES_H_ + +#include "iotivity_config.h" +#include "ocstackconfig.h" +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#ifdef __cplusplus +#include <string.h> + +extern "C" { +#endif // __cplusplus + +/** For the feature presence.*/ +#define WITH_PRESENCE + +#include "ocpresence.h" +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- + +/** + * OIC Virtual resources supported by every OIC device. + */ +/** + * Default discovery mechanism using '/oic/res' is supported by all OIC devices + * That are Discoverable. + */ +#define OC_RSRVD_WELL_KNOWN_URI "/oic/res" + +/** Device URI.*/ +#define OC_RSRVD_DEVICE_URI "/oic/d" + +/** Platform URI.*/ +#define OC_RSRVD_PLATFORM_URI "/oic/p" + +/** Resource Type.*/ +#define OC_RSRVD_RESOURCE_TYPES_URI "/oic/res/types/d" + +/** Gateway URI.*/ +#define OC_RSRVD_GATEWAY_URI "/oic/gateway" + +/** MQ Broker URI.*/ +#define OC_RSRVD_WELL_KNOWN_MQ_URI "/oic/ps" + +/** KeepAlive URI.*/ +#define OC_RSRVD_KEEPALIVE_URI "/oic/ping" + + +/** Presence */ + +/** Presence URI through which the OIC devices advertise their presence.*/ +#define OC_RSRVD_PRESENCE_URI "/oic/ad" + +/** Presence URI through which the OIC devices advertise their device presence.*/ +#define OC_RSRVD_DEVICE_PRESENCE_URI "/oic/prs" + +/** Sets the default time to live (TTL) for presence.*/ +#define OC_DEFAULT_PRESENCE_TTL_SECONDS (60) + +/** For multicast Discovery mechanism.*/ +#define OC_MULTICAST_DISCOVERY_URI "/oic/res" + +/** Separator for multiple query string.*/ +#define OC_QUERY_SEPARATOR "&;" + +/** + * OC_DEFAULT_PRESENCE_TTL_SECONDS sets the default time to live (TTL) for presence. + */ +#define OC_DEFAULT_PRESENCE_TTL_SECONDS (60) + +/** + * OC_MAX_PRESENCE_TTL_SECONDS sets the maximum time to live (TTL) for presence. + * NOTE: Changing the setting to a longer duration may lead to unsupported and untested + * operation. + * 60 sec/min * 60 min/hr * 24 hr/day + */ +#define OC_MAX_PRESENCE_TTL_SECONDS (60 * 60 * 24) + + +/** + * Presence "Announcement Triggers". + */ + +/** To create.*/ +#define OC_RSRVD_TRIGGER_CREATE "create" + +/** To change.*/ +#define OC_RSRVD_TRIGGER_CHANGE "change" + +/** To delete.*/ +#define OC_RSRVD_TRIGGER_DELETE "delete" + +/** + * Attributes used to form a proper OIC conforming JSON message. + */ + +#define OC_RSRVD_OC "oic" + + +/** For payload. */ + +#define OC_RSRVD_PAYLOAD "payload" + +/** To represent href */ +#define OC_RSRVD_HREF "href" + +/** To represent property*/ +#define OC_RSRVD_PROPERTY "prop" + +/** For representation.*/ +#define OC_RSRVD_REPRESENTATION "rep" + +/** To represent content type.*/ +#define OC_RSRVD_CONTENT_TYPE "ct" + +/** To represent resource type.*/ +#define OC_RSRVD_RESOURCE_TYPE "rt" + +/** To represent resource type with presence.*/ +#define OC_RSRVD_RESOURCE_TYPE_PRESENCE "oic.wk.ad" + +/** To represent resource type with device.*/ +#define OC_RSRVD_RESOURCE_TYPE_DEVICE "oic.wk.d" + +/** To represent resource type with platform.*/ +#define OC_RSRVD_RESOURCE_TYPE_PLATFORM "oic.wk.p" + +/** To represent resource type with collection.*/ +#define OC_RSRVD_RESOURCE_TYPE_COLLECTION "oic.wk.col" + +/** To represent resource type with RES.*/ +#define OC_RSRVD_RESOURCE_TYPE_RES "oic.wk.res" + +/** To represent content type with MQ Broker.*/ +#define OC_RSRVD_RESOURCE_TYPE_MQ_BROKER "oic.wk.ps" + +/** To represent content type with MQ Topic.*/ +#define OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC "oic.wk.ps.topic" + + +/** To represent interface.*/ +#define OC_RSRVD_INTERFACE "if" + +/** To indicate how long RD should publish this item.*/ +#define OC_RSRVD_DEVICE_TTL "lt" + +/** To represent time to live.*/ +#define OC_RSRVD_TTL "ttl" + +/** To represent non*/ +#define OC_RSRVD_NONCE "non" + +/** To represent trigger type.*/ +#define OC_RSRVD_TRIGGER "trg" + +/** To represent links.*/ +#define OC_RSRVD_LINKS "links" + +/** To represent default interface.*/ +#define OC_RSRVD_INTERFACE_DEFAULT "oic.if.baseline" + +/** To represent read-only interface.*/ +#define OC_RSRVD_INTERFACE_READ "oic.if.r" + +/** To represent ll interface.*/ +#define OC_RSRVD_INTERFACE_LL "oic.if.ll" + +/** To represent batch interface.*/ +#define OC_RSRVD_INTERFACE_BATCH "oic.if.b" + +/** To represent interface group.*/ +#define OC_RSRVD_INTERFACE_GROUP "oic.mi.grp" + +/** To represent MFG date.*/ +#define OC_RSRVD_MFG_DATE "mndt" + +/** To represent FW version.*/ +#define OC_RSRVD_FW_VERSION "mnfv" + +/** To represent host name.*/ +#define OC_RSRVD_HOST_NAME "hn" + +/** To represent policy.*/ +#define OC_RSRVD_POLICY "p" + +/** To represent bitmap.*/ +#define OC_RSRVD_BITMAP "bm" + +/** For security.*/ +#define OC_RSRVD_SECURE "sec" + +/** Port. */ +#define OC_RSRVD_HOSTING_PORT "port" + +/** TCP Port. */ +#define OC_RSRVD_TCP_PORT "tcp" + +/** TLS Port. */ +#define OC_RSRVD_TLS_PORT "tls" + +/** For Server instance ID.*/ +#define OC_RSRVD_SERVER_INSTANCE_ID "sid" + +/** + * Platform. + */ + +/** Platform ID. */ +#define OC_RSRVD_PLATFORM_ID "pi" + +/** Platform MFG NAME. */ +#define OC_RSRVD_MFG_NAME "mnmn" + +/** Platform URL. */ +#define OC_RSRVD_MFG_URL "mnml" + +/** Model Number.*/ +#define OC_RSRVD_MODEL_NUM "mnmo" + +/** Platform MFG Date.*/ +#define OC_RSRVD_MFG_DATE "mndt" + +/** Platform versio.n */ +#define OC_RSRVD_PLATFORM_VERSION "mnpv" + +/** Platform Operating system version. */ +#define OC_RSRVD_OS_VERSION "mnos" + +/** Platform Hardware version. */ +#define OC_RSRVD_HARDWARE_VERSION "mnhw" + +/**Platform Firmware version. */ +#define OC_RSRVD_FIRMWARE_VERSION "mnfv" + +/** Support URL for the platform. */ +#define OC_RSRVD_SUPPORT_URL "mnsl" + +/** System time for the platform. */ +#define OC_RSRVD_SYSTEM_TIME "st" + +/** VID for the platform. */ +#define OC_RSRVD_VID "vid" +/** + * Device. + */ + +/** Device ID.*/ +#define OC_RSRVD_DEVICE_ID "di" + +/** Device Name.*/ +#define OC_RSRVD_DEVICE_NAME "n" + +/** Device specification version.*/ +#define OC_RSRVD_SPEC_VERSION "icv" + +/** Device data model.*/ +#define OC_RSRVD_DATA_MODEL_VERSION "dmv" + +/** Device specification version.*/ +#define OC_SPEC_VERSION "core.1.1.0" + +/** Device Data Model version.*/ +#define OC_DATA_MODEL_VERSION "res.1.1.0,sh.1.1.0" +/** + * These provide backward compatibility - their use is deprecated. + */ +#ifndef GOING_AWAY + +/** Multicast Prefix.*/ +#define OC_MULTICAST_PREFIX "224.0.1.187:5683" + +/** Multicast IP address.*/ +#define OC_MULTICAST_IP "224.0.1.187" + +/** Multicast Port.*/ +#define OC_MULTICAST_PORT (5683) +#endif // GOING_AWAY + +/** Max Device address size. */ +#ifdef RA_ADAPTER +#define MAX_ADDR_STR_SIZE (256) +#else +/** Max Address could be + * "coaps+tcp://[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:yyy.yyy.yyy.yyy]:xxxxx" + * +1 for null terminator. + */ +#define MAX_ADDR_STR_SIZE (66) +#endif + +/** Length of MAC address */ +#define MAC_ADDR_STR_SIZE (17) + +/** Blocks of MAC address */ +#define MAC_ADDR_BLOCKS (6) + +/** Max identity size. */ +#define MAX_IDENTITY_SIZE (37) + +/** Universal unique identity size. */ +#define UUID_IDENTITY_SIZE (128/8) + +/** Resource Directory */ + +/** Resource Directory URI used to Discover RD and Publish resources.*/ +#define OC_RSRVD_RD_URI "/oic/rd" + +/** To represent resource type with rd.*/ +#define OC_RSRVD_RESOURCE_TYPE_RD "oic.wk.rd" + +/** RD Discovery bias factor type. */ +#define OC_RSRVD_RD_DISCOVERY_SEL "sel" + +/** Resource URI used to discover Proxy */ +#define OC_RSRVD_PROXY_URI "/oic/chp" + +/** Resource URI used to discover Proxy */ +#define OC_RSRVD_PROXY_OPTION_ID 35 + +/** Base URI. */ +#define OC_RSRVD_BASE_URI "baseURI" + +/** Unique value per collection/link. */ +#define OC_RSRVD_INS "ins" + +/** Allowable resource types in the links. */ +#define OC_RSRVD_RTS "rts" + +/** Default relationship. */ +#define OC_RSRVD_DREL "drel" + +/** Defines relationship between links. */ +#define OC_RSRVD_REL "rel" + +/** Defines title. */ +#define OC_RSRVD_TITLE "title" + +/** Defines URI. */ +#define OC_RSRVD_URI "anchor" + +/** Defines media type. */ +#define OC_RSRVD_MEDIA_TYPE "type" + +/** To represent resource type with Publish RD.*/ +#define OC_RSRVD_RESOURCE_TYPE_RDPUBLISH "oic.wk.rdpub" + +/** Cloud Account */ + +/** Account URI.*/ +#define OC_RSRVD_ACCOUNT_URI "/oic/account" + +/** Account user URI.*/ +#define OC_RSRVD_ACCOUNT_SEARCH_URI "/oic/account/search" + +/** Account session URI.*/ +#define OC_RSRVD_ACCOUNT_SESSION_URI "/oic/account/session" + +/** Account token refresh URI.*/ +#define OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI "/oic/account/tokenrefresh" + +/** ACL group URI.*/ +#define OC_RSRVD_ACL_GROUP_URI "/oic/acl/group" + +/** ACL invite URI.*/ +#define OC_RSRVD_ACL_INVITE_URI "/oic/acl/invite" + +/** Defines auth provider. */ +#define OC_RSRVD_AUTHPROVIDER "authprovider" + +/** Defines auth code. */ +#define OC_RSRVD_AUTHCODE "authcode" + +/** Defines access token. */ +#define OC_RSRVD_ACCESS_TOKEN "accesstoken" + +/** Defines login. */ +#define OC_RSRVD_LOGIN "login" + +/** Defines search. */ +#define OC_RSRVD_SEARCH "search" + +/** Defines grant type. */ +#define OC_RSRVD_GRANT_TYPE "granttype" + +/** Defines refresh token. */ +#define OC_RSRVD_REFRESH_TOKEN "refreshtoken" + +/** Defines user UUID. */ +#define OC_RSRVD_USER_UUID "uid" + +/** Defines group ID. */ +#define OC_RSRVD_GROUP_ID "gid" + +/** Defines member of group ID. */ +#define OC_RSRVD_MEMBER_ID "mid" + +/** Defines invite. */ +#define OC_RSRVD_INVITE "invite" + +/** Defines accept. */ +#define OC_RSRVD_ACCEPT "accept" + +/** Defines operation. */ +#define OC_RSRVD_OPERATION "op" + +/** Defines add. */ +#define OC_RSRVD_ADD "add" + +/** Defines delete. */ +#define OC_RSRVD_DELETE "delete" + +/** Defines owner. */ +#define OC_RSRVD_OWNER "owner" + +/** Defines members. */ +#define OC_RSRVD_MEMBERS "members" + +/** To represent grant type with refresh token. */ +#define OC_RSRVD_GRANT_TYPE_REFRESH_TOKEN "refresh_token" + +/** Cloud CRL */ +#define OC_RSRVD_PROV_CRL_URL "/oic/credprov/crl" + +#define OC_RSRVD_LAST_UPDATE "lu" + +#define OC_RSRVD_THIS_UPDATE "tu" + +#define OC_RSRVD_NEXT_UPDATE "nu" + +#define OC_RSRVD_SERIAL_NUMBERS "rcsn" + +#define OC_RSRVD_CRL "crl" + +#define OC_RSRVD_CRL_ID "crlid" + +/** Cloud ACL */ +#define OC_RSRVD_GROUP_URL "/oic/group" + +#define OC_RSRVD_ACL_GROUP_URL "/oic/acl/group" + +#define OC_RSRVD_ACL_INVITE_URL "/oic/acl/invite" + +#define OC_RSRVD_ACL_VERIFY_URL "/oic/acl/verify" + +#define OC_RSRVD_ACL_ID_URL "/oic/acl/id" + +#define OC_RSRVD_MEMBER_ID "mid" + +#define OC_RSRVD_GROUP_ID "gid" + +#define OC_RSRVD_OWNER_ID "oid" + +#define OC_RSRVD_ACL_ID "aclid" + +#define OC_RSRVD_ACE_ID "aceid" + +#define OC_RSRVD_DEVICE_ID "di" + +#define OC_RSRVD_SUBJECT_ID "sid" + +#define OC_RSRVD_REQUEST_METHOD "rm" + +#define OC_RSRVD_REQUEST_URI "uri" + +#define OC_RSRVD_GROUP_MASTER_ID "gmid" + +#define OC_RSRVD_GROUP_TYPE "gtype" + +#define OC_RSRVD_SUBJECT_TYPE "stype" + +#define OC_RSRVD_GROUP_ID_LIST "gidlist" + +#define OC_RSRVD_MEMBER_ID_LIST "midlist" + +#define OC_RSRVD_DEVICE_ID_LIST "dilist" + +#define OC_RSRVD_ACCESS_CONTROL_LIST "aclist" + +#define OC_RSRVD_RESOURCES "resources" + +#define OC_RSRVD_VALIDITY "validity" + +#define OC_RSRVD_PERIOD "period" + +#define OC_RSRVD_RECURRENCE "recurrence" + +#define OC_RSRVD_INVITE "invite" + +#define OC_RSRVD_INVITED "invited" + +#define OC_RSRVD_ENCODING "encoding" + +#define OC_OIC_SEC "oic.sec" + +#define OC_RSRVD_BASE64 "base64" + +#define OC_RSRVD_DER "der" + +#define OC_RSRVD_PEM "pem" + +#define OC_RSRVD_RAW "raw" + +#define OC_RSRVD_UNKNOWN "unknown" + +#define OC_RSRVD_DATA "data" + +#define OC_RSRVD_RESOURCE_OWNER_UUID "rowneruuid" + +#define OC_RSRVD_SUBJECT_UUID "subjectuuid" + +#define OC_RSRVD_PERMISSION_MASK "permission" + +#define OC_RSRVD_GROUP_PERMISSION "gp" + +#define OC_RSRVD_GROUP_ACL "gacl" + +/** Certificete Sign Request */ +#define OC_RSRVD_PROV_CERT_URI "/oic/credprov/cert" + +#define OC_RSRVD_CSR "csr" + +#define OC_RSRVD_CERT "cert" + +#define OC_RSRVD_CACERT "certchain" + +#define OC_RSRVD_TOKEN_TYPE "tokentype" + +#define OC_RSRVD_EXPIRES_IN "expiresin" + +#define OC_RSRVD_REDIRECT_URI "redirecturi" + +#define OC_RSRVD_CERTIFICATE "certificate" +/** + * Mark a parameter as unused. Used to prevent unused variable compiler warnings. + * Used in three cases: + * 1. in callbacks when one of the parameters are unused + * 2. when due to code changes a functions parameter is no longer + * used but must be left in place for backward compatibility + * reasons. + * 3. a variable is only used in the debug build variant and would + * give a build warning in release mode. + */ +#define OC_UNUSED(x) (void)(x) + +/** + * These enums (OCTransportAdapter and OCTransportFlags) must + * be kept synchronized with OCConnectivityType (below) as well as + * CATransportAdapter and CATransportFlags (in CACommon.h). + */ +typedef enum +{ + /** value zero indicates discovery.*/ + OC_DEFAULT_ADAPTER = 0, + + /** IPv4 and IPv6, including 6LoWPAN.*/ + OC_ADAPTER_IP = (1 << 0), + + /** GATT over Bluetooth LE.*/ + OC_ADAPTER_GATT_BTLE = (1 << 1), + + /** RFCOMM over Bluetooth EDR.*/ + OC_ADAPTER_RFCOMM_BTEDR = (1 << 2), +#ifdef RA_ADAPTER + /**Remote Access over XMPP.*/ + OC_ADAPTER_REMOTE_ACCESS = (1 << 3), +#endif + /** CoAP over TCP.*/ + OC_ADAPTER_TCP = (1 << 4), + + /** NFC Transport for Messaging.*/ + OC_ADAPTER_NFC = (1 << 5) +} OCTransportAdapter; + +/** + * Enum layout assumes some targets have 16-bit integer (e.g., Arduino). + */ +typedef enum +{ + /** default flag is 0*/ + OC_DEFAULT_FLAGS = 0, + + /** Insecure transport is the default (subject to change).*/ + /** secure the transport path*/ + OC_FLAG_SECURE = (1 << 4), + + /** IPv4 & IPv6 auto-selection is the default.*/ + /** IP & TCP adapter only.*/ + OC_IP_USE_V6 = (1 << 5), + + /** IP & TCP adapter only.*/ + OC_IP_USE_V4 = (1 << 6), + + /** Multicast only.*/ + OC_MULTICAST = (1 << 7), + + /** Link-Local multicast is the default multicast scope for IPv6. + * These are placed here to correspond to the IPv6 multicast address bits.*/ + + /** IPv6 Interface-Local scope (loopback).*/ + OC_SCOPE_INTERFACE = 0x1, + + /** IPv6 Link-Local scope (default).*/ + OC_SCOPE_LINK = 0x2, + + /** IPv6 Realm-Local scope. */ + OC_SCOPE_REALM = 0x3, + + /** IPv6 Admin-Local scope. */ + OC_SCOPE_ADMIN = 0x4, + + /** IPv6 Site-Local scope. */ + OC_SCOPE_SITE = 0x5, + + /** IPv6 Organization-Local scope. */ + OC_SCOPE_ORG = 0x8, + + /**IPv6 Global scope. */ + OC_SCOPE_GLOBAL = 0xE, + +} OCTransportFlags; + +/** Bit mask for scope.*/ +#define OC_MASK_SCOPE (0x000F) + +/** Bit mask for Mods.*/ +#define OC_MASK_MODS (0x0FF0) +#define OC_MASK_FAMS (OC_IP_USE_V6|OC_IP_USE_V4) + +typedef struct OCStringLL +{ + struct OCStringLL *next; + char* value; +} OCStringLL; + +/** + * End point identity. + */ +typedef struct +{ + /** Identity Length */ + uint16_t id_length; + + /** Array of end point identity.*/ + unsigned char id[MAX_IDENTITY_SIZE]; +} OCIdentity; + +/** + * Universally unique identifier. + */ +typedef struct +{ + /** identitifier string.*/ + unsigned char id[UUID_IDENTITY_SIZE]; +} OCUUIdentity; + +/** + * Data structure to encapsulate IPv4/IPv6/Contiki/lwIP device addresses. + * OCDevAddr must be the same as CAEndpoint (in CACommon.h). + */ +typedef struct +{ + /** adapter type.*/ + OCTransportAdapter adapter; + + /** transport modifiers.*/ + OCTransportFlags flags; + + /** for IP.*/ + uint16_t port; + + /** address for all adapters.*/ + char addr[MAX_ADDR_STR_SIZE]; + + /** usually zero for default interface.*/ + uint32_t ifindex; +#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP) + char routeData[MAX_ADDR_STR_SIZE]; //destination GatewayID:ClientId +#endif +} OCDevAddr; + +/** + * This enum type includes elements of both ::OCTransportAdapter and ::OCTransportFlags. + * It is defined conditionally because the smaller definition limits expandability on 32/64 bit + * integer machines, and the larger definition won't fit into an enum on 16-bit integer machines + * like Arduino. + * + * This structure must directly correspond to ::OCTransportAdapter and ::OCTransportFlags. + */ +typedef enum +{ + /** use when defaults are ok. */ + CT_DEFAULT = 0, + + /** IPv4 and IPv6, including 6LoWPAN.*/ + CT_ADAPTER_IP = (1 << 16), + + /** GATT over Bluetooth LE.*/ + CT_ADAPTER_GATT_BTLE = (1 << 17), + + /** RFCOMM over Bluetooth EDR.*/ + CT_ADAPTER_RFCOMM_BTEDR = (1 << 18), + +#ifdef RA_ADAPTER + /** Remote Access over XMPP.*/ + CT_ADAPTER_REMOTE_ACCESS = (1 << 19), +#endif + /** CoAP over TCP.*/ + CT_ADAPTER_TCP = (1 << 20), + + /** NFC Transport.*/ + CT_ADAPTER_NFC = (1 << 21), + + /** Insecure transport is the default (subject to change).*/ + + /** secure the transport path.*/ + CT_FLAG_SECURE = (1 << 4), + + /** IPv4 & IPv6 autoselection is the default.*/ + + /** IP adapter only.*/ + CT_IP_USE_V6 = (1 << 5), + + /** IP adapter only.*/ + CT_IP_USE_V4 = (1 << 6), + + /** Link-Local multicast is the default multicast scope for IPv6. + * These are placed here to correspond to the IPv6 address bits.*/ + + /** IPv6 Interface-Local scope(loopback).*/ + CT_SCOPE_INTERFACE = 0x1, + + /** IPv6 Link-Local scope (default).*/ + CT_SCOPE_LINK = 0x2, + + /** IPv6 Realm-Local scope.*/ + CT_SCOPE_REALM = 0x3, + + /** IPv6 Admin-Local scope.*/ + CT_SCOPE_ADMIN = 0x4, + + /** IPv6 Site-Local scope.*/ + CT_SCOPE_SITE = 0x5, + + /** IPv6 Organization-Local scope.*/ + CT_SCOPE_ORG = 0x8, + + /** IPv6 Global scope.*/ + CT_SCOPE_GLOBAL = 0xE, +} OCConnectivityType; + +/** bit shift required for connectivity adapter.*/ +#define CT_ADAPTER_SHIFT 16 + +/** Mask Flag.*/ +#define CT_MASK_FLAGS 0xFFFF + +/** Mask Adapter.*/ +#define CT_MASK_ADAPTER 0xFFFF0000 + +/** + * OCDoResource methods to dispatch the request + */ +typedef enum +{ + OC_REST_NOMETHOD = 0, + + /** Read.*/ + OC_REST_GET = (1 << 0), + + /** Write.*/ + OC_REST_PUT = (1 << 1), + + /** Update.*/ + OC_REST_POST = (1 << 2), + + /** Delete.*/ + OC_REST_DELETE = (1 << 3), + + /** Register observe request for most up date notifications ONLY.*/ + OC_REST_OBSERVE = (1 << 4), + + /** Register observe request for all notifications, including stale notifications.*/ + OC_REST_OBSERVE_ALL = (1 << 5), + +#ifdef WITH_PRESENCE + /** Subscribe for all presence notifications of a particular resource.*/ + OC_REST_PRESENCE = (1 << 7), + +#endif + /** Allows OCDoResource caller to do discovery.*/ + OC_REST_DISCOVER = (1 << 8) +} OCMethod; + +/** + * Formats for payload encoding. + */ +typedef enum +{ + OC_FORMAT_CBOR, + OC_FORMAT_JSON, + OC_FORMAT_UNDEFINED, + OC_FORMAT_UNSUPPORTED, +} OCPayloadFormat; + +/** + * Host Mode of Operation. + */ +typedef enum +{ + OC_CLIENT = 0, + OC_SERVER, + OC_CLIENT_SERVER, + OC_GATEWAY /**< Client server mode along with routing capabilities.*/ +} OCMode; + +/** + * Quality of Service attempts to abstract the guarantees provided by the underlying transport + * protocol. The precise definitions of each quality of service level depend on the + * implementation. In descriptions below are for the current implementation and may changed + * over time. + */ +typedef enum +{ + /** Packet delivery is best effort.*/ + OC_LOW_QOS = 0, + + /** Packet delivery is best effort.*/ + OC_MEDIUM_QOS, + + /** Acknowledgments are used to confirm delivery.*/ + OC_HIGH_QOS, + + /** No Quality is defined, let the stack decide.*/ + OC_NA_QOS +} OCQualityOfService; + +/** + * Resource Properties. + * The value of a policy property is defined as bitmap. + * The LSB represents OC_DISCOVERABLE and Second LSB bit represents OC_OBSERVABLE and so on. + * Not including the policy property is equivalent to zero. + * + */ +typedef enum +{ + /** When none of the bits are set, the resource is non-discoverable & + * non-observable by the client.*/ + OC_RES_PROP_NONE = (0), + + /** When this bit is set, the resource is allowed to be discovered by clients.*/ + OC_DISCOVERABLE = (1 << 0), + + /** When this bit is set, the resource is allowed to be observed by clients.*/ + OC_OBSERVABLE = (1 << 1), + + /** When this bit is set, the resource is initialized, otherwise the resource + * is 'inactive'. 'inactive' signifies that the resource has been marked for + * deletion or is already deleted.*/ + OC_ACTIVE = (1 << 2), + + /** When this bit is set, the resource has been marked as 'slow'. + * 'slow' signifies that responses from this resource can expect delays in + * processing its requests from clients.*/ + OC_SLOW = (1 << 3), + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + /** When this bit is set, the resource is a secure resource.*/ + OC_SECURE = (1 << 4), +#else + OC_SECURE = (0), +#endif + + /** When this bit is set, the resource is allowed to be discovered only + * if discovery request contains an explicit querystring. + * Ex: GET /oic/res?rt=oic.sec.acl */ + OC_EXPLICIT_DISCOVERABLE = (1 << 5) + +#ifdef WITH_MQ + /** When this bit is set, the resource is allowed to be published */ + ,OC_MQ_PUBLISHER = (1 << 6) +#endif + +#ifdef MQ_BROKER + /** When this bit is set, the resource is allowed to be notified as MQ broker.*/ + ,OC_MQ_BROKER = (1 << 7) +#endif +} OCResourceProperty; + +/** + * Transport Protocol IDs. + */ +typedef enum +{ + /** For invalid ID.*/ + OC_INVALID_ID = (1 << 0), + + /* For coap ID.*/ + OC_COAP_ID = (1 << 1) +} OCTransportProtocolID; + +/** + * Declares Stack Results & Errors. + */ +typedef enum +{ + /** Success status code - START HERE.*/ + OC_STACK_OK = 0, + OC_STACK_RESOURCE_CREATED, + OC_STACK_RESOURCE_DELETED, + OC_STACK_CONTINUE, + OC_STACK_RESOURCE_CHANGED, + /** Success status code - END HERE.*/ + + /** Error status code - START HERE.*/ + OC_STACK_INVALID_URI = 20, + OC_STACK_INVALID_QUERY, + OC_STACK_INVALID_IP, + OC_STACK_INVALID_PORT, + OC_STACK_INVALID_CALLBACK, + OC_STACK_INVALID_METHOD, + + /** Invalid parameter.*/ + OC_STACK_INVALID_PARAM, + OC_STACK_INVALID_OBSERVE_PARAM, + OC_STACK_NO_MEMORY, + OC_STACK_COMM_ERROR, + OC_STACK_TIMEOUT, + OC_STACK_ADAPTER_NOT_ENABLED, + OC_STACK_NOTIMPL, + + /** Resource not found.*/ + OC_STACK_NO_RESOURCE, + + /** e.g: not supported method or interface.*/ + OC_STACK_RESOURCE_ERROR, + OC_STACK_SLOW_RESOURCE, + OC_STACK_DUPLICATE_REQUEST, + + /** Resource has no registered observers.*/ + OC_STACK_NO_OBSERVERS, + OC_STACK_OBSERVER_NOT_FOUND, + OC_STACK_VIRTUAL_DO_NOT_HANDLE, + OC_STACK_INVALID_OPTION, + + /** The remote reply contained malformed data.*/ + OC_STACK_MALFORMED_RESPONSE, + OC_STACK_PERSISTENT_BUFFER_REQUIRED, + OC_STACK_INVALID_REQUEST_HANDLE, + OC_STACK_INVALID_DEVICE_INFO, + OC_STACK_INVALID_JSON, + + /** Request is not authorized by Resource Server. */ + OC_STACK_UNAUTHORIZED_REQ, + OC_STACK_TOO_LARGE_REQ, + + /** Error code from PDM */ + OC_STACK_PDM_IS_NOT_INITIALIZED, + OC_STACK_DUPLICATE_UUID, + OC_STACK_INCONSISTENT_DB, + + /** + * Error code from OTM + * This error is pushed from DTLS interface when handshake failure happens + */ + OC_STACK_AUTHENTICATION_FAILURE, + OC_STACK_NOT_ALLOWED_OXM, + + /** Insert all new error codes here!.*/ +#ifdef WITH_PRESENCE + OC_STACK_PRESENCE_STOPPED = 128, + OC_STACK_PRESENCE_TIMEOUT, + OC_STACK_PRESENCE_DO_NOT_HANDLE, +#endif + + /** ERROR code from server */ + OC_STACK_FORBIDDEN_REQ, /** 403*/ + OC_STACK_INTERNAL_SERVER_ERROR, /** 500*/ + + /** ERROR in stack.*/ + OC_STACK_ERROR = 255 + /** Error status code - END HERE.*/ +} OCStackResult; + +/** + * Handle to an OCDoResource invocation. + */ +typedef void * OCDoHandle; + +/** + * Handle to an OCResource object owned by the OCStack. + */ +typedef void * OCResourceHandle; + +/** + * Handle to an OCRequest object owned by the OCStack. + */ +typedef uint32_t OCRequestHandle; + +/** + * Unique identifier for each observation request. Used when observations are + * registered or de-registered. Used by entity handler to signal specific + * observers to be notified of resource changes. + * There can be maximum of 256 observations per server. + */ +typedef uint8_t OCObservationId; + +/** + * Sequence number is a 24 bit field, + * per https://tools.ietf.org/html/rfc7641. + */ +#define MAX_SEQUENCE_NUMBER (0xFFFFFF) + +/** + * Action associated with observation. + */ +typedef enum +{ + /** To Register. */ + OC_OBSERVE_REGISTER = 0, + + /** To Deregister. */ + OC_OBSERVE_DEREGISTER = 1, + + /** Others. */ + OC_OBSERVE_NO_OPTION = 2, + +} OCObserveAction; + + +/** + * Persistent storage handlers. An APP must provide OCPersistentStorage handler pointers + * when it calls OCRegisterPersistentStorageHandler. + * Persistent storage open handler points to default file path. + * It should check file path and whether the file is symbolic link or no. + * Application can point to appropriate SVR database path for it's IoTivity Server. + */ +typedef struct { + /** Persistent storage file path.*/ + FILE* (* open)(const char *path, const char *mode); + + /** Persistent storage read handler.*/ + size_t (* read)(void *ptr, size_t size, size_t nmemb, FILE *stream); + + /** Persistent storage write handler.*/ + size_t (* write)(const void *ptr, size_t size, size_t nmemb, FILE *stream); + + /** Persistent storage close handler.*/ + int (* close)(FILE *fp); + + /** Persistent storage unlink handler.*/ + int (* unlink)(const char *path); +} OCPersistentStorage; + +/** + * Possible returned values from entity handler. + */ +typedef struct +{ + /** Action associated with observation request.*/ + OCObserveAction action; + + /** Identifier for observation being registered/deregistered.*/ + OCObservationId obsId; +} OCObservationInfo; + +/** + * Possible returned values from entity handler. + */ +typedef enum +{ + OC_EH_OK = 0, + OC_EH_ERROR, + OC_EH_SLOW, + OC_EH_RESOURCE_CREATED = 201, + OC_EH_RESOURCE_DELETED = 202, + OC_EH_VALID = 203, + OC_EH_CHANGED = 204, + OC_EH_CONTENT = 205, + OC_EH_BAD_REQ = 400, + OC_EH_UNAUTHORIZED_REQ = 401, + OC_EH_BAD_OPT = 402, + OC_EH_FORBIDDEN = 403, + OC_EH_RESOURCE_NOT_FOUND = 404, + OC_EH_METHOD_NOT_ALLOWED = 405, + OC_EH_NOT_ACCEPTABLE = 406, + OC_EH_TOO_LARGE = 413, + OC_EH_UNSUPPORTED_MEDIA_TYPE = 415, + OC_EH_INTERNAL_SERVER_ERROR = 500, + OC_EH_BAD_GATEWAY = 502, + OC_EH_SERVICE_UNAVAILABLE = 503, + OC_EH_RETRANSMIT_TIMEOUT = 504 +} OCEntityHandlerResult; + +/** + * This structure will be used to define the vendor specific header options to be included + * in communication packets. + */ +typedef struct OCHeaderOption +{ + /** The protocol ID this option applies to.*/ + OCTransportProtocolID protocolID; + + /** The header option ID which will be added to communication packets.*/ + uint16_t optionID; + + /** its length 191.*/ + uint16_t optionLength; + + /** pointer to its data.*/ + uint8_t optionData[MAX_HEADER_OPTION_DATA_LENGTH]; + +#ifdef SUPPORTS_DEFAULT_CTOR + OCHeaderOption() = default; + OCHeaderOption(OCTransportProtocolID pid, + uint16_t optId, + uint16_t optlen, + const uint8_t* optData) + : protocolID(pid), + optionID(optId), + optionLength(optlen) + { + + // parameter includes the null terminator. + optionLength = optionLength < MAX_HEADER_OPTION_DATA_LENGTH ? + optionLength : MAX_HEADER_OPTION_DATA_LENGTH; + memcpy(optionData, optData, optionLength); + optionData[optionLength - 1] = '\0'; + } +#endif +} OCHeaderOption; + +/** + * This structure describes the platform properties. All non-Null properties will be + * included in a platform discovery request. + * @deprecated: Use OCSetPropertyValue to set platform value. + */ +typedef struct +{ + /** Platform ID.*/ + char *platformID; + + /** Manufacturer name.*/ + char *manufacturerName; + + /** Manufacturer URL for platform property.*/ + char *manufacturerUrl; + + /** Model number.*/ + char *modelNumber; + + /** Manufacturer date.*/ + char *dateOfManufacture; + + /** Platform version.*/ + char *platformVersion; + + /** Operating system version.*/ + char *operatingSystemVersion; + + /** HW version.*/ + char *hardwareVersion; + + /** FW version.*/ + char *firmwareVersion; + + /** Platform support URL.*/ + char *supportUrl; + + /** System time.*/ + char *systemTime; + +} OCPlatformInfo; + +/** + * This structure is expected as input for device properties. + * device name is mandatory and expected from the application. + * device id of type UUID will be generated by the stack. + * @deprecated: Use OCSetPropertyValue to set device value. + */ +typedef struct +{ + /** Pointer to the device name.*/ + char *deviceName; + /** Pointer to the types.*/ + OCStringLL *types; + /** Pointer to the device specification version.*/ + char *specVersion; + /** Pointer to the device data model versions (in CSV format).*/ + OCStringLL *dataModelVersions; +} OCDeviceInfo; + +#ifdef RA_ADAPTER +/** + * callback for bound JID + */ +typedef void (*jid_bound_cb)(char *jid); + +/** + * CA Remote Access information for XMPP Client + * + */ +typedef struct +{ + char *hostname; /**< XMPP server hostname */ + uint16_t port; /**< XMPP server serivce port */ + char *xmpp_domain; /**< XMPP login domain */ + char *username; /**< login username */ + char *password; /**< login password */ + char *resource; /**< specific resource for login */ + char *user_jid; /**< specific JID for login */ + jid_bound_cb jidbound; /**< callback when JID bound */ +} OCRAInfo_t; +#endif /* RA_ADAPTER */ + + +/** Enum to describe the type of object held by the OCPayload object.*/ +typedef enum +{ + /** Contents of the payload are invalid */ + PAYLOAD_TYPE_INVALID, + /** The payload is an OCDiscoveryPayload */ + PAYLOAD_TYPE_DISCOVERY, + /** The payload of the device */ + PAYLOAD_TYPE_DEVICE, + /** The payload type of the platform */ + PAYLOAD_TYPE_PLATFORM, + /** The payload is an OCRepPayload */ + PAYLOAD_TYPE_REPRESENTATION, + /** The payload is an OCSecurityPayload */ + PAYLOAD_TYPE_SECURITY, + /** The payload is an OCPresencePayload */ + PAYLOAD_TYPE_PRESENCE +} OCPayloadType; + +/** + * A generic struct representing a payload returned from a resource operation + * + * A pointer to OCPayLoad can be cast to a more specific struct to access members + * for the its type. + */ +typedef struct +{ + /** The type of message that was received */ + OCPayloadType type; +} OCPayload; + +typedef enum +{ + OCREP_PROP_NULL, + OCREP_PROP_INT, + OCREP_PROP_DOUBLE, + OCREP_PROP_BOOL, + OCREP_PROP_STRING, + OCREP_PROP_BYTE_STRING, + OCREP_PROP_OBJECT, + OCREP_PROP_ARRAY +}OCRepPayloadPropType; + +/** This structure will be used to represent a binary string for CBOR payloads.*/ +typedef struct +{ + /** pointer to data bytes.*/ + uint8_t* bytes; + + /** number of data bytes.*/ + size_t len; +} OCByteString; + +#define MAX_REP_ARRAY_DEPTH 3 +typedef struct +{ + OCRepPayloadPropType type; + size_t dimensions[MAX_REP_ARRAY_DEPTH]; + + union + { + int64_t* iArray; + double* dArray; + bool* bArray; + char** strArray; + + /** pointer to ByteString array.*/ + OCByteString* ocByteStrArray; + + struct OCRepPayload** objArray; + }; +} OCRepPayloadValueArray; + +typedef struct OCRepPayloadValue +{ + char* name; + OCRepPayloadPropType type; + union + { + int64_t i; + double d; + bool b; + char* str; + + /** ByteString object.*/ + OCByteString ocByteStr; + + struct OCRepPayload* obj; + OCRepPayloadValueArray arr; + }; + struct OCRepPayloadValue* next; + +} OCRepPayloadValue; + +// used for get/set/put/observe/etc representations +typedef struct OCRepPayload +{ + OCPayload base; + char* uri; + OCStringLL* types; + OCStringLL* interfaces; + OCRepPayloadValue* values; + struct OCRepPayload* next; +} OCRepPayload; + +// used inside a discovery payload +typedef struct OCResourcePayload +{ + char* uri; + OCStringLL* types; + OCStringLL* interfaces; + uint8_t bitmap; + bool secure; + uint16_t port; +#ifdef TCP_ADAPTER + uint16_t tcpPort; +#endif + struct OCResourcePayload* next; +} OCResourcePayload; + +typedef struct OCDiscoveryPayload +{ + OCPayload base; + + /** Device Id */ + char *sid; + + /** A special case for handling RD address. */ + char* baseURI; + + /** Name */ + char *name; + + /** HREF */ + char *uri; + + /** Resource Type */ + OCStringLL *type; + + /** Interface */ + OCStringLL *iface; + + /** This structure holds the old /oic/res response. */ + OCResourcePayload *resources; + + /** Holding address of the next DiscoveryPayload. */ + struct OCDiscoveryPayload *next; + +} OCDiscoveryPayload; + +typedef struct +{ + OCPayload base; + uint8_t* securityData; + size_t payloadSize; +} OCSecurityPayload; + +#ifdef WITH_PRESENCE +typedef struct +{ + OCPayload base; + uint32_t sequenceNumber; + uint32_t maxAge; + OCPresenceTrigger trigger; + char* resourceType; +} OCPresencePayload; +#endif + +/** + * Incoming requests handled by the server. Requests are passed in as a parameter to the + * OCEntityHandler callback API. + * The OCEntityHandler callback API must be implemented in the application in order + * to receive these requests. + */ +typedef struct +{ + /** Associated resource.*/ + OCResourceHandle resource; + + /** Associated request handle.*/ + OCRequestHandle requestHandle; + + /** the REST method retrieved from received request PDU.*/ + OCMethod method; + + /** description of endpoint that sent the request.*/ + OCDevAddr devAddr; + + /** resource query send by client.*/ + char * query; + + /** Information associated with observation - valid only when OCEntityHandler flag includes + * ::OC_OBSERVE_FLAG.*/ + OCObservationInfo obsInfo; + + /** Number of the received vendor specific header options.*/ + uint8_t numRcvdVendorSpecificHeaderOptions; + + /** Pointer to the array of the received vendor specific header options.*/ + OCHeaderOption * rcvdVendorSpecificHeaderOptions; + + /** Message id.*/ + uint16_t messageID; + + /** the payload from the request PDU.*/ + OCPayload *payload; + +} OCEntityHandlerRequest; + + +/** + * Response from queries to remote servers. Queries are made by calling the OCDoResource API. + */ +typedef struct +{ + /** Address of remote server.*/ + OCDevAddr devAddr; + + /** backward compatibility (points to devAddr).*/ + OCDevAddr *addr; + + /** backward compatibility.*/ + OCConnectivityType connType; + + /** the security identity of the remote server.*/ + OCIdentity identity; + + /** the is the result of our stack, OCStackResult should contain coap/other error codes.*/ + OCStackResult result; + + /** If associated with observe, this will represent the sequence of notifications from server.*/ + uint32_t sequenceNumber; + + /** resourceURI.*/ + const char * resourceUri; + + /** the payload for the response PDU.*/ + OCPayload *payload; + + /** Number of the received vendor specific header options.*/ + uint8_t numRcvdVendorSpecificHeaderOptions; + + /** An array of the received vendor specific header options.*/ + OCHeaderOption rcvdVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS]; +} OCClientResponse; + +/** + * Request handle is passed to server via the entity handler for each incoming request. + * Stack assigns when request is received, server sets to indicate what request response is for. + */ +typedef struct +{ + /** Request handle.*/ + OCRequestHandle requestHandle; + + /** Resource handle.*/ + OCResourceHandle resourceHandle; + + /** Allow the entity handler to pass a result with the response.*/ + OCEntityHandlerResult ehResult; + + /** This is the pointer to server payload data to be transferred.*/ + OCPayload* payload; + + /** number of the vendor specific header options .*/ + uint8_t numSendVendorSpecificHeaderOptions; + + /** An array of the vendor specific header options the entity handler wishes to use in response.*/ + OCHeaderOption sendVendorSpecificHeaderOptions[MAX_HEADER_OPTIONS]; + + /** URI of new resource that entity handler might create.*/ + char resourceUri[MAX_URI_LENGTH]; + + /** Server sets to true for persistent response buffer,false for non-persistent response buffer*/ + uint8_t persistentBufferFlag; +} OCEntityHandlerResponse; + +/** + * Entity's state + */ +typedef enum +{ + /** Request state.*/ + OC_REQUEST_FLAG = (1 << 1), + /** Observe state.*/ + OC_OBSERVE_FLAG = (1 << 2) +} OCEntityHandlerFlag; + +/** + * Possible return values from client application callback + * + * A client application callback returns an OCStackApplicationResult to indicate whether + * the stack should continue to keep the callback registered. + */ +typedef enum +{ + /** Make no more calls to the callback and call the OCClientContextDeleter for this callback */ + OC_STACK_DELETE_TRANSACTION = 0, + /** Keep this callback registered and call it if an apropriate event occurs */ + OC_STACK_KEEP_TRANSACTION +} OCStackApplicationResult; + + +//#ifdef DIRECT_PAIRING +/** + * @brief direct pairing Method Type. + * 0: not allowed + * 1: pre-configured pin + * 2: random pin + */ +typedef enum OCPrm +{ + DP_NOT_ALLOWED = 0x0, + DP_PRE_CONFIGURED = (0x1 << 0), + DP_RANDOM_PIN = (0x1 << 1), +} OCPrm_t; + +/** + * Device Information of discoverd direct pairing device(s). + */ +typedef struct OCDPDev +{ + OCDevAddr endpoint; + OCConnectivityType connType; + uint16_t securePort; + bool edp; + OCPrm_t *prm; + size_t prmLen; + OCUUIdentity deviceID; + OCUUIdentity rowner; + struct OCDPDev *next; +} OCDPDev_t; +//#endif // DIRECT_PAIRING + +/* + * ------------------------------------------------------------------------------------------- + * Callback function definitions + * ------------------------------------------------------------------------------------------- + */ + +/** + * Client applications implement this callback to consume responses received from Servers. + */ +typedef OCStackApplicationResult (* OCClientResponseHandler)(void *context, OCDoHandle handle, + OCClientResponse * clientResponse); + +/** + * Client applications using a context pointer implement this callback to delete the + * context upon removal of the callback/context pointer from the internal callback-list. + */ +typedef void (* OCClientContextDeleter)(void *context); + +/** + * This info is passed from application to OC Stack when initiating a request to Server. + */ +typedef struct OCCallbackData +{ + /** Pointer to the context.*/ + void *context; + + /** The pointer to a function the stack will call to handle the requests.*/ + OCClientResponseHandler cb; + + /** A pointer to a function to delete the context when this callback is removed.*/ + OCClientContextDeleter cd; + +#ifdef SUPPORTS_DEFAULT_CTOR + OCCallbackData() = default; + OCCallbackData(void* ctx, OCClientResponseHandler callback, OCClientContextDeleter deleter) + :context(ctx), cb(callback), cd(deleter){} +#endif +} OCCallbackData; + +/** + * Application server implementations must implement this callback to consume requests OTA. + * Entity handler callback needs to fill the resPayload of the entityHandlerRequest. + * + * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT, + * OC_EH_SLOW and etc in entity handler callback, + * ocstack will be not send response automatically to client + * except for error return value like OC_EH_ERROR. + * + * If you want to send response to client with specific result, + * OCDoResponse API should be called with the result value. + * + * e.g) + * + * OCEntityHandlerResponse response; + * + * .. + * + * response.ehResult = OC_EH_CHANGED; + * + * .. + * + * OCDoResponse(&response) + * + * .. + * + * return OC_EH_OK; + */ +typedef OCEntityHandlerResult (*OCEntityHandler) +(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest, void* callbackParam); + +/** + * Device Entity handler need to use this call back instead of OCEntityHandler. + * + * When you set specific return value like OC_EH_CHANGED, OC_EH_CONTENT, + * OC_EH_SLOW and etc in entity handler callback, + * ocstack will be not send response automatically to client + * except for error return value like OC_EH_ERROR. + * + * If you want to send response to client with specific result, + * OCDoResponse API should be called with the result value. + * + * e.g) + * + * OCEntityHandlerResponse response; + * + * .. + * + * response.ehResult = OC_EH_CHANGED; + * + * .. + * + * OCDoResponse(&response) + * + * .. + * + * return OC_EH_OK; + */ +typedef OCEntityHandlerResult (*OCDeviceEntityHandler) +(OCEntityHandlerFlag flag, OCEntityHandlerRequest * entityHandlerRequest, char* uri, void* callbackParam); + +//#ifdef DIRECT_PAIRING +/** + * Callback function definition of direct-pairing + * + * @param[OUT] ctx - user context returned in the callback. + * @param[OUT] peer - pairing device info. + * @param[OUT] result - It's returned with 'OC_STACK_XXX'. It will return 'OC_STACK_OK' + * if D2D pairing is success without error + */ +typedef void (*OCDirectPairingCB)(void *ctx, OCDPDev_t *peer, OCStackResult result); +//#endif // DIRECT_PAIRING + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +/** + * Callback function definition for Change in TrustCertChain + * + * @param[IN] ctx - user context returned in the callback. + * @param[IN] credId - trustCertChain changed for this ID + * @param[IN] trustCertChain - trustcertchain binary blob. + * @param[IN] chainSize - size of trustchain + */ +typedef void (*TrustCertChainChangeCB)(void *ctx, uint16_t credId, uint8_t *trustCertChain, + size_t chainSize); + +/** + * certChain context structure. + */ +typedef struct trustCertChainContext +{ + TrustCertChainChangeCB callback; + void *context; +} trustCertChainContext_t; +#endif + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif /* OCTYPES_H_ */ diff --git a/inc/iotivity/platform_features.h b/inc/iotivity/platform_features.h new file mode 100644 index 0000000..3af42cd --- /dev/null +++ b/inc/iotivity/platform_features.h @@ -0,0 +1,90 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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 + * + * This file contains compiler and platform feature definitions. These + * can be used to enable functionality on only platforms that support + * said functionality. + */ + +#ifndef PLATFORM_FEATURES_H_ +#define PLATFORM_FEATURES_H_ + + +#if (__cplusplus >=201103L) || defined(__GXX_EXPERIMENTAL_CXX0X__) +# define SUPPORTS_DEFAULT_CTOR +#endif + +#if (__STDC_VERSION__ >= 201112L) +# include <assert.h> +# define OC_STATIC_ASSERT(condition, msg) static_assert(condition, msg) +#elif defined(_WIN32) +# if defined(__msys_nt__) && !defined(__cplusplus) +# define static_assert _Static_assert +# endif +# define OC_STATIC_ASSERT(condition, msg) static_assert(condition, msg) +#else +# define OC_STATIC_ASSERT(condition, msg) ((void)sizeof(char[2*!!(condition) - 1])) +#endif + +#ifndef INLINE_API +# if defined(__cplusplus) +# define INLINE_API inline +# else +# ifdef _MSC_VER +# define INLINE_API static __inline +# else +# define INLINE_API static inline +# endif +# endif +#endif + +#ifdef _MSC_VER +# define OC_ANNOTATE_UNUSED +#else +# define OC_ANNOTATE_UNUSED __attribute__((unused)) +#endif + +#ifdef _WIN32 +# define __func__ __FUNCTION__ +# define strncasecmp _strnicmp +# define strtok_r strtok_s +# if _MSC_VER && (_MSC_VER < 1900) +# include "windows/include/vs12_snprintf.h" +# endif +# define ssize_t SSIZE_T +# define F_OK 0 +# define sleep(SECS) Sleep(1000*(SECS)) +# ifdef __cplusplus +# define SUPPORTS_DEFAULT_CTOR +# endif +# include "windows/include/win_sleep.h" +# include "windows/include/pthread_create.h" +#endif + +#ifdef HAVE_WINSOCK2_H +# define OPTVAL_T(t) (const char*)(t) +#else +# define OPTVAL_T(t) (t) +#endif + +#endif diff --git a/inc/iotivity/targets/oc_console_logger.h b/inc/iotivity/targets/oc_console_logger.h new file mode 100644 index 0000000..b8b738f --- /dev/null +++ b/inc/iotivity/targets/oc_console_logger.h @@ -0,0 +1,43 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_CONSOLE_LOGGER_H_ +#define OC_CONSOLE_LOGGER_H_ + +#include "oc_logger_types.h" + +#ifdef __cplusplus + extern "C" { +#endif + +oc_log_ctx_t *oc_make_console_logger(); + +int oc_console_logger_init(oc_log_ctx_t *ctx, void *world); +void oc_console_logger_destroy(oc_log_ctx_t *ctx); +void oc_console_logger_flush(oc_log_ctx_t *ctx); +void oc_console_logger_set_level(oc_log_ctx_t *ctx, const int level); +size_t oc_console_logger_write(oc_log_ctx_t *ctx, const int level, const char *msg); +int oc_console_logger_set_module(oc_log_ctx_t *ctx, const char *module_name); + +#ifdef __cplusplus + } // extern "C" +#endif + +#endif diff --git a/inc/iotivity/targets/oc_ostream_logger.h b/inc/iotivity/targets/oc_ostream_logger.h new file mode 100644 index 0000000..2fa7930 --- /dev/null +++ b/inc/iotivity/targets/oc_ostream_logger.h @@ -0,0 +1,49 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#ifndef OC_OSTREAM_LOGGER_H_ +#define OC_OSTREAM_LOGGER_H_ + +#include "oc_logger_types.h" + +/* Example of a C-callable C++ logger: */ +#ifdef __cplusplus + extern "C" { +#endif + +oc_log_ctx_t *oc_make_ostream_logger(); + +int oc_ostream_log_init(oc_log_ctx_t *ctx, void *world); +void oc_ostream_log_destroy(oc_log_ctx_t *ctx); +void oc_ostream_log_flush(oc_log_ctx_t *ctx); +void oc_ostream_log_set_level(oc_log_ctx_t *ctx, const int level); +size_t oc_ostream_log_write(oc_log_ctx_t *ctx, const int level, const char *msg); +int oc_ostream_log_set_module(oc_log_ctx_t *ctx, const char *module_name); + +int oc_ostream_log_lock(oc_log_ctx_t *ctx); +int oc_ostream_log_unlock(oc_log_ctx_t *ctx); +int oc_ostream_log_try_lock(oc_log_ctx_t *ctx); // non-blocking +int oc_ostream_log_locked_destroy(oc_log_ctx_t *ctx); + +#ifdef __cplusplus + } // extern "C" +#endif + +#endif diff --git a/inc/ua_client.h b/inc/ua_client.h new file mode 100644 index 0000000..9e25ae9 --- /dev/null +++ b/inc/ua_client.h @@ -0,0 +1,46 @@ +#ifndef __UA_CLIENT_H__ +#define __UA_CLIENT_H__ + +#include <stdio.h> +#include <dlog.h> + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "UA_CLIENT" + +#define UA_LOG(fmt, ...) { \ + dlog_print(DLOG_DEBUG, LOG_TAG, "[%s: %s(): %d] " fmt "", rindex(__FILE__, '/')+1, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ +} + +#define UA_LOG_ONLY(fmt, ...) { \ + dlog_print(DLOG_DEBUG, LOG_TAG, fmt, ##__VA_ARGS__); \ +} + +typedef struct { + char *manufacturer; + char *model_name; + char *firmware_ver; + char * firmware_update_state; + char *uuid; // for test + char *access_token; // for test +} ua_device_info_s; + +typedef enum { + UA_HTTP_GET = 0, + UA_HTTP_POST, + UA_HTTP_PUT, + UA_HTTP_DELETE +}rest_req_type; + + +/* ua_http.cpp */ +int ua_http_download_file(const char *download_url); +int ua_http_send_request(rest_req_type type, char *req_url, char **res_header, char **res_body); + +/* ua_json_parser.cpp */ +void ua_json_parser_firmware_info(const char *data, char **old_ver, char **new_ver, \ + char **download_url, char **priority); + + +#endif /* __UA_CLIENT_H__ */ diff --git a/lib/libc_common.a b/lib/libc_common.a Binary files differnew file mode 100755 index 0000000..d49c9ac --- /dev/null +++ b/lib/libc_common.a diff --git a/lib/libcoap.a b/lib/libcoap.a Binary files differnew file mode 100755 index 0000000..f385efd --- /dev/null +++ b/lib/libcoap.a diff --git a/lib/libconnectivity_abstraction.a b/lib/libconnectivity_abstraction.a Binary files differnew file mode 100755 index 0000000..9c9dcab --- /dev/null +++ b/lib/libconnectivity_abstraction.a diff --git a/lib/liblogger.a b/lib/liblogger.a Binary files differnew file mode 100755 index 0000000..8baa4e8 --- /dev/null +++ b/lib/liblogger.a diff --git a/lib/liboc.a b/lib/liboc.a Binary files differnew file mode 100755 index 0000000..cc1de40 --- /dev/null +++ b/lib/liboc.a diff --git a/lib/liboc_logger.a b/lib/liboc_logger.a Binary files differnew file mode 100755 index 0000000..75616d0 --- /dev/null +++ b/lib/liboc_logger.a diff --git a/lib/libocsrm.a b/lib/libocsrm.a Binary files differnew file mode 100755 index 0000000..1b4115f --- /dev/null +++ b/lib/libocsrm.a diff --git a/lib/liboctbstack.a b/lib/liboctbstack.a Binary files differnew file mode 100755 index 0000000..da57b88 --- /dev/null +++ b/lib/liboctbstack.a diff --git a/lib/libresource_directory.a b/lib/libresource_directory.a Binary files differnew file mode 100755 index 0000000..f50d276 --- /dev/null +++ b/lib/libresource_directory.a diff --git a/lib/libroutingmanager.a b/lib/libroutingmanager.a Binary files differnew file mode 100755 index 0000000..abb6448 --- /dev/null +++ b/lib/libroutingmanager.a diff --git a/packaging/ua-client.service b/packaging/ua-client.service new file mode 100644 index 0000000..5d6ce71 --- /dev/null +++ b/packaging/ua-client.service @@ -0,0 +1,10 @@ +[Unit] +Description=Firmware Upgrade Agent Client +After=lazy_mount.service systemd-logind.service + +[Service] +Type=simple +ExecStart=/usr/bin/ua-client + +[Install] +WantedBy=multi-user.target diff --git a/packaging/ua-client.spec b/packaging/ua-client.spec new file mode 100755 index 0000000..8b21a10 --- /dev/null +++ b/packaging/ua-client.spec @@ -0,0 +1,63 @@ +Name: ua-client +Version: 0.0.1 +Release: 1 +License: Apache-2.0 +Summary: Upgrade agent client +Group: System/Service +Source0: %{name}-%{version}.tar.gz +Source1: ua-client.service + +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +Requires(post): systemd +Requires(postun): systemd +BuildRequires: cmake +BuildRequires: pkgconfig(boost) +BuildRequires: pkgconfig(capi-network-connection) +BuildRequires: pkgconfig(capi-network-wifi) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(glib-2.0) +#BuildRequires: pkgconfig(iotivity) +BuildRequires: pkgconfig(json-glib-1.0) +BuildRequires: pkgconfig(libcurl) +#BuildRequires: pkgconfig(libssl) +BuildRequires: pkgconfig(uuid) + +%description +Description: Firmware Upgrade agent client using OCF + +%prep +%setup -q + +%build +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + +make %{?jobs:-j%jobs} + +%install +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +install -m 0644 %SOURCE1 %{buildroot}%{_unitdir}/ua-client.service +%install_service multi-user.target.wants ua-client.service + +%make_install + +%clean + +%post +/sbin/ldconfig +mkdir -p -m 770 /opt/usr/data/ua_client/ +chmod 766 /opt/usr/data/ua_client/device_info.ini +chsmack -a "_" /opt/usr/data/ua_client/device_info.ini +chmod 766 /opt/usr/data/ua_client/.firmware_controlee.dat +chsmack -a "_" /opt/usr/data/ua_client/.firmware_controlee.dat + +%postun -p /sbin/ldconfig +rm /opt/usr/data/ua_client/device_info.ini +rm /opt/usr/data/ua_client/.firmware_controlee.dat + +%files +%{_bindir}/ua-client +%{_unitdir}/ua-client.service +%{_unitdir}/multi-user.target.wants/ua-client.service +%config(noreplace) /opt/usr/data/ua_client/device_info.ini +%config(noreplace) /opt/usr/data/ua_client/.firmware_controlee.dat diff --git a/ref_rpms/iotivity-sec_3.0/iotivity-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity-sec_3.0/iotivity-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..47b626f --- /dev/null +++ b/ref_rpms/iotivity-sec_3.0/iotivity-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity-sec_3.0/iotivity-devel-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity-sec_3.0/iotivity-devel-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..83121ec --- /dev/null +++ b/ref_rpms/iotivity-sec_3.0/iotivity-devel-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity-sec_3.0/iotivity-service-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity-sec_3.0/iotivity-service-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..e85e0a8 --- /dev/null +++ b/ref_rpms/iotivity-sec_3.0/iotivity-service-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity-sec_3.0/iotivity-test-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity-sec_3.0/iotivity-test-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..61bc9b7 --- /dev/null +++ b/ref_rpms/iotivity-sec_3.0/iotivity-test-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..66d2797 --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-debuginfo-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-debuginfo-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..a17579a --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-debuginfo-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-debugsource-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-debugsource-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..945e8f6 --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-debugsource-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-devel-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-devel-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..8e25ad0 --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-devel-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-service-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-service-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..13a2da4 --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-service-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-service-debuginfo-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-service-debuginfo-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..ee0b4f8 --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-service-debuginfo-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-test-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-test-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..6bac8f5 --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-test-1.2.1-0.armv7l.rpm diff --git a/ref_rpms/iotivity_unified/iotivity-test-debuginfo-1.2.1-0.armv7l.rpm b/ref_rpms/iotivity_unified/iotivity-test-debuginfo-1.2.1-0.armv7l.rpm Binary files differnew file mode 100644 index 0000000..12fcf88 --- /dev/null +++ b/ref_rpms/iotivity_unified/iotivity-test-debuginfo-1.2.1-0.armv7l.rpm diff --git a/res/.firmware_controlee.dat b/res/.firmware_controlee.dat Binary files differnew file mode 100755 index 0000000..24f2c73 --- /dev/null +++ b/res/.firmware_controlee.dat diff --git a/res/device_info.ini b/res/device_info.ini new file mode 100755 index 0000000..18e3d88 --- /dev/null +++ b/res/device_info.ini @@ -0,0 +1,7 @@ +[device_info] +manufacturer=samsung +model_name=tm1 +firmware_ver=1.0 +firmware_update_state=0 +uuid= +access_token= diff --git a/src/ua_client.cpp b/src/ua_client.cpp new file mode 100755 index 0000000..a733b93 --- /dev/null +++ b/src/ua_client.cpp @@ -0,0 +1,1019 @@ +#include <memory> +#include <iostream> +#include <stdexcept> +#include <condition_variable> +#include <map> +#include <vector> +#include <string> +#include <unistd.h> +#include <mutex> +#include <glib.h> +#include <signal.h> +#include <pthread.h> +#include <gio/gio.h> + +#include "ocstack.h" +#include "ocpayload.h" +#include "RDClient.h" +#include "logger.h" + +#include "OCApi.h" +#include "OCPlatform.h" + +#include <wifi.h> + + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +#include "ocprovisioningmanager.h" +#include "mbedtls/ssl_ciphersuites.h" +#include "byte_array.h" +#include <ca_adapter_net_ssl.h> +#endif // WITH_DTLS__ or __WITH_TLS__ + +#include "ua_client.h" + +#define OC_SECURITY_DB_DAT_FILE_NAME "oic_svr_db.dat" +#define OC_RSRVD_PROTOCOL_INDEPENDENT_ID "piid" +#define OC_CONTROLEE_DATA_FILE_PATH "/opt/usr/data/ua_client/" +#define OC_CONTROLEE_DB_DAT_FILE_NAME ".firmware_controlee.dat" + +#define UA_OCF_SERVER_URL "13.124.29.169:5683" +#define UA_CONTENTS_SERVER_URL "http://13.124.95.191:8000" + +using namespace OC; +using namespace std; + +static GMainLoop* mainloop = NULL; + +string g_host; + +condition_variable g_callbackLock; +string g_uid; +string g_accesstoken; + +static void _set_device_info(const char *key, const char *value); +static void _get_device_info(ua_device_info_s *device); +static void _exec_update(); + +class Resource +{ + public: + OCResourceHandle m_handle; + Resource(string uri, vector<string> rt, vector<string> itf) + { + m_representation.setUri(uri); + m_representation.setResourceTypes(rt); + m_representation.setResourceInterfaces(itf); + } + + string getResourceUri() + { + return m_representation.getUri(); + } + + vector<string> getResourceType() + { + return m_representation.getResourceTypes(); + } + + vector<string> getInterfaces() + { + return m_representation.getResourceInterfaces(); + } + + OCRepresentation getRepresentation(void) + { + m_representation.clearChildren(); + for (auto it = m_childResources.begin(); it != m_childResources.end(); it++) + { + m_representation.addChild((*it)->getRepresentation()); + } + return m_representation; + } + + OCStackResult addChildResource(Resource *childResource) + { + m_childResources.push_back(childResource); + return OCPlatform::bindResource(m_handle, childResource->m_handle); + } + + OCStackResult sendRepresentation(shared_ptr<OCResourceRequest> pRequest) + { + auto pResponse = make_shared<OC::OCResourceResponse>(); + pResponse->setRequestHandle(pRequest->getRequestHandle()); + pResponse->setResourceHandle(pRequest->getResourceHandle()); + + // Check for query params (if any) + QueryParamsMap queryParamsMap = pRequest->getQueryParameters(); + + UA_LOG("\tquery params:"); + for (auto it = queryParamsMap.begin(); it != queryParamsMap.end(); it++) + { +// UA_LOG("\t\t%s : %s", query1, query2); + } + + auto findRes = queryParamsMap.find("if"); + + if (findRes != queryParamsMap.end()) + { + pResponse->setResourceRepresentation(getRepresentation(), findRes->second); + } + else + { + pResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE); + } + + pResponse->setResponseResult(OC_EH_OK); + + return OCPlatform::sendResponse(pResponse); + } + + OCStackResult propagate() + { + if (m_interestedObservers.size() > 0) + { + shared_ptr<OCResourceResponse> resourceResponse = + { make_shared<OCResourceResponse>() }; + + resourceResponse->setResourceRepresentation(getRepresentation(), DEFAULT_INTERFACE); + + return OCPlatform::notifyListOfObservers(m_handle, + m_interestedObservers, + resourceResponse); + } + + return OC_STACK_OK; + } + + virtual OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request) = 0; + + protected: + OCRepresentation m_representation; + vector<Resource *> m_childResources; + ObservationIds m_interestedObservers; +}; + + +class FirmwareResource : public Resource // x.samsung.firmware +{ + private: + string m_currentversion; + int m_state; //0: Idle, 1: Downloading, 2: Downloaded, 3: Updating + int m_result; //0: Initial, 1: success, 2: not enough space, 3: out of ram, 4: connection lost, 5: invalid binary, 6: invalid uri, 7: update failed, 8: unsupport protocol + string m_packageuri; + string m_newversion; + + int m_update; // 0: initial value 1: download , 2: upgrade, 3: auto + + char szState[2] = {0,}; + + public: + FirmwareResource(string uri, vector<string> rt, vector<string> itf, string cur_ver, string new_ver, string url, int update_state) + : Resource(uri, rt, itf) + { + m_currentversion = cur_ver; + update_state == 3 ? m_state = 0 : m_state = update_state; + m_result = 0; + m_packageuri = url; + m_newversion = new_ver; + m_update = 0; + + m_representation.setValue<string>("currentversion", m_currentversion); + m_representation.setValue<int>("state", m_state); + m_representation.setValue<int>("result", m_result); + + m_representation.setValue<string>("packageuri", m_packageuri); + m_representation.setValue<string>("newversion", m_newversion); + m_representation.setValue<int>("update", m_update); + } + + void onUpdateFirmware() + { + UA_LOG("onUpdateFirmware() called"); + if ((m_state == 0 && m_update == 1) || (m_state == 0 && m_update == 3)) { + UA_LOG("currentversion [%s]", m_currentversion.c_str()); + UA_LOG("newversion [%s]", m_newversion.c_str()); + + if(g_strcmp0(m_currentversion.c_str(), m_newversion.c_str()) == 0 || + g_strcmp0(m_newversion.c_str(), "") == 0) { + UA_LOG("no need for update cur=[%s], new=[%s]", m_currentversion.c_str(), m_newversion.c_str()); + return; + } + + UA_LOG("***Downloading image from [%s] ***", m_packageuri.c_str()); + //Downloading, Initial + m_state = 1; + m_representation.setValue<int>("state", m_state); + m_representation.setValue<int>("result", 0); + propagate(); + + snprintf(szState, sizeof(szState), "%d", m_state); + _set_device_info("firmware_update_state", szState); + + if (ua_http_download_file(m_packageuri.c_str()) != 0) { + UA_LOG("ua_http_download_file() is failed"); + m_state = 0; + m_representation.setValue<int>("state", m_state); + snprintf(szState, sizeof(szState), "%d", m_state); + _set_device_info("firmware_update_state", szState); + return; + } + + UA_LOG("***Firmware Image downloaded***"); + //Downloaded + m_state = 2; + m_representation.setValue<int>("state", m_state); + propagate(); + + snprintf(szState, sizeof(szState), "%d", m_state); + _set_device_info("firmware_update_state", szState); + } + + if ((m_state == 2 && m_update == 2) || (m_state == 2 && m_update == 3)) { + //Updating + m_state = 3; + m_representation.setValue<int>("state", m_update); + propagate(); + + snprintf(szState, sizeof(szState), "%d", m_state); + _set_device_info("firmware_update_state", szState); + + //After Upgrade, state = Idle + m_state = 0; + m_representation.setValue<int>("state", m_state); + m_representation.setValue<int>("result", 1); + + m_newversion = m_representation.getValue<string>("newversion"); + m_currentversion = m_representation.getValue<string>("currentversion"); + + UA_LOG("*** Update completed from %s to %s ***", m_currentversion.c_str(), m_newversion.c_str()); + + m_representation.setValue<string>("currentversion", m_newversion); + m_representation.setValue<string>("newversion", ""); + m_representation.setValue<string>("packageuri", ""); + m_currentversion = m_newversion; + m_newversion =""; + m_packageuri =""; + propagate(); + + snprintf(szState, sizeof(szState), "%d", m_state); + _set_device_info("firmware_update_state", szState); + + _set_device_info("firmware_ver", m_currentversion.c_str()); + + _exec_update(); + + } + } + + static void *_worker(void *pArg) + { + FirmwareResource *pThread = (FirmwareResource *)pArg; + pThread->onUpdateFirmware(); + return NULL; + } + + void setFirmwareRepresentation(OCRepresentation &rep) + { + UA_LOG(""); + bool hasUpdates = false; + string tmpStr; + int tmpUpdate; + if (rep.getValue<string>("packageuri", tmpStr)) + { + m_packageuri = tmpStr; + UA_LOG("\tpackageuri: %s", m_packageuri.c_str()); + m_representation.setValue<string>("packageuri", m_packageuri); + hasUpdates = true; + } + if (rep.getValue<string>("newversion", tmpStr)) + { + m_newversion = tmpStr; + UA_LOG("\tnewversion: %s", m_newversion.c_str()); + m_representation.setValue<string>("newversion", m_newversion); + hasUpdates = true; + } + +// if (rep.getValue<int>("updatemethod", m_updatemethod)) +// { +// UA_LOG("\t\t\t\t updatemethod: %d", m_updatemethod); +// m_representation.setValue<int>("updatemethod", m_updatemethod); +// hasUpdates = true; +// } + + if (rep.getValue<int>("update", tmpUpdate)) + { + m_update = tmpUpdate; + UA_LOG("\tupdate: %d", m_update); + hasUpdates = true; + + pthread_t hThread; + //Start temp thread to manage update simulator + pthread_create(&hThread, NULL, (void *(*)(void *))_worker, (void *)this); + } + + if (hasUpdates) + { + propagate(); + } + } + + OCEntityHandlerResult entityHandler(shared_ptr<OCResourceRequest> request) + { + UA_LOG("\tIn Server Firmware entity handler:"); + OCEntityHandlerResult ehResult = OC_EH_ERROR; + + if (request) + { + // Get the request type and request flag + string requestType = request->getRequestType(); + int requestFlag = request->getRequestHandlerFlag(); + + if (requestFlag & RequestHandlerFlag::RequestFlag) + { + UA_LOG("\trequestFlag : Request"); + + // If the request type is GET + if (requestType == "GET") + { + UA_LOG("\trequestType : GET"); + if (OC_STACK_OK == sendRepresentation(request)) + { + ehResult = OC_EH_OK; + } + } + else if (requestType == "PUT") + { + UA_LOG("\ttrequestType : PUT"); + // PUT requeist operations + } + else if (requestType == "POST") + { + UA_LOG("\trequestType : POST"); + // POST request operations + OCRepresentation rep = request->getResourceRepresentation(); + setFirmwareRepresentation(rep); + + if (OC_STACK_OK == sendRepresentation(request)) + { + ehResult = OC_EH_OK; + } + } + else if (requestType == "DELETE") + { + UA_LOG("\trequestType : DELETE"); + // DELETE request operations + } + } + + if (requestFlag & RequestHandlerFlag::ObserverFlag) + { + UA_LOG("\trequestFlag : Observer"); + + ObservationInfo observationInfo = request->getObservationInfo(); + if (ObserveAction::ObserveRegister == observationInfo.action) + { + m_interestedObservers.push_back(observationInfo.obsId); + } + else if (ObserveAction::ObserveUnregister == observationInfo.action) + { + m_interestedObservers.erase(remove( + m_interestedObservers.begin(), + m_interestedObservers.end(), + observationInfo.obsId), + m_interestedObservers.end()); + } + } + } + else + { + UA_LOG("Request invalid"); + } + + return ehResult; + } +}; + +#define UPDATE_FILE "/opt/usr/data/fota/init_tota" + +static void _exec_update() +{ + FILE* fp = fopen(UPDATE_FILE, "w"); + if(!fp) { + UA_LOG("fopen error: %d", errno); + } + fclose(fp); +} + +#if 0 +static void _exec_update() +{ + UA_LOG(""); + GError *gerror = NULL; + +#if !GLIB_CHECK_VERSION(2, 36, 0) + g_type_init(); +#endif + + GCancellable *proxy_cancel = g_cancellable_new(); + GDBusProxy* bproxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.tizen.system.tota", + "/Org/Tizen/System/Tota", + "org.tizen.system.tota", + proxy_cancel, + &gerror); + + if (!bproxy) { + UA_LOG ("g_dbus_proxy_new_for_bus_sync error [%s]", gerror->message); + if (bproxy) + g_object_unref (bproxy); + if (proxy_cancel) + g_object_unref(proxy_cancel); + if (gerror) + g_error_free (gerror); + return; + } + + GVariant *result = g_dbus_proxy_call_sync (bproxy, + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, /* msec, 5s*/ + NULL, + &gerror); + + + if (!result) { + UA_LOG ("g_dbus_proxy_call_sync error [%s]", gerror->message); + if (bproxy) + g_object_unref (bproxy); + + if (proxy_cancel) + g_object_unref(proxy_cancel); + + if (gerror) + g_error_free (gerror); + return; + } + + + UA_LOG ("success"); + if (bproxy) + g_object_unref (bproxy); + + if (proxy_cancel) + g_object_unref(proxy_cancel); + + if (gerror) + g_error_free (gerror); +} +#endif + +static void _set_device_info(const char *key, const char *value) +{ + UA_LOG("_set_device_info() key = %s, value = %s", key, value); + GKeyFile *keyfile; + GKeyFileFlags flags = G_KEY_FILE_NONE; + GError *error = NULL; + char file_path[256] = {0,}; + + keyfile = g_key_file_new(); + + snprintf(file_path, sizeof(file_path), "%s/%s", OC_CONTROLEE_DATA_FILE_PATH, "device_info.ini"); + + if (!g_key_file_load_from_file(keyfile, file_path, flags, &error)) { + UA_LOG("error=[%s]", error->message); + } else { + g_key_file_set_string(keyfile, "device_info", key, value); + g_key_file_save_to_file(keyfile, file_path, NULL); + g_key_file_unref(keyfile); + } +} + + +static void _get_device_info(ua_device_info_s *device) +{ + GKeyFile *keyfile; + GKeyFileFlags flags = G_KEY_FILE_NONE; + GError *error = NULL; + char file_path[256] = {0,}; + + keyfile = g_key_file_new(); + + snprintf(file_path, sizeof(file_path), "%s/%s", OC_CONTROLEE_DATA_FILE_PATH, "device_info.ini"); + + // wait for /opt/ mount + do { + sleep(5); + } while(!g_key_file_load_from_file(keyfile, file_path, flags, &error)); + + if (!g_key_file_load_from_file(keyfile, file_path, flags, &error)) { + UA_LOG("error=[%s]", error->message); + } else { + + device->manufacturer = g_key_file_get_string(keyfile, "device_info", "manufacturer", NULL); + device->model_name = g_key_file_get_string(keyfile, "device_info", "model_name", NULL); + device->firmware_ver = g_key_file_get_string(keyfile, "device_info", "firmware_ver", NULL); + device->firmware_update_state = g_key_file_get_string(keyfile, "device_info", "firmware_update_state", NULL); + device->uuid = g_key_file_get_string(keyfile, "device_info", "uuid", NULL); + device->access_token = g_key_file_get_string(keyfile, "device_info", "access_token", NULL); + + g_key_file_unref(keyfile); + } + + UA_LOG("manufacturer=[%s]", device->manufacturer); + UA_LOG("model_name=[%s]", device->model_name); + UA_LOG("firmware_ver=[%s]", device->firmware_ver); + UA_LOG("firmware_update_state=[%s]", device->firmware_update_state); + UA_LOG("uuid=[%s]", device->uuid); + UA_LOG("access_token=[%s]", device->access_token); +} + +void onPublish(const OCRepresentation &, const int &eCode) +{ + UA_LOG("Publish resource response received, code: %d", eCode); + + g_callbackLock.notify_all(); +} + +void printRepresentation(OCRepresentation rep) +{ + for (auto itr = rep.begin(); itr != rep.end(); ++itr) + { + UA_LOG("\t%s:\t%s", (itr->attrname()).c_str(), (itr->getValueToString()).c_str()); + if (itr->type() == AttributeType::Vector) + { + switch (itr->base_type()) + { + case AttributeType::OCRepresentation: + for (auto itr2 : (*itr).getValue<vector<OCRepresentation> >()) + { + printRepresentation(itr2); + } + break; + + case AttributeType::Integer: + for (auto itr2 : (*itr).getValue<vector<int> >()) + { + UA_LOG("\t\t%d", itr2); + } + break; + + case AttributeType::String: + for (auto itr2 : (*itr).getValue<vector<string> >()) + { + UA_LOG("\t\t%s", itr2.c_str()); + } + break; + + default: + UA_LOG("Unhandled base type = %d" , itr->base_type()); + break; + } + } + else if (itr->type() == AttributeType::OCRepresentation) + { + printRepresentation((*itr).getValue<OCRepresentation>()); + } + } +} + +void handleSignupCB(const HeaderOptions &, + const OCRepresentation &rep, const int ecode) +{ + UA_LOG("Auth response received code: %d", ecode); + + if (rep.getPayload() != NULL) + { + printRepresentation(rep); + } + + if (ecode == 4) + { + g_accesstoken = rep.getValueToString("accesstoken"); + g_uid = rep.getValueToString("uid"); + + _set_device_info("uuid", g_uid.c_str()); + _set_device_info("access_token", g_accesstoken.c_str()); + } + + g_callbackLock.notify_all(); +} + + +void handleSigninCB(const HeaderOptions &, + const OCRepresentation &rep, const int ecode) +{ + UA_LOG("Auth response received code: %d", ecode); + + if (rep.getPayload() != NULL) + { + printRepresentation(rep); + } + + g_callbackLock.notify_all(); +} + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) +int saveTrustCert(void) +{ + OCStackResult res = OC_STACK_ERROR; + uint16_t g_credId = 0; + + UA_LOG("Save Trust Cert. Chain into Cred of SVR"); + + ByteArray trustCertChainArray = {0, 0}; + + FILE *fp = fopen("rootca.crt", "rb+"); + + if (fp) + { + size_t fsize; + if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp)) > 0) + { + trustCertChainArray.data = (uint8_t *)malloc(fsize); + trustCertChainArray.len = fsize; + if (NULL == trustCertChainArray.data) + { + UA_LOG("Failed to allocate memory"); + fclose(fp); + return res; + } + rewind(fp); + if (fsize != fread(trustCertChainArray.data, 1, fsize, fp)) + { + UA_LOG("Certiface not read completely"); + } + fclose(fp); + } + } + + res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM, + &g_credId); + + if (OC_STACK_OK != res) + { + UA_LOG("OCSaveTrustCertChainBin API error"); + return res; + } + UA_LOG("CredId of Saved Trust Cert. Chain into Cred of SVR : %d", g_credId); + + return res; +} +#endif + +static FILE *client_open(const char *path, const char *mode) +{ + if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) + { + char *file_path = g_strconcat(OC_CONTROLEE_DATA_FILE_PATH, OC_CONTROLEE_DB_DAT_FILE_NAME, NULL); + FILE *fp = fopen(file_path, mode); + g_free(file_path); + return fp; + } + else + { + return fopen(path, mode); + } +} + +OCStackResult SetDeviceInfo() +{ + OCStackResult result = OC_STACK_ERROR; + + OCResourceHandle handle = OCGetResourceHandleAtUri(OC_RSRVD_DEVICE_URI); + + if (handle == NULL) + { + UA_LOG("Failed to find resource [%s]", OC_RSRVD_DEVICE_URI); + return result; + } + + //result = OCBindResourceTypeToResource(handle, "oic.d.airconditioner"); + result = OCBindResourceTypeToResource(handle, "x.tizen.ri3"); + + if (result != OC_STACK_OK) + { + UA_LOG("Failed to add device type"); + return result; + } + + result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, "TIZEN_RI3"); + + if (result != OC_STACK_OK) + { + UA_LOG("Failed to set device name"); + return result; + } + + result = OCPlatform::setPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_PROTOCOL_INDEPENDENT_ID, + "d7d2b492-83ac-4783-9dcc-b1b54587ebed"); + + if (result != OC_STACK_OK) + { + UA_LOG("Failed to set piid"); + return result; + } + + return OC_STACK_OK; +} + +//#include <wifi.h> +#include <net_connection.h> + +connection_cellular_state_e get_cellular_network_state() +{ + connection_h connection; + connection_create(&connection); + + connection_cellular_state_e cellular_state; + connection_get_cellular_state(connection, &cellular_state); + connection_destroy(connection); + + return cellular_state; +} + +connection_wifi_state_e get_wifi_network_state() +{ + connection_h connection; + connection_create(&connection); + + connection_wifi_state_e wifi_state; + connection_get_wifi_state(connection, &wifi_state); + connection_destroy(connection); + + return wifi_state; +} + + +int is_network_connected() +{ + //cellular + int network_state = 0; + + if (get_cellular_network_state() == CONNECTION_CELLULAR_STATE_CONNECTED) + { + network_state = true; + } + + // ethernet + if (get_wifi_network_state() == CONNECTION_ETHERNET_STATE_CONNECTED) + { + network_state = true; + } + + //wifi + if (get_wifi_network_state() == CONNECTION_WIFI_STATE_CONNECTED) + { + network_state = true; + } + + return network_state; +} + + +void *_start_ua_client(void *data) +{ + UA_LOG(""); + + ua_device_info_s *device = (ua_device_info_s *)data; + + mutex blocker; + unique_lock<mutex> lock(blocker); + + UA_LOG("Registering firmware resources to platform..."); + + OCStackResult result = OC_STACK_ERROR; + string uri; + string rt; + string itf; + +#if 1 + /* Check new firmware version at content server */ + char *http_url = g_strconcat(UA_CONTENTS_SERVER_URL, "/firmware", "?manufacturer=", device->manufacturer, "&model=", device->model_name, \ + "&version=", device->firmware_ver, NULL); + + char *httr_res_header = NULL; + char *httr_res_body = NULL; + + char *old_ver = NULL; + char *new_ver = NULL; + char *download_url = NULL; + char *priority = NULL; + + if (ua_http_send_request(UA_HTTP_GET, http_url, &httr_res_header, &httr_res_body) != 0) { + UA_LOG("ua_http_send_request() is failed"); + } + + if (httr_res_body) { + ua_json_parser_firmware_info(httr_res_body, &old_ver, &new_ver, &download_url, &priority); + } + + UA_LOG("firm_ver: %s , new_ver: %s", device->firmware_ver, new_ver); + + string cur_firmware_ver((device->firmware_ver)?device->firmware_ver:""); + string new_firmware_ver((new_ver)?new_ver:""); + string new_url((download_url)?download_url:""); + + UA_LOG("device->firmware_update_state: %s", device->firmware_update_state); + FirmwareResource firmware("/firmware", { "x.samsung.firmware" }, { DEFAULT_INTERFACE }, \ + cur_firmware_ver, new_firmware_ver, new_url, atoi(device->firmware_update_state)); + +#else + string cur_firmware_ver(device->firmware_ver); + string new_firmware_ver(""); + + FirmwareResource firmware("/firmware", { "x.samsung.firmware" }, { DEFAULT_INTERFACE }, \ + cur_firmware_ver, new_firmware_ver, atoi(device->firmware_update_state)); + +#endif + uri = firmware.getResourceUri(); + rt = firmware.getResourceType()[0]; + itf = firmware.getInterfaces()[0]; + + // Time to Live is 30 seconds + OCPlatform::startPresence(30); + + result = OCPlatform::registerResource(firmware.m_handle, + uri, + rt, + itf, + bind(&FirmwareResource::entityHandler, + &firmware, placeholders::_1), + OC_DISCOVERABLE | OC_OBSERVABLE); + + UA_LOG("registerResource firmware: result = %d", result); + if (result != OC_STACK_OK) { + UA_LOG("Resource registration was unsuccessful, [%d]", result); + return NULL; + } + + UA_LOG("Publishing resources to cloud"); + + result = SetDeviceInfo(); + if (result != OC_STACK_OK) { + UA_LOG("SetDeviceInfo() is failed, [%d]", result); + return NULL; + } + + OCPlatform::stopPresence(); + + ResourceHandles resourceHandles; + + result = RDClient::Instance().publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP, + resourceHandles, + &onPublish); + + UA_LOG(" result: %d, Waiting Publish default resource response from cloud", result); + + resourceHandles.push_back(firmware.m_handle); + + result = RDClient::Instance().publishResourceToRD(g_host, OCConnectivityType::CT_ADAPTER_TCP, + resourceHandles, + &onPublish); + + UA_LOG(" result: %d, Waiting Publish user resource response from cloud", result); + + g_callbackLock.wait(lock); + + while(true) { + // Running.... + } + + return NULL; +} + + +int main(int argc, char *argv[]) +{ +#if !GLIB_CHECK_VERSION(2, 31, 0) + g_thread_init(NULL); +#endif + +#if !GLIB_CHECK_VERSION(2, 36, 0) + g_type_init(); +#endif + + signal(SIGCHLD, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGPIPE, SIG_IGN); + + + GThread *main_thd = NULL; + + mutex blocker; + unique_lock<mutex> lock(blocker); + + + OCPersistentStorage ps{ client_open, fread, fwrite, fclose, unlink }; + + PlatformConfig cfg + { + ServiceType::InProc, + ModeType::Both, + "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces + 0, // Uses randomly available port + QualityOfService::LowQos, + &ps + }; + + OCPlatform::Configure(cfg); + + g_host = "coap+tcp://"; + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + g_host = "coaps+tcp://"; +#endif + + +#if 0 + g_host += argv[1]; +#else + string ocf_server_url(UA_OCF_SERVER_URL); + g_host += ocf_server_url; + + ua_device_info_s *device = (ua_device_info_s *)calloc(1, sizeof(ua_device_info_s)); + + _get_device_info(device); +#endif + UA_LOG("host address = %s", g_host.c_str()); + + OCAccountManager::Ptr accountMgr = OCPlatform::constructAccountManagerObject(g_host, + CT_ADAPTER_TCP); + + +#if defined(__WITH_DTLS__) || defined(__WITH_TLS__) + UA_LOG("Security Mode"); + if (CA_STATUS_OK != saveTrustCert()) + { + UA_LOG("saveTrustCert returned an error"); + } + + uint16_t cipher = MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256; + if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP)) + { + UA_LOG("CASelectCipherSuite returned an error"); + } +#endif + + // wait for network connection + while(is_network_connected() == 0){ + UA_LOG("network not ready"); + sleep(5); + } + + try { + if (device->uuid == NULL || (device->uuid && strlen(device->uuid) == 0)) { + if (argc != 3) + { + fprintf(stderr, "\n\nPut \"[authprovider] [authcode]\" for sign-up and sign-in and publish resources!!\n\n"); + return 0; + } + UA_LOG("Sign-up..."); + accountMgr->signUp(argv[1], argv[2], &handleSignupCB); + g_callbackLock.wait(lock); + UA_LOG("Sign-In..."); + accountMgr->signIn(g_uid, g_accesstoken, &handleSigninCB); + g_callbackLock.wait(lock); + } else { + UA_LOG("Sign-In..."); + string uuid(device->uuid); + string access_token(device->access_token); + accountMgr->signIn(uuid, access_token, &handleSigninCB); + g_callbackLock.wait(lock); + } + } + catch (exception& e){ + UA_LOG("Authentication failed"); + goto _END_OF_PROC; + } + + main_thd = g_thread_new("ua_client", _start_ua_client, (void *)device); + if (main_thd == NULL) { + UA_LOG("Fail to run main thread"); + } + + mainloop = g_main_loop_new(NULL, FALSE); + + if (mainloop != NULL) { + UA_LOG("Start ua_client"); + g_main_loop_run(mainloop); + } else { + UA_LOG("Fail to start ua_client"); + } + + +_END_OF_PROC: + g_free(device->manufacturer); + g_free(device->model_name); + g_free(device->firmware_ver); + g_free(device->firmware_update_state); + g_free(device->uuid); + g_free(device->access_token); + g_free(device); + + + return 0; +} diff --git a/src/ua_http.cpp b/src/ua_http.cpp new file mode 100644 index 0000000..ee67f15 --- /dev/null +++ b/src/ua_http.cpp @@ -0,0 +1,214 @@ +#include <glib.h> +#include <curl/curl.h> + +#include <ua_client.h> + +#define UA_FIRMWARE_DOWNLOAD_PATH "/opt/usr/data/fota/" +#define UA_FIRMWARE_DOWNLOAD_FILE UA_FIRMWARE_DOWNLOAD_PATH"delta.tar" + + +static size_t _gather_data(void *downloaded_data, + size_t size, + size_t nmemb, + void *user_data) +{ + size_t total_size = size * nmemb; + g_byte_array_append((GByteArray *)user_data, (const unsigned char *) downloaded_data, total_size); + return total_size; +} + + +void _curl_set_response(CURL *curl, + GByteArray *response_header, + GByteArray *response_body, + char **res_header, + char **res_body, + void *user_data) +{ + CURLcode curl_ret_code; + + long response = 0; + curl_ret_code = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response); + if (CURLE_OK != curl_ret_code) + return; + + char *tmp_header = g_strndup((const gchar *)response_header->data, response_header->len); + char *tmp_body = g_strndup((const gchar *)response_body->data, response_body->len); + + *res_header = tmp_header; + *res_body = tmp_body; +} + + +void _curl_set_common_option(CURL *curl, + const char *url, + GByteArray **response_header_ptr, + GByteArray **response_body_ptr) +{ + UA_LOG("_curl_set_common_option()"); + CURLcode curl_ret_code; + + UA_LOG("set URL = [%s]", url); + curl_ret_code = curl_easy_setopt(curl, CURLOPT_URL, url); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_URL failed!! curl_ret_code[%d]", curl_ret_code); + } + + GByteArray *response_header_data = g_byte_array_new(); + curl_ret_code = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, _gather_data); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_HEADERFUNCTION failed!! curl_ret_code[%d]", curl_ret_code); + } + + curl_ret_code = curl_easy_setopt(curl, CURLOPT_HEADERDATA, response_header_data); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_HEADERDATA failed!! curl_ret_code[%d]", curl_ret_code); + } + + GByteArray *response_body_data = g_byte_array_new(); + + curl_ret_code = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _gather_data); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_WRITEFUNCTION failed!! curl_ret_code[%d]", curl_ret_code); + } + + curl_ret_code = curl_easy_setopt(curl, CURLOPT_WRITEDATA, response_body_data); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_WRITEDATA failed!! curl_ret_code[%d]", curl_ret_code); + } + + curl_ret_code = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_NOPROGRESS failed!! curl_ret_code[%d]", curl_ret_code); + } + + *response_header_ptr = response_header_data; + *response_body_ptr = response_body_data; + +#if 0 + curl_ret_code = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_VERBOSE failed!! curl_ret_code[%d]", curl_ret_code); + } + + curl_ret_code = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_SSL_VERIFYPEER failed!! curl_ret_code[%d]", curl_ret_code); + } + + curl_ret_code = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, FALSE); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_SSL_VERIFYHOST failed!! curl_ret_code[%d]", curl_ret_code); + } + + curl_ret_code = curl_easy_setopt(curl, CURLOPT_CERTINFO, 0L); + if (CURLE_OK != curl_ret_code) { + UA_LOG("curl_easy_setopt: CURLOPT_CERTINFO failed!! curl_ret_code[%d]", curl_ret_code); + } +#endif +} + + +static void _curl_set_request_headers(CURL *curl) +{ + struct curl_slist *header = NULL; + + char *tmp_header = NULL; + + tmp_header = g_strconcat("Content-Type: ", "application/json", NULL); + UA_LOG("header=[%s]", tmp_header); + header = curl_slist_append(header, tmp_header); + g_free(tmp_header); + + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header); +} + + +int ua_http_send_request(rest_req_type type, char *req_url, char **res_header, char **res_body) +{ + UA_LOG("Enter http_send_request()"); + + CURL *curl; + GByteArray *response_header = NULL; + GByteArray *response_body= NULL; + CURLcode error_code; + int ret = 0; + + // Start a libcurl easy session + curl = curl_easy_init(); + + UA_LOG("curl_easy_init()"); + + _curl_set_request_headers(curl); + + if (type == UA_HTTP_GET) { + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + } else if (type == UA_HTTP_POST) { + curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1); + } else { + return -1; + } + + _curl_set_common_option(curl, (const char *)req_url, &response_header, &response_body); + + UA_LOG("Start curl_easy_perform......"); + error_code = curl_easy_perform(curl); + UA_LOG("curl_easy_perform(curl): %s (%d)", curl_easy_strerror(error_code), error_code); + + if (error_code == CURLE_ABORTED_BY_CALLBACK) { + ret = -1; + goto _END_OF_FUNC_; + } else if (error_code != CURLE_OK) { + ret = -1; + goto _END_OF_FUNC_; + } + + _curl_set_response(curl, response_header, response_body, res_header, res_body, NULL); + +_END_OF_FUNC_: + if (response_header) { + g_byte_array_free(response_header, TRUE); + } + if (response_body) { + g_byte_array_free(response_body, TRUE); + } + + curl_easy_cleanup(curl); + return ret; +} + + +int ua_http_download_file(const char *download_url) +{ + UA_LOG("http_download_file() enter"); + + if (!download_url) + return -1; + + int ret = 0; + CURL *curl; + FILE *fp; + CURLcode error_code; + + curl = curl_easy_init(); + if (curl) + { + fp = fopen(UA_FIRMWARE_DOWNLOAD_FILE, "wb"); + curl_easy_setopt(curl, CURLOPT_URL, download_url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + error_code = curl_easy_perform(curl); + UA_LOG("curl_easy_perform() [%d]", error_code); + curl_easy_cleanup(curl); + fclose(fp); + + if (error_code != CURLE_OK) { + remove(UA_FIRMWARE_DOWNLOAD_FILE); + ret = -1; + } + } else { + ret = -1; + } + + return ret; +} diff --git a/src/ua_json_parser.cpp b/src/ua_json_parser.cpp new file mode 100644 index 0000000..9dedba2 --- /dev/null +++ b/src/ua_json_parser.cpp @@ -0,0 +1,170 @@ +#include <glib.h> +#include <json-glib/json-glib.h> +#include <json-glib/json-gobject.h> + +#include "ua_client.h" + +#define UA_JSON_OLD_VERSION_STR "old_version" +#define UA_JSON_NEW_VERSION_STR "new_version" +#define UA_JSON_DOWNLOAD_URL_STR "url" +#define UA_JSON_PRIORITY_STR "priority" +#define UA_JSON_DEVICE_STR "devices" +#define UA_JSON_ERR_MSG_STR "errmsg" + + +void _set_hash_table(char *key, JsonObject *json_obj, GHashTable *hash_table) +{ + UA_LOG("BEGIN"); + + const gchar *str_val; + gint64 int_val; + + char ret[64] = {0,}; + + JsonNode *tmpNode = json_object_get_member(json_obj, key); + + GType val_type = json_node_get_value_type(tmpNode); + + if (val_type == G_TYPE_INT || val_type == G_TYPE_INT64) { + int_val = json_object_get_int_member(json_obj, (const gchar *)key); + UA_LOG("key=[%s] value=[%lld]", key, int_val); + snprintf(ret, sizeof(ret), "%lld", int_val); + } else if (val_type == G_TYPE_STRING) { + str_val = json_object_get_string_member(json_obj, (const gchar *)key); + UA_LOG("key=[%s] value=[%s]", key, str_val); + snprintf(ret, sizeof(ret), "%s", str_val); + } else { + UA_LOG("Invalid GType"); + return; + } + + if (g_hash_table_insert(hash_table, (gpointer)g_strdup(key), (gpointer)g_strdup(ret)) == 0) + UA_LOG("g_hash_table_insert() failed"); + UA_LOG("END"); +} + +void _parse_json_members(JsonObject *json_obj, GHashTable *hash_table) +{ + UA_LOG("_parse_json_members()"); + + GList *json_object_members_list = NULL; + int len; + int i = 0; + char *key; + + json_object_members_list = json_object_get_members(json_obj); + len = g_list_length(json_object_members_list); + + for (i = 0; i < len; i++) { + JsonObject *child_obj = NULL; + JsonArray *ary_obj = NULL; + key = (char *)g_list_nth_data(json_object_members_list, i); + + JsonNode *tmpNode = json_object_get_member(json_obj, key); + JsonNodeType node_type = json_node_get_node_type(tmpNode); + + switch (node_type) { + case JSON_NODE_OBJECT: + { + child_obj = json_object_get_object_member(json_obj, key); + if (child_obj) { + _parse_json_members(child_obj, hash_table); + } + break; + } + case JSON_NODE_ARRAY : + { + ary_obj = json_object_get_array_member(json_obj, UA_JSON_DEVICE_STR); + child_obj = json_array_get_object_element(ary_obj, 0); + if (child_obj) { + _parse_json_members(child_obj, hash_table); + } + break; + } + case JSON_NODE_VALUE : + { + _set_hash_table(key, json_obj, hash_table); + break; + } + default: + break; + } + } + + g_list_free(json_object_members_list); + UA_LOG("END"); +} + +void _parse_response(const char *data, GHashTable *hash_table) +{ + JsonParser *json_parser = NULL; + JsonNode *root_node = NULL; + GError *error = NULL; + + json_parser = json_parser_new(); + + char *json_data = g_strdup(data); + + json_parser_load_from_data(json_parser, (const gchar *)json_data, -1, &error); + if (error) { + UA_LOG("json_parser_load_from_data() : error [%s]", error->message); + g_error_free(error); + g_object_unref(json_parser); + g_free(json_data); + return; + } + + root_node = json_parser_get_root(json_parser); + + JsonNodeType node_type = json_node_get_node_type(root_node); + + JsonObject *json_object = NULL; + + switch(node_type) { + case JSON_NODE_OBJECT: + { + json_object = json_node_get_object(root_node); + _parse_json_members(json_object, hash_table); + UA_LOG("_parse_json_members done"); + break; + } + default: + UA_LOG("json node other"); + break; + } + + if (json_parser) + g_object_unref(json_parser); + if (json_data) + g_free(json_data); + UA_LOG("END"); +} + +void ua_json_parser_firmware_info(const char *data, char **old_ver, char **new_ver, \ + char **download_url, char **priority) +{ + UA_LOG("http_registration_res_json_parser()"); + + GHashTable *hash_table = NULL; + + hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + + _parse_response(data, hash_table); + + if (old_ver) + *old_ver = g_strdup((char *)g_hash_table_lookup(hash_table, UA_JSON_OLD_VERSION_STR)); + + if (new_ver) + *new_ver = g_strdup((char *)g_hash_table_lookup(hash_table, UA_JSON_NEW_VERSION_STR)); + + if (download_url) + *download_url = g_strdup((char *)g_hash_table_lookup(hash_table, UA_JSON_DOWNLOAD_URL_STR)); + + if (priority) + *priority = g_strdup((char *)g_hash_table_lookup(hash_table, UA_JSON_PRIORITY_STR)); + + g_hash_table_destroy(hash_table); + UA_LOG("END"); + +} + |