RD client features in base layer
[platform/upstream/iotivity.git] / resource / src / OCPlatform_impl.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 //******************************************************************
22 // File name:
23 //     OCPlatform_impl.cpp
24 //
25 // Description: Implementation of the OCPlatform functionality.  It contains
26 // a singleton interface that is used only by the OCPlatform namespace and is the
27 // central entrance to the stack.
28 //
29 //
30 //
31 //*********************************************************************
32
33 #include "OCPlatform_impl.h"
34
35 #include <random>
36 #include <utility>
37 #include <functional>
38
39 #include "ocstack.h"
40
41 #include "OCPlatform.h"
42 #include "OCApi.h"
43 #include "OCException.h"
44 #include "OCUtilities.h"
45 #include "ocpayload.h"
46
47 #include "oc_logger.hpp"
48
49 namespace OC
50 {
51
52     PlatformConfig& OCPlatform_impl::globalConfig()
53     {
54         static PlatformConfig s_config;
55         return s_config;
56     }
57
58     void OCPlatform_impl::Configure(const PlatformConfig& config)
59     {
60         OCRegisterPersistentStorageHandler(config.ps);
61         globalConfig() = config;
62     }
63
64     OCPlatform_impl& OCPlatform_impl::Instance()
65     {
66         static OCPlatform_impl platform(globalConfig());
67         return platform;
68     }
69
70     void OCPlatform_impl::init(const PlatformConfig& config)
71     {
72         switch(config.mode)
73         {
74             case ModeType::Server:
75                 m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
76                 break;
77
78             case ModeType::Client:
79                 m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
80                 break;
81
82             case ModeType::Both:
83             case ModeType::Gateway:
84                 m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
85                 m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
86                 break;
87          }
88     }
89
90     OCPlatform_impl::OCPlatform_impl(const PlatformConfig& config)
91      : m_cfg             { config },
92        m_WrapperInstance { make_unique<WrapperFactory>() },
93        m_csdkLock        { std::make_shared<std::recursive_mutex>() }
94     {
95         init(m_cfg);
96     }
97
98     OCPlatform_impl::~OCPlatform_impl(void)
99     {
100     }
101
102     OCStackResult OCPlatform_impl::setDefaultDeviceEntityHandler(EntityHandler entityHandler)
103     {
104         return checked_guard(m_server, &IServerWrapper::setDefaultDeviceEntityHandler,
105                              entityHandler);
106     }
107
108     OCStackResult OCPlatform_impl::notifyAllObservers(OCResourceHandle resourceHandle,
109                                                 QualityOfService QoS)
110     {
111         return result_guard(OCNotifyAllObservers(resourceHandle,
112                     static_cast<OCQualityOfService>(QoS)));
113     }
114
115     OCStackResult OCPlatform_impl::notifyAllObservers(OCResourceHandle resourceHandle)
116     {
117         return notifyAllObservers(resourceHandle, m_cfg.QoS);
118     }
119
120     OCStackResult OCPlatform_impl::notifyListOfObservers(OCResourceHandle resourceHandle,
121                                        ObservationIds& observationIds,
122                                        const std::shared_ptr<OCResourceResponse> pResponse)
123     {
124         return notifyListOfObservers(resourceHandle, observationIds, pResponse, m_cfg.QoS);
125     }
126
127     OCStackResult OCPlatform_impl::notifyListOfObservers(OCResourceHandle resourceHandle,
128                                        ObservationIds& observationIds,
129                                        const std::shared_ptr<OCResourceResponse> pResponse,
130                                        QualityOfService QoS)
131     {
132         if(!pResponse)
133         {
134          return result_guard(OC_STACK_ERROR);
135         }
136
137         OCRepPayload* pl = pResponse->getResourceRepresentation().getPayload();
138         OCStackResult result =
139                    OCNotifyListOfObservers(resourceHandle,
140                             &observationIds[0], observationIds.size(),
141                             pl,
142                             static_cast<OCQualityOfService>(QoS));
143         OCRepPayloadDestroy(pl);
144         return result_guard(result);
145     }
146
147     OCResource::Ptr OCPlatform_impl::constructResourceObject(const std::string& host,
148                                                 const std::string& uri,
149                                                 OCConnectivityType connectivityType,
150                                                 bool isObservable,
151                                                 const std::vector<std::string>& resourceTypes,
152                                                 const std::vector<std::string>& interfaces)
153     {
154         if(!m_client)
155         {
156             return std::shared_ptr<OCResource>();
157         }
158
159         uint8_t resourceProperty = 0;
160         if (isObservable)
161         {
162             resourceProperty = (resourceProperty | OC_OBSERVABLE);
163         }
164         return std::shared_ptr<OCResource>(new OCResource(m_client,
165                                             host,
166                                             uri, "", connectivityType,
167                                             resourceProperty,
168                                             resourceTypes,
169                                             interfaces));
170     }
171
172     OCStackResult OCPlatform_impl::findResource(const std::string& host,
173                                             const std::string& resourceName,
174                                             OCConnectivityType connectivityType,
175                                             FindCallback resourceHandler)
176     {
177         return findResource(host, resourceName, connectivityType, resourceHandler, m_cfg.QoS);
178     }
179
180     OCStackResult OCPlatform_impl::findResource(const std::string& host,
181                                             const std::string& resourceName,
182                                             OCConnectivityType connectivityType,
183                                             FindCallback resourceHandler,
184                                             QualityOfService QoS)
185     {
186         return checked_guard(m_client, &IClientWrapper::ListenForResource,
187                              host, resourceName, connectivityType, resourceHandler, QoS);
188     }
189
190     OCStackResult OCPlatform_impl::findResource(const std::string& host,
191                                             const std::string& resourceName,
192                                             OCConnectivityType connectivityType,
193                                             FindCallback resourceHandler,
194                                             FindErrorCallback errorHandler)
195     {
196         return findResource(host, resourceName, connectivityType, resourceHandler,
197                             errorHandler, m_cfg.QoS);
198     }
199
200     OCStackResult OCPlatform_impl::findResource(const std::string& host,
201                                             const std::string& resourceName,
202                                             OCConnectivityType connectivityType,
203                                             FindCallback resourceHandler,
204                                             FindErrorCallback errorHandler,
205                                             QualityOfService QoS)
206     {
207         return checked_guard(m_client, &IClientWrapper::ListenErrorForResource,
208                              host, resourceName, connectivityType, resourceHandler,
209                              errorHandler, QoS);
210     }
211
212     OCStackResult OCPlatform_impl::getDeviceInfo(const std::string& host,
213                                             const std::string& deviceURI,
214                                             OCConnectivityType connectivityType,
215                                             FindDeviceCallback deviceInfoHandler)
216     {
217         return result_guard(getDeviceInfo(host, deviceURI, connectivityType,
218                deviceInfoHandler, m_cfg.QoS));
219     }
220
221     OCStackResult OCPlatform_impl::getDeviceInfo(const std::string& host,
222                                             const std::string& deviceURI,
223                                             OCConnectivityType connectivityType,
224                                             FindDeviceCallback deviceInfoHandler,
225                                             QualityOfService QoS)
226     {
227         return checked_guard(m_client, &IClientWrapper::ListenForDevice,
228                              host, deviceURI, connectivityType, deviceInfoHandler, QoS);
229     }
230
231     OCStackResult OCPlatform_impl::getPlatformInfo(const std::string& host,
232                                             const std::string& platformURI,
233                                             OCConnectivityType connectivityType,
234                                             FindPlatformCallback platformInfoHandler)
235     {
236         return result_guard(getPlatformInfo(host, platformURI, connectivityType,
237                platformInfoHandler, m_cfg.QoS));
238     }
239
240     OCStackResult OCPlatform_impl::getPlatformInfo(const std::string& host,
241                                             const std::string& platformURI,
242                                             OCConnectivityType connectivityType,
243                                             FindPlatformCallback platformInfoHandler,
244                                             QualityOfService QoS)
245     {
246         return checked_guard(m_client, &IClientWrapper::ListenForDevice,
247                              host, platformURI, connectivityType, platformInfoHandler, QoS);
248     }
249
250     OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
251                                             std::string& resourceURI,
252                                             const std::string& resourceTypeName,
253                                             const std::string& resourceInterface,
254                                             EntityHandler entityHandler,
255                                             uint8_t resourceProperty)
256     {
257         return checked_guard(m_server, &IServerWrapper::registerResource,
258                              std::ref(resourceHandle), resourceURI, resourceTypeName,
259                              resourceInterface, entityHandler, resourceProperty);
260     }
261
262     OCStackResult OCPlatform_impl::registerDeviceInfo(const OCDeviceInfo deviceInfo)
263     {
264         return checked_guard(m_server, &IServerWrapper::registerDeviceInfo, deviceInfo);
265     }
266
267     OCStackResult OCPlatform_impl::registerPlatformInfo(const OCPlatformInfo platformInfo)
268     {
269         return checked_guard(m_server, &IServerWrapper::registerPlatformInfo, platformInfo);
270     }
271
272     OCStackResult OCPlatform_impl::registerResource(OCResourceHandle& resourceHandle,
273                                             const std::shared_ptr< OCResource > resource)
274     {
275         uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
276         std::vector<std::string> resourceTypes = resource->getResourceTypes();
277
278         return checked_guard(m_server, &IServerWrapper::registerResource,
279                 std::ref(resourceHandle), resource->host() + resource->uri(),
280                 resourceTypes[0]/*"core.remote"*/, DEFAULT_INTERFACE,
281                 (EntityHandler) nullptr, resourceProperty);
282     }
283
284     OCStackResult OCPlatform_impl::unregisterResource(const OCResourceHandle& resourceHandle) const
285     {
286         return checked_guard(m_server, &IServerWrapper::unregisterResource,
287                              resourceHandle);
288     }
289
290     OCStackResult OCPlatform_impl::unbindResource(OCResourceHandle collectionHandle,
291                                             OCResourceHandle resourceHandle)
292     {
293         return result_guard(OCUnBindResource(std::ref(collectionHandle), std::ref(resourceHandle)));
294     }
295
296     OCStackResult OCPlatform_impl::unbindResources(const OCResourceHandle collectionHandle,
297                                             const std::vector<OCResourceHandle>& resourceHandles)
298     {
299         for(const auto& h : resourceHandles)
300         {
301            OCStackResult r;
302
303            if(OC_STACK_OK != (r = result_guard(OCUnBindResource(collectionHandle, h))))
304            {
305                return r;
306            }
307         }
308
309         return OC_STACK_OK;
310     }
311
312     OCStackResult OCPlatform_impl::bindResource(const OCResourceHandle collectionHandle,
313                                             const OCResourceHandle resourceHandle)
314     {
315         return result_guard(OCBindResource(collectionHandle, resourceHandle));
316     }
317
318     OCStackResult OCPlatform_impl::bindResources(const OCResourceHandle collectionHandle,
319                                             const std::vector<OCResourceHandle>& resourceHandles)
320     {
321         for(const auto& h : resourceHandles)
322         {
323            OCStackResult r;
324
325            if(OC_STACK_OK != (r = result_guard(OCBindResource(collectionHandle, h))))
326            {
327                return r;
328            }
329         }
330
331         return OC_STACK_OK;
332     }
333
334     OCStackResult OCPlatform_impl::bindTypeToResource(const OCResourceHandle& resourceHandle,
335                                              const std::string& resourceTypeName) const
336     {
337         return checked_guard(m_server, &IServerWrapper::bindTypeToResource,
338                              resourceHandle, resourceTypeName);
339     }
340
341     OCStackResult OCPlatform_impl::bindInterfaceToResource(const OCResourceHandle& resourceHandle,
342                                              const std::string& resourceInterfaceName) const
343     {
344         return checked_guard(m_server, &IServerWrapper::bindInterfaceToResource,
345                              resourceHandle, resourceInterfaceName);
346     }
347
348     OCStackResult OCPlatform_impl::startPresence(const unsigned int announceDurationSeconds)
349     {
350         return checked_guard(m_server, &IServerWrapper::startPresence,
351                              announceDurationSeconds);
352     }
353
354     OCStackResult OCPlatform_impl::stopPresence()
355     {
356         return checked_guard(m_server, &IServerWrapper::stopPresence);
357     }
358
359     OCStackResult OCPlatform_impl::subscribePresence(OCPresenceHandle& presenceHandle,
360                                             const std::string& host,
361                                             OCConnectivityType connectivityType,
362                                             SubscribeCallback presenceHandler)
363     {
364         return subscribePresence(presenceHandle, host, "", connectivityType, presenceHandler);
365     }
366
367
368     OCStackResult OCPlatform_impl::subscribePresence(OCPresenceHandle& presenceHandle,
369                                             const std::string& host,
370                                             const std::string& resourceType,
371                                             OCConnectivityType connectivityType,
372                                             SubscribeCallback presenceHandler)
373     {
374         return checked_guard(m_client, &IClientWrapper::SubscribePresence,
375                              &presenceHandle, host, resourceType, connectivityType,
376                              presenceHandler);
377     }
378
379     OCStackResult OCPlatform_impl::unsubscribePresence(OCPresenceHandle presenceHandle)
380     {
381         return checked_guard(m_client, &IClientWrapper::UnsubscribePresence,
382                              std::ref(presenceHandle));
383     }
384
385 #ifdef WITH_CLOUD
386     OCStackResult OCPlatform_impl::subscribeDevicePresence(OCPresenceHandle& presenceHandle,
387                                                            const std::string& host,
388                                                            const QueryParamsList& queryParams,
389                                                            OCConnectivityType connectivityType,
390                                                            ObserveCallback callback)
391     {
392         return checked_guard(m_client, &IClientWrapper::SubscribeDevicePresence,
393                              &presenceHandle, host, queryParams, connectivityType, callback);
394     }
395 #endif
396
397     OCStackResult OCPlatform_impl::sendResponse(const std::shared_ptr<OCResourceResponse> pResponse)
398     {
399         return checked_guard(m_server, &IServerWrapper::sendResponse,
400                              pResponse);
401     }
402 #ifdef RD_CLIENT
403     OCStackResult OCPlatform_impl::publishResourceToRD(const std::string& host,
404                                                        OCConnectivityType connectivityType,
405                                                        ResourceHandles& resourceHandles,
406                                                        PublishResourceCallback callback)
407     {
408         return publishResourceToRD(host, connectivityType, resourceHandles,
409                                    callback, m_cfg.QoS);
410     }
411
412     OCStackResult OCPlatform_impl::publishResourceToRD(const std::string& host,
413                                                        OCConnectivityType connectivityType,
414                                                        ResourceHandles& resourceHandles,
415                                                        PublishResourceCallback callback,
416                                                        QualityOfService qos)
417     {
418         return checked_guard(m_server, &IServerWrapper::publishResourceToRD,
419                              host, connectivityType, resourceHandles, callback,
420                              static_cast<OCQualityOfService>(qos));
421     }
422
423     OCStackResult OCPlatform_impl::deleteResourceFromRD(const std::string& host,
424                                                         OCConnectivityType connectivityType,
425                                                         ResourceHandles& resourceHandles,
426                                                         DeleteResourceCallback callback)
427     {
428         return deleteResourceFromRD(host, connectivityType, resourceHandles, callback,
429                                     m_cfg.QoS);
430     }
431
432     OCStackResult OCPlatform_impl::deleteResourceFromRD(const std::string& host,
433                                                         OCConnectivityType connectivityType,
434                                                         ResourceHandles& resourceHandles,
435                                                         DeleteResourceCallback callback,
436                                                         QualityOfService qos)
437     {
438         return checked_guard(m_server, &IServerWrapper::deleteResourceFromRD,
439                              host, connectivityType, resourceHandles, callback,
440                              static_cast<OCQualityOfService>(qos));
441     }
442 #endif
443     std::weak_ptr<std::recursive_mutex> OCPlatform_impl::csdkLock()
444     {
445         return m_csdkLock;
446     }
447
448     OCStackResult OCPlatform_impl::findDirectPairingDevices(unsigned short waittime,
449                              GetDirectPairedCallback directPairingHandler)
450     {
451         return checked_guard(m_client, &IClientWrapper::FindDirectPairingDevices,
452                              waittime, directPairingHandler);
453
454     }
455
456     OCStackResult OCPlatform_impl::getDirectPairedDevices(
457                              GetDirectPairedCallback directPairingHandler)
458     {
459
460         return checked_guard(m_client, &IClientWrapper::GetDirectPairedDevices,
461                              directPairingHandler);
462     }
463
464     OCStackResult OCPlatform_impl::doDirectPairing(std::shared_ptr<OCDirectPairing> peer,
465                              OCPrm_t pmSel,
466                              const std::string& pinNumber,
467                              DirectPairingCallback resultCallback)
468     {
469         return checked_guard(m_client, &IClientWrapper::DoDirectPairing,
470                              peer, pmSel, pinNumber, resultCallback);
471     }
472 #ifdef WITH_CLOUD
473     OCStackResult OCPlatform_impl::signUp(const std::string& host,
474                                           const std::string& authProvider,
475                                           const std::string& authCode,
476                                           OCConnectivityType connectivityType,
477                                           PostCallback cloudConnectHandler)
478     {
479         const char* di = OCGetServerInstanceIDString();
480         if (!di)
481         {
482             oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
483             return result_guard(OC_STACK_ERROR);
484         }
485         std::string deviceId(di);
486
487         OCRepresentation rep;
488         rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
489         rep.setValue(OC_RSRVD_AUTHPROVIDER, authProvider);
490         rep.setValue(OC_RSRVD_AUTHCODE, authCode);
491
492         std::string uri = host + OC_RSRVD_ACCOUNT_URI;
493
494         OCDevAddr devAddr;
495         QueryParamsMap queryParams;
496         HeaderOptions headerOptions;
497
498         QualityOfService defaultQos = OC::QualityOfService::NaQos;
499         checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
500
501         return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
502                              devAddr, uri, rep, queryParams, headerOptions,
503                              connectivityType, cloudConnectHandler, defaultQos);
504     }
505
506     OCStackResult OCPlatform_impl::signIn(const std::string& host,
507                                           const std::string& accessToken,
508                                           OCConnectivityType connectivityType,
509                                           PostCallback cloudConnectHandler)
510     {
511         return signInOut(host, accessToken, true, connectivityType, cloudConnectHandler);
512     }
513
514     OCStackResult OCPlatform_impl::signOut(const std::string& host,
515                                            const std::string& accessToken,
516                                            OCConnectivityType connectivityType,
517                                            PostCallback cloudConnectHandler)
518     {
519         return signInOut(host, accessToken, false, connectivityType, cloudConnectHandler);
520     }
521
522     OCStackResult OCPlatform_impl::signInOut(const std::string& host,
523                                              const std::string& accessToken,
524                                              bool isSignIn,
525                                              OCConnectivityType connectivityType,
526                                              PostCallback cloudConnectHandler)
527     {
528         const char* di = OCGetServerInstanceIDString();
529         if (!di)
530         {
531             oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
532             return result_guard(OC_STACK_ERROR);
533         }
534         std::string deviceId(di);
535
536         OCRepresentation rep;
537         rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
538         rep.setValue(OC_RSRVD_ACCESS_TOKEN, accessToken);
539         rep.setValue(OC_RSRVD_STATUS, isSignIn);
540
541         std::string uri = host + OC_RSRVD_ACCOUNT_SESSION_URI;
542
543         OCDevAddr devAddr;
544         QueryParamsMap queryParams;
545         HeaderOptions headerOptions;
546
547         QualityOfService defaultQos = OC::QualityOfService::NaQos;
548         checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
549
550         return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
551                              devAddr, uri, rep, queryParams, headerOptions,
552                              connectivityType, cloudConnectHandler, defaultQos);
553     }
554
555     OCStackResult OCPlatform_impl::refreshAccessToken(const std::string& host,
556                                                       const std::string& refreshToken,
557                                                       OCConnectivityType connectivityType,
558                                                       PostCallback cloudConnectHandler)
559     {
560         const char* di = OCGetServerInstanceIDString();
561         if (!di)
562         {
563             oclog() << "The mode should be Server or Both to generate UUID" << std::flush;
564             return result_guard(OC_STACK_ERROR);
565         }
566         std::string deviceId(di);
567
568         OCRepresentation rep;
569         rep.setValue(OC_RSRVD_DEVICE_ID, deviceId);
570         rep.setValue(OC_RSRVD_REFRESH_TOKEN, refreshToken);
571         rep.setValue(OC_RSRVD_GRANT_TYPE, OC_RSRVD_GRANT_TYPE_REFRESH_TOKEN);
572
573         std::string uri = host + OC_RSRVD_ACCOUNT_TOKEN_REFRESH_URI;
574
575         OCDevAddr devAddr;
576         QueryParamsMap queryParams;
577         HeaderOptions headerOptions;
578
579         QualityOfService defaultQos = OC::QualityOfService::NaQos;
580         checked_guard(m_client, &IClientWrapper::GetDefaultQos, defaultQos);
581
582         return checked_guard(m_client, &IClientWrapper::PostResourceRepresentation,
583                              devAddr, uri, rep, queryParams, headerOptions,
584                              connectivityType, cloudConnectHandler, defaultQos);
585     }
586 #endif // WITH_CLOUD
587 } //namespace OC
588