replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / notification / unittest / NSProviderSimulator.h
1 //******************************************************************
2 //
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #ifndef _NS_PROVIDER_SIMULATOR_H_
22 #define _NS_PROVIDER_SIMULATOR_H_
23
24 #include <iostream>
25 #include <memory>
26
27 #include "OCPlatform.h"
28 #include "OCApi.h"
29 #include "OCResourceResponse.h"
30
31 namespace
32 {
33     enum class requestType
34     {
35         NS_NOTIFICATION,
36         NS_MESSAGE,
37         NS_SYNC,
38         NS_TOPIC,
39     };
40     enum class messageType
41     {
42         NS_ALLOW = 1,
43         NS_DENY,
44         NS_TOPIC,
45     };
46 }
47
48 class NSProviderSimulator
49 {
50 public:
51     enum class TopicAllowState
52     {
53         DENY,
54         ALLOW
55     };
56     typedef std::pair<std::string, TopicAllowState> NS_TopicState;
57     typedef std::map<std::string, TopicAllowState> NS_TopicStateList;
58
59     typedef std::list<std::string> NS_TopicList;
60 private:
61     OCResourceHandle m_notificationHandle;
62     OCResourceHandle m_messageHandle;
63     OCResourceHandle m_syncHandle;
64     OCResourceHandle m_topicHandle;
65     OC::OCRepresentation m_syncRep;
66     OC::OCRepresentation m_messageRep;
67     int m_accepter;
68
69     std::string m_notificationUri;
70     std::string m_messageUri;
71     std::string m_syncUri;
72     std::string m_topicUri;
73     NS_TopicList m_topicList;
74     NS_TopicStateList m_allowedTopicList;
75
76     OC::ObservationIds m_syncObservers;
77
78 public:
79     NSProviderSimulator()
80     : m_notificationHandle(), m_messageHandle(), m_syncHandle(), m_topicHandle(),
81       m_syncRep(), m_messageRep(), m_accepter(0),
82       m_notificationUri(std::string("/notification")),
83       m_messageUri(std::string("/message")),
84       m_syncUri(std::string("/sync")),
85       m_topicUri(std::string("/topic")),
86       m_topicList(),
87       m_allowedTopicList(),
88       m_syncObservers()
89     {
90
91     };
92
93     ~NSProviderSimulator() = default;
94
95     NSProviderSimulator(const NSProviderSimulator &) = delete;
96     NSProviderSimulator & operator = (const NSProviderSimulator &) = delete;
97
98     NSProviderSimulator(NSProviderSimulator &&) = delete;
99     NSProviderSimulator & operator = (NSProviderSimulator &&) = delete;
100
101 private:
102     std::shared_ptr<OC::OCResourceResponse> getResponse(
103             std::shared_ptr< OC::OCResourceRequest > requests, requestType type)
104     {
105         auto response = std::make_shared<OC::OCResourceResponse>();
106         response->setRequestHandle(requests->getRequestHandle());
107         response->setResourceHandle(requests->getResourceHandle());
108
109         int requestFlag = requests->getRequestHandlerFlag();
110         if (requestFlag == OC::RequestHandlerFlag::RequestFlag)
111         {
112             std::string request = requests->getRequestType();
113
114             response->setErrorCode(200);
115             response->setResponseResult(OC_EH_OK);
116
117             if (request == "GET")
118             {
119                 OC::OCRepresentation rep;
120
121                 if (type == requestType::NS_NOTIFICATION)
122                 {
123                     std::string msgUri = m_notificationUri + m_messageUri;
124                     std::string syncUri = m_notificationUri + m_syncUri;
125                     std::string topicUri = m_notificationUri + m_topicUri;
126                     std::string providerId = "123456789012345678901234567890123456";
127                     rep.setValue("x.org.iotivity.ns.subcontrollability", m_accepter);
128                     rep.setValue("x.org.iotivity.ns.messageuri", msgUri);
129                     rep.setValue("x.org.iotivity.ns.syncuri", syncUri);
130                     rep.setValue("x.org.iotivity.ns.topicuri", topicUri);
131                     rep.setValue("x.org.iotivity.ns.providerid", providerId);
132                 }
133                 else if (type == requestType::NS_SYNC)
134                 {
135                     rep = m_syncRep;
136                 }
137                 else if (type == requestType::NS_MESSAGE)
138                 {
139                     rep = m_messageRep;
140                 }
141                 else if (type == requestType::NS_TOPIC)
142                 {
143                     if (m_allowedTopicList.empty())
144                     {
145                         std::for_each (m_topicList.begin(), m_topicList.end(),
146                             [this](const std::string & topic)
147                             {
148                                 m_allowedTopicList.insert(
149                                         std::make_pair<std::string, TopicAllowState>(
150                                                 std::string(topic), TopicAllowState::DENY));
151                             }
152                         );
153                     }
154
155                     std::vector<OC::OCRepresentation> topicArr;
156
157                     std::for_each (m_allowedTopicList.begin(), m_allowedTopicList.end(),
158                         [& topicArr](const NS_TopicState & topicState)
159                         {
160                             OC::OCRepresentation topic;
161                             topic.setValue("x.org.iotivity.ns.topicname", topicState.first);
162                             topic.setValue("x.org.iotivity.ns.topicstate", (int) topicState.second);
163                             topicArr.push_back(topic);
164                         }
165                     );
166
167                     rep.setValue<std::vector<OC::OCRepresentation>>
168                         ("x.org.iotivity.ns.topiclist", topicArr);
169                 }
170                 else
171                 {
172                     return NULL;
173                 }
174
175                 response->setResourceRepresentation(rep);
176                 return response;
177             }
178
179             else if (request == "POST")
180             {
181                 if (type == requestType::NS_SYNC)
182                 {
183                     m_syncRep = requests->getResourceRepresentation();
184
185                     std::cout << "Receive POST for Sync" << std::endl;
186                     std::cout << "provider Id : " << m_syncRep.getValueToString("x.org.iotivity.ns.providerid") << std::endl;
187                     std::cout << "Sync State : " << m_syncRep.getValueToString("x.org.iotivity.ns.state") << std::endl;
188
189                     response->setResourceRepresentation(m_syncRep);
190
191                     OC::OCPlatform::notifyAllObservers(m_syncHandle);
192
193                     return response;
194                 }
195                 else if (type == requestType::NS_TOPIC)
196                 {
197                     auto receivePayload =
198                             requests->getResourceRepresentation()
199                             .getValue<std::vector<OC::OCRepresentation>>("x.org.iotivity.ns.topiclist");
200
201                     std::for_each (receivePayload.begin(), receivePayload.end(),
202                           [this](const OC::OCRepresentation & rep)
203                           {
204                               auto tmp = m_allowedTopicList.find(rep.getValueToString("x.org.iotivity.ns.topicname"));
205                               if (tmp != m_allowedTopicList.end())
206                               {
207                                   tmp->second = (TopicAllowState) rep.getValue<int>("x.org.iotivity.ns.topicstate");
208                               }
209                           }
210                     );
211                 }
212             }
213         }
214
215         return NULL;
216     }
217
218     void setObserver(std::shared_ptr< OC::OCResourceRequest > requests, requestType type)
219     {
220         if (type == requestType::NS_SYNC)
221         {
222             OC::ObservationInfo observationInfo = requests->getObservationInfo();
223             if (OC::ObserveAction::ObserveRegister == observationInfo.action)
224             {
225                 m_syncObservers.push_back(observationInfo.obsId);
226             }
227             else if (OC::ObserveAction::ObserveUnregister == observationInfo.action)
228             {
229                 m_syncObservers.erase(std::remove(
230                         m_syncObservers.begin(), m_syncObservers.end(),
231                         observationInfo.obsId), m_syncObservers.end());
232             }
233         }
234         else if (type == requestType::NS_MESSAGE)
235         {
236             OC::OCRepresentation rep;
237             std::string providerId = "123456789012345678901234567890123456";
238             rep.setValue<int>("x.org.iotivity.ns.messageid", (int)messageType::NS_ALLOW);
239             rep.setValue("x.org.iotivity.ns.providerid", providerId);
240
241             auto response = std::make_shared<OC::OCResourceResponse>();
242             response->setRequestHandle(requests->getRequestHandle());
243             response->setResourceHandle(requests->getResourceHandle());
244             response->setErrorCode(200);
245             response->setResponseResult(OC_EH_OK);
246             response->setResourceRepresentation(rep);
247
248             OC::ObservationIds ids;
249             ids.push_back(requests->getObservationInfo().obsId);
250
251             OC::OCPlatform::notifyListOfObservers(m_messageHandle, ids, response);
252         }
253     }
254
255     OCEntityHandlerResult entityHandler(
256             std::shared_ptr< OC::OCResourceRequest > request, requestType type)
257     {
258         if (!request)
259         {
260             return OC_EH_ERROR;
261         }
262
263         std::cout << "Provider : Income request : " << request->getRequestHandlerFlag() << std::endl;
264         if ((request->getRequestHandlerFlag() & OC::RequestHandlerFlag::ObserverFlag))
265         {
266             std::cout << "Provider : Income Observe : " << std::endl;
267             setObserver(request, type);
268             return OC_EH_OK;
269         }
270
271         auto pResponse = getResponse(request, type);
272         if (pResponse == nullptr)
273         {
274             return OC_EH_ERROR;
275         }
276
277         try
278         {
279             OC::OCPlatform::sendResponse(pResponse);
280         }
281         catch (std::exception & e)
282         {
283             return OC_EH_ERROR;
284         }
285
286         return OC_EH_OK;
287     }
288
289 public:
290
291     void setAccepter(int accepter)
292     {
293         m_accepter = accepter;
294     }
295
296     void notifyMessage()
297     {
298         std::cout << "Provider : notify~" << std::endl;
299         OC::OCPlatform::notifyAllObservers(m_messageHandle);
300     }
301
302     void notifyMessage(const uint64_t & id, const std::string & title, const std::string & content)
303     {
304         setMessage(id, title, content);
305         notifyMessage();
306     }
307
308     void sendRead(const uint64_t & id)
309     {
310         std::string providerId = "123456789012345678901234567890123456";
311         m_syncRep.setValue<int>("x.org.iotivity.ns.messageid", id);
312         m_syncRep.setValue("x.org.iotivity.ns.state", (int)1);
313         m_syncRep.setValue("x.org.iotivity.ns.providerid", providerId);
314         OC::OCPlatform::notifyAllObservers(m_syncHandle);
315     }
316     void sendDismiss(const uint64_t & id)
317     {
318         std::string providerId = "123456789012345678901234567890123456";
319         m_syncRep.setValue<int>("x.org.iotivity.ns.messageid", id);
320         m_syncRep.setValue("x.org.iotivity.ns.state", (int)2);
321         m_syncRep.setValue("x.org.iotivity.ns.providerid", providerId);
322         OC::OCPlatform::notifyAllObservers(m_syncHandle);
323     }
324
325     void setMessage(const uint64_t & id, const std::string & title, const std::string & content)
326     {
327         std::string providerId = "123456789012345678901234567890123456";
328         m_messageRep.setValue<int>("x.org.iotivity.ns.messageid", id);
329         m_messageRep.setValue<std::string>("x.org.iotivity.ns.title", title);
330         m_messageRep.setValue<std::string>("x.org.iotivity.ns.contenttext", content);
331         m_messageRep.setValue<std::string>("x.org.iotivity.ns.providerid", providerId);
332     }
333
334     void setTopics(const NS_TopicList & topics)
335     {
336         bool isChanged = false;
337         std::for_each (topics.begin(), topics.end(),
338             [this, & isChanged](const std::string & topic)
339             {
340                 auto found = std::find(
341                         this->m_topicList.begin(), this->m_topicList.end(), topic);
342                 if (found == this->m_topicList.end())
343                 {
344                     this->m_topicList.push_back(topic);
345                     isChanged = true;
346                 }
347             });
348
349         if (isChanged)
350         {
351             this->notifyMessage((uint64_t)messageType::NS_TOPIC, "", "");
352         }
353     }
354
355     NS_TopicList getTopics() const
356     {
357         return m_topicList;
358     }
359
360     void updateTopicState(const NS_TopicStateList & allowedTopics)
361     {
362         std::for_each (allowedTopics.begin(), allowedTopics.end(),
363             [this](const NS_TopicState & allowedTopic)
364             {
365                 auto found = this->m_allowedTopicList.find(allowedTopic.first);
366                 if (found != this->m_allowedTopicList.end())
367                 {
368                     found->second = allowedTopic.second;
369                 }
370             });
371     }
372
373     NS_TopicStateList getTopicAllowState() const
374     {
375         return m_allowedTopicList;
376     }
377
378     void deleteNotificationResource()
379     {
380         OC::OCPlatform::unregisterResource(m_notificationHandle);
381         OC::OCPlatform::unregisterResource(m_messageHandle);
382         OC::OCPlatform::unregisterResource(m_syncHandle);
383         OC::OCPlatform::unregisterResource(m_topicHandle);
384         m_allowedTopicList.clear();
385         m_topicList.clear();
386     }
387
388     void createNotificationResource()
389     {
390         createNotificationResource(m_notificationUri);
391     }
392
393     void createNotificationResource(const std::string & uri)
394     {
395         if (m_notificationUri != uri)
396         {
397             m_notificationUri = uri;
398         }
399
400         OC::OCPlatform::startPresence(30);
401
402         std::string notificationUri = m_notificationUri;
403         std::string resourceTypeName = "x.org.iotivity.notification.topic";
404         std::string resourceInterface = OC::DEFAULT_INTERFACE;
405
406         uint8_t resourceProperty = OC_OBSERVABLE;
407         std::string childUri = uri + m_topicUri;
408         try
409         {
410             OC::OCPlatform::registerResource(
411                     m_topicHandle, childUri,
412                     resourceTypeName, resourceInterface,
413                     std::bind(& NSProviderSimulator::entityHandler, this,
414                             std::placeholders::_1, requestType::NS_TOPIC),
415                             resourceProperty);
416         }
417         catch(std::exception & e)
418         {
419             std::cout << e.what() << std::endl;
420         }
421
422         //resourceProperty |= OC_OBSERVABLE;
423         resourceTypeName = "x.org.iotivity.notification.message";
424         childUri = uri + m_messageUri;
425         try
426         {
427             OC::OCPlatform::registerResource(
428                     m_messageHandle, childUri,
429                     resourceTypeName, resourceInterface,
430                     std::bind(& NSProviderSimulator::entityHandler, this,
431                             std::placeholders::_1, requestType::NS_MESSAGE),
432                             resourceProperty);
433         }
434         catch (std::exception & e)
435         {
436             std::cout << e.what() << std::endl;
437         }
438
439         resourceTypeName = "x.org.iotivity.notification.sync";
440         childUri = uri + m_syncUri;
441         try
442         {
443             OC::OCPlatform::registerResource(
444                     m_syncHandle, childUri,
445                     resourceTypeName, resourceInterface,
446                     std::bind(& NSProviderSimulator::entityHandler, this,
447                             std::placeholders::_1, requestType::NS_SYNC),
448                             resourceProperty);
449         }
450         catch (std::exception & e)
451         {
452             std::cout << e.what() << std::endl;
453         }
454
455         resourceProperty |= OC_DISCOVERABLE;
456         resourceTypeName = "x.org.iotivity.notification";
457         try
458         {
459             OC::OCPlatform::registerResource(
460                     m_notificationHandle, notificationUri,
461                     resourceTypeName, resourceInterface,
462                     std::bind(& NSProviderSimulator::entityHandler, this,
463                             std::placeholders::_1, requestType::NS_NOTIFICATION),
464                             resourceProperty);
465         }
466         catch (std::exception & e)
467         {
468             std::cout << e.what() << std::endl;
469         }
470     }
471 };
472
473 #endif /* _NS_PROVIDER_SIMULATOR_H_ */