1 //******************************************************************
3 // Copyright 2017 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
23 #ifndef _CONCURRENTIOTIVITYUTILS_H_
24 #define _CONCURRENTIOTIVITYUTILS_H_
29 #include <condition_variable>
36 #include "IotivityWorkItem.h"
37 #include "WorkQueue.h"
45 template<typename T, typename... Args>
46 std::unique_ptr<T> make_unique(Args &&... args)
48 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
52 * Provides a synchronized C++ wrapper over the Iotivity CSDK.
53 * Accepts workItems from the plugins for common operations.
54 * A consumer thread processes these worker items and makes calls into Iotivity.
55 * Another thread calls OCProcess() to check for network requests.
57 class ConcurrentIotivityUtils
61 static std::unique_ptr<WorkQueue<std::unique_ptr<IotivityWorkItem>>> m_queue;
62 std::mutex m_iotivityApiCallMutex;
64 std::thread m_processWorkQueueThread, m_ocProcessThread;
66 bool m_shutDownOCProcessThread;
67 static const int OCPROCESS_SLEEP_MICROSECONDS = 200000;
69 // Fetches work item from queue and processes it.
70 void processWorkQueue()
74 std::unique_ptr<IotivityWorkItem> workItem;
75 bool fetchedWorkItem = m_queue->get(&workItem);
79 std::lock_guard<std::mutex> lock(m_iotivityApiCallMutex);
91 while (!m_shutDownOCProcessThread)
94 std::lock_guard<std::mutex> lock(m_iotivityApiCallMutex);
97 // Hopefully it's enough for other threads to be scheduled
98 // instead of the spin here. OCProcess is very lightweight though.
99 usleep(OCPROCESS_SLEEP_MICROSECONDS);
106 ConcurrentIotivityUtils(std::unique_ptr<WorkQueue<std::unique_ptr<IotivityWorkItem>>>
109 m_queue = std::move(queueToMonitor);
110 m_threadStarted = false;
111 m_shutDownOCProcessThread = false;
115 * Starts 2 worker threads. One to service the concurrent work queue to call
116 * into Iotivity. One to process network requests by calling OCProcess()
118 void startWorkerThreads();
121 * Stops the 2 worker threads started by startWorkerThreads. @see startWorkerThreads
123 void stopWorkerThreads();
126 * Gets the string uri associated with an Iotivity handle.
127 * @warning This function is not thread safe and should only be called from entityHandler
128 * specified when creating the resource. The entityhandler is called with the
129 * Iotivity access mutex locked and this function does not modify anything
132 * @param[in] handle handle for the resource
133 * @param[out] uri uri associated with the handle
135 * @return true if the resource is found and uri will be populated, else false.
137 bool static getUriFromHandle(OCResourceHandle handle, std::string &uri);
140 * Sends out OBSERVE notifications for the resource with the given uri.
141 * Notifications are sent out using OC_NA_QOS.
143 * @param[in] resourceUri resource uri for fetching handle and notifying
145 * @return OCStackResult OC_STACK_OK on success, some other value upon failure.
147 OCStackResult static queueNotifyObservers(const std::string &resourceUri);
150 * Create an Iotivity resource with the given properties.
153 * @param[in] resourceType
154 * @param[in] interface
155 * @param[in] entityHandler Callback function that will be called on requests to this resource.
156 * @param[in] callbackParam
157 * @param[in] resourceProperties
159 * @return OCStackResult OC_STACK_OK on success, some other value upon failure.
162 queueCreateResource(const std::string &uri, const std::string &resourceType,
163 const std::string &interface,
164 OCEntityHandler entityHandler, void *callbackParam,
165 uint8_t resourceProperties);
168 * Delete the Iotivity resource given in the uri.
172 * @return OCStackResult OC_STACK_OK on success, some other value upon failure.
174 OCStackResult static queueDeleteResource(const std::string &uri);
177 * Send a response to a request.
179 * @param[in] request OCEntityHandleRequest type that was handed in the entityhandler.
180 * @param[in] payload The response payload. This is cloned and callee still has ownership
181 * and the onus to free this.
182 * @param[in] responseCode The response code of type OCEntityHandlerResult in ocstack.h
184 * @return OCStackResult OC_STACK_OK on success, some other value upon failure.
187 respondToRequest(OCEntityHandlerRequest *request, OCRepPayload *payload,
188 OCEntityHandlerResult responseCode);
191 * Respond with an error message. Internally calls
192 * ConcurrentIotivityUtils::respondToRequest() after creating
193 * a payload containing the error message. The error message
194 * key will be x.org.iotivity.error and the value will be
197 * @param[in] request EntityHandler request
198 * @param[in] errorMessage May be NULL.
199 * @param[in] errorCode entity handler result
201 * @return OCStackResult OC_STACK_OK on success, some other value upon failure.
203 OCStackResult static respondToRequestWithError(OCEntityHandlerRequest *request,
204 const std::string &errorMessage,
205 OCEntityHandlerResult errorCode);
208 * Parse the query parameter as a keyValueMap
210 * @param[in] query query to be parsed
211 * @param[in,out] keyValueMap key value map of the query
213 void static getKeyValueParams(const std::string &query,
214 std::map<std::string, std::string> &keyValueMap);
217 * Can be called from the entity handler to handle requests for default interface
221 * @return true if request for default interface (oic.if.baseline) else false.
223 bool static isRequestForDefaultInterface(const std::string &query);
229 #endif //_CONCURRENTIOTIVITYUTILS_H_