provisioning: Rename some C++ headers to avoid collision with CSDK ones
[platform/upstream/iotivity.git] / resource / provisioning / src / OCProvisioningManager.cpp
1 /* *****************************************************************
2  *
3  * Copyright 2015 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 #include "ocstack.h"
22 #include "srmutility.h"
23 #include "base64.h"
24 #include "OCProvisioningManager.hpp"
25
26 namespace OC
27 {
28     OCStackResult OCSecure::provisionInit(const std::string& dbPath)
29     {
30         OCStackResult result;
31         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
32
33         if (cLock)
34         {
35             std::lock_guard<std::recursive_mutex> lock(*cLock);
36             result = OCInitPM(dbPath.c_str());
37         }
38         else
39         {
40             oclog() <<"Mutex not found";
41             result = OC_STACK_ERROR;
42         }
43
44         return result;
45     }
46
47     OCStackResult OCSecure::discoverUnownedDevices(unsigned short timeout,
48             DeviceList_t &list)
49     {
50         OCStackResult result;
51         OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
52         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
53         auto cLock = csdkLock.lock();
54
55         if (cLock)
56         {
57             std::lock_guard<std::recursive_mutex> lock(*cLock);
58             result = OCDiscoverUnownedDevices(timeout, &pDevList);
59             if (result == OC_STACK_OK)
60             {
61                 // Create DeviceList of OCSecureResource's
62                 pCurDev = pDevList;
63                 while (pCurDev)
64                 {
65                     tmp = pCurDev;
66                     list.push_back(std::shared_ptr<OCSecureResource>(
67                                 new OCSecureResource(csdkLock, pCurDev)));
68                     pCurDev = pCurDev->next;
69                     tmp->next = nullptr;
70                 }
71             }
72             else
73             {
74                 oclog() <<"Unowned device discovery failed!";
75             }
76         }
77         else
78         {
79             oclog() <<"Mutex not found";
80             result = OC_STACK_ERROR;
81         }
82
83         return result;
84     }
85
86     OCStackResult OCSecure::discoverOwnedDevices(unsigned short timeout,
87             DeviceList_t &list)
88     {
89         OCStackResult result;
90         OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
91         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
92         auto cLock = csdkLock.lock();
93
94         if (cLock)
95         {
96             std::lock_guard<std::recursive_mutex> lock(*cLock);
97             result = OCDiscoverOwnedDevices(timeout, &pDevList);
98             if (result == OC_STACK_OK)
99             {
100                 pCurDev = pDevList;
101                 while (pCurDev)
102                 {
103                     tmp = pCurDev;
104                     list.push_back(std::shared_ptr<OCSecureResource>(
105                                 new OCSecureResource(csdkLock, pCurDev)));
106                     pCurDev = pCurDev->next;
107                     tmp->next = nullptr;
108                 }
109             }
110             else
111             {
112                 oclog() <<"Owned device discovery failed!";
113             }
114         }
115         else
116         {
117             oclog() <<"Mutex not found";
118             result = OC_STACK_ERROR;
119         }
120
121         return result;
122     }
123
124     OCStackResult OCSecure::discoverSingleDevice(unsigned short timeout,
125             const OicUuid_t* deviceID,
126             std::shared_ptr<OCSecureResource> &foundDevice)
127     {
128         OCStackResult result;
129         OCProvisionDev_t *pDev = nullptr;
130         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
131         auto cLock = csdkLock.lock();
132
133         if (cLock)
134         {
135             std::lock_guard<std::recursive_mutex> lock(*cLock);
136             result = OCDiscoverSingleDevice(timeout, deviceID, &pDev);
137             if (result == OC_STACK_OK)
138             {
139                 if (pDev)
140                 {
141                     foundDevice.reset(new OCSecureResource(csdkLock, pDev));
142                 }
143                 else
144                 {
145                     oclog() <<"Not found Secure resource!";
146                     foundDevice.reset();
147                 }
148             }
149             else
150             {
151                 oclog() <<"Secure resource discovery failed!";
152             }
153         }
154         else
155         {
156             oclog() <<"Mutex not found";
157             result = OC_STACK_ERROR;
158         }
159
160         return result;
161     }
162
163     OCStackResult OCSecure::setOwnerTransferCallbackData(OicSecOxm_t oxm,
164             OTMCallbackData_t* callbackData, InputPinCallback inputPin)
165     {
166         if (NULL == callbackData || oxm >= OIC_OXM_COUNT)
167         {
168             oclog() <<"Invalid callbackData or OXM type";
169             return OC_STACK_INVALID_PARAM;
170         }
171
172         if ((OIC_RANDOM_DEVICE_PIN == oxm) && !inputPin)
173         {
174             oclog() <<"for OXM type DEVICE_PIN, inputPin callback can't be null";
175             return OC_STACK_INVALID_PARAM;
176         }
177
178         OCStackResult result;
179         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
180
181         if (cLock)
182         {
183             std::lock_guard<std::recursive_mutex> lock(*cLock);
184             result = OCSetOwnerTransferCallbackData(oxm, callbackData);
185             if (result == OC_STACK_OK && (OIC_RANDOM_DEVICE_PIN == oxm))
186             {
187                 SetInputPinCB(inputPin);
188             }
189         }
190         else
191         {
192             oclog() <<"Mutex not found";
193             result = OC_STACK_ERROR;
194         }
195
196         return result;
197
198     }
199
200     OCStackResult OCSecure::getDevInfoFromNetwork(unsigned short timeout,
201             DeviceList_t &ownedDevList,
202             DeviceList_t &unownedDevList)
203     {
204         OCStackResult result = OC_STACK_OK;
205         OCProvisionDev_t *owned = nullptr, *unowned = nullptr, *tmp = nullptr, *dev = nullptr;
206         auto csdkLock = OCPlatform_impl::Instance().csdkLock();
207         auto cLock = csdkLock.lock();
208
209         if (cLock)
210         {
211             std::lock_guard<std::recursive_mutex> lock(*cLock);
212
213             result = OCGetDevInfoFromNetwork(timeout, &owned, &unowned);
214
215             if (result == OC_STACK_OK)
216             {
217                 dev = owned;
218                 while (dev)
219                 {
220                     tmp = dev;
221                     ownedDevList.push_back(std::shared_ptr<OCSecureResource>(
222                                 new OCSecureResource(csdkLock, dev)));
223                     dev = dev->next;
224                     tmp->next = nullptr;
225                 }
226
227                 dev = unowned;
228                 while (dev)
229                 {
230                     tmp = dev;
231                     unownedDevList.push_back(std::shared_ptr<OCSecureResource>(
232                                 new OCSecureResource(csdkLock,  dev)));
233                     dev = dev->next;
234                     tmp->next = nullptr;
235                 }
236             }
237         }
238         else
239         {
240             oclog() <<"Mutex not found";
241             result = OC_STACK_ERROR;
242         }
243
244         return result;
245     }
246
247     OCStackResult OCSecure::setDisplayPinCB(GeneratePinCallback displayPin)
248     {
249         if (!displayPin)
250         {
251             oclog() <<"displayPin can't be null";
252             return OC_STACK_INVALID_PARAM;
253         }
254
255         OCStackResult result = OC_STACK_OK;
256         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
257
258         if (cLock)
259         {
260             std::lock_guard<std::recursive_mutex> lock(*cLock);
261             SetGeneratePinCB(displayPin);
262         }
263         else
264         {
265             oclog() <<"Mutex not found";
266             result = OC_STACK_ERROR;
267         }
268
269         return result;
270     }
271
272     OCStackResult OCSecure::removeDeviceWithUuid(unsigned short waitTimeForOwnedDeviceDiscovery,
273             std::string uuid,
274             ResultCallBack resultCallback)
275     {
276         if (!resultCallback)
277         {
278             oclog() << "Result calback can't be null";
279             return OC_STACK_INVALID_CALLBACK;
280         }
281
282         OCStackResult result;
283         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
284
285         if (cLock)
286         {
287             ProvisionContext* context = new ProvisionContext(resultCallback);
288
289             std::lock_guard<std::recursive_mutex> lock(*cLock);
290
291             OicUuid_t targetDev;
292             result = ConvertStrToUuid(uuid.c_str(), &targetDev);
293             if(OC_STACK_OK == result)
294             {
295                 result = OCRemoveDeviceWithUuid(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
296                         &targetDev, &OCSecureResource::callbackWrapper);
297             }
298             else
299             {
300                 oclog() <<"Can not convert struuid to uuid";
301             }
302         }
303         else
304         {
305             oclog() <<"Mutex not found";
306             result = OC_STACK_ERROR;
307         }
308         return result;
309     }
310
311     OCStackResult OCSecure::saveACL(const OicSecAcl_t* acl)
312     {
313         if (!acl)
314         {
315             oclog() <<"ACL can't be null";
316             return OC_STACK_INVALID_PARAM;
317         }
318
319         OCStackResult result;
320         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
321
322         if (cLock)
323         {
324             std::lock_guard<std::recursive_mutex> lock(*cLock);
325             result = OCSaveACL(const_cast<OicSecAcl_t*>(acl));
326         }
327         else
328         {
329             oclog() <<"Mutex not found";
330             result = OC_STACK_ERROR;
331         }
332         return result;
333     }
334
335 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
336     OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
337                                         OicEncodingType_t encodingType, uint16_t *credId)
338     {
339         if (!trustCertChain)
340         {
341             oclog() <<"trustCertChain can't be null";
342             return OC_STACK_INVALID_PARAM;
343         }
344         if (!credId)
345         {
346             oclog() <<"cred ID can not be null";
347             return OC_STACK_INVALID_PARAM;
348         }
349
350         OCStackResult result;
351         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
352
353         if (cLock)
354         {
355             std::lock_guard<std::recursive_mutex> lock(*cLock);
356             result = OCSaveTrustCertChain(trustCertChain, chainSize, encodingType, credId );
357         }
358         else
359         {
360             oclog() <<"Mutex not found";
361             result = OC_STACK_ERROR;
362         }
363         return result;
364     }
365
366     OCStackResult OCSecure::readTrustCertChain(uint16_t credId, uint8_t **trustCertChain,
367             size_t *chainSize)
368     {
369         OCStackResult result;
370         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
371
372         if (cLock)
373         {
374             std::lock_guard<std::recursive_mutex> lock(*cLock);
375             result = OCReadTrustCertChain(credId, trustCertChain, chainSize);
376         }
377         else
378         {
379             oclog() <<"Mutex not found";
380             result = OC_STACK_ERROR;
381         }
382         return result;
383     }
384
385     void OCSecure::certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain,
386             size_t chainSize)
387     {
388         TrustCertChainContext* context = static_cast<TrustCertChainContext*>(ctx);
389         uint8_t *certChain = new uint8_t[chainSize];
390         memcpy(certChain, trustCertChain, chainSize);
391         std::thread exec(context->callback, credId, certChain, chainSize);
392         exec.detach();
393         delete context;
394     }
395
396     OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
397     {
398         if (!callback)
399         {
400             oclog() <<"callback can not be null";
401             return OC_STACK_INVALID_CALLBACK;
402         }
403
404         OCStackResult result;
405         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
406
407         if (cLock)
408         {
409             TrustCertChainContext* context = new TrustCertChainContext(callback);
410             std::lock_guard<std::recursive_mutex> lock(*cLock);
411             result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
412                     &OCSecure::certCallbackWrapper);
413         }
414         else
415         {
416             oclog() <<"Mutex not found";
417             result = OC_STACK_ERROR;
418         }
419         return result;
420     }
421
422
423     OCStackResult OCSecure::removeTrustCertChangeNotifier()
424     {
425         OCStackResult result;
426         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
427
428         if (cLock)
429         {
430             std::lock_guard<std::recursive_mutex> lock(*cLock);
431             OCRemoveTrustCertChainNotifier();
432             result = OC_STACK_OK;
433         }
434         else
435         {
436             oclog() <<"Mutex not found";
437             result = OC_STACK_ERROR;
438         }
439         return result;
440     }
441 #endif // __WITH_DTLS__ || __WITH_TLS__
442
443     void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
444     {
445         PMResultList_t *results = nullptr;
446         ProvisionContext* context = static_cast<ProvisionContext*>(ctx);
447
448         try
449         {
450             results = new PMResultList_t;
451         }
452         catch (std::bad_alloc& e)
453         {
454             oclog() <<"Bad alloc exception";
455             return;
456         }
457
458         for (int i = 0; i < nOfRes; i++)
459         {
460             results->push_back(arr[i]);
461         }
462
463         std::thread exec(context->callback, results, hasError);
464         exec.detach();
465
466         delete context;
467     }
468
469     OCSecureResource::OCSecureResource(): m_csdkLock(std::weak_ptr<std::recursive_mutex>()),
470                                         devPtr(nullptr)
471     {
472     }
473
474     OCSecureResource::OCSecureResource(std::weak_ptr<std::recursive_mutex> csdkLock,
475             OCProvisionDev_t *dPtr)
476         :m_csdkLock(csdkLock), devPtr(dPtr)
477     {
478     }
479
480     OCSecureResource::~OCSecureResource()
481     {
482         if (devPtr)
483         {
484             OCDeleteDiscoveredDevices(devPtr);
485         }
486     }
487
488     OCStackResult OCSecureResource::doOwnershipTransfer(ResultCallBack resultCallback)
489     {
490         if (!resultCallback)
491         {
492             oclog() <<"Result callback can't be null";
493             return OC_STACK_INVALID_CALLBACK;
494         }
495
496         OCStackResult result;
497         auto cLock = m_csdkLock.lock();
498
499         if (cLock)
500         {
501             ProvisionContext* context = new ProvisionContext(resultCallback);
502
503             std::lock_guard<std::recursive_mutex> lock(*cLock);
504             result = OCDoOwnershipTransfer(static_cast<void*>(context),
505                     devPtr, &OCSecureResource::callbackWrapper);
506         }
507         else
508         {
509             oclog() <<"Mutex not found";
510             result = OC_STACK_ERROR;
511         }
512         return result;
513     }
514
515     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
516             ResultCallBack resultCallback)
517     {
518         if (!acl)
519         {
520             oclog() <<"ACL can't be null";
521             return OC_STACK_INVALID_PARAM;
522         }
523         if (!resultCallback)
524         {
525             oclog() <<"result callback can not be null";
526             return OC_STACK_INVALID_CALLBACK;
527         }
528
529         OCStackResult result;
530         auto cLock = m_csdkLock.lock();
531
532         if (cLock)
533         {
534             ProvisionContext* context = new ProvisionContext(resultCallback);
535
536             std::lock_guard<std::recursive_mutex> lock(*cLock);
537             result = OCProvisionACL(static_cast<void*>(context),
538                     devPtr, const_cast<OicSecAcl_t*>(acl),
539                     &OCSecureResource::callbackWrapper);
540         }
541         else
542         {
543             oclog() <<"Mutex not found";
544             result = OC_STACK_ERROR;
545         }
546         return result;
547     }
548
549     OCStackResult OCSecureResource::provisionCredentials(const Credential &cred,
550             const OCSecureResource &device2, ResultCallBack resultCallback)
551     {
552         if (!resultCallback)
553         {
554             oclog() << "Result calback can't be null";
555             return OC_STACK_INVALID_CALLBACK;
556         }
557
558         OCStackResult result;
559         auto cLock = m_csdkLock.lock();
560
561         if (cLock)
562         {
563             ProvisionContext* context = new ProvisionContext(resultCallback);
564
565             std::lock_guard<std::recursive_mutex> lock(*cLock);
566             result = OCProvisionCredentials(static_cast<void*>(context),
567                     cred.getCredentialType(),
568                     cred.getCredentialKeySize(),
569                     devPtr, device2.getDevPtr(),
570                     &OCSecureResource::callbackWrapper);
571         }
572         else
573         {
574             oclog() <<"Mutex not found";
575             result = OC_STACK_ERROR;
576         }
577         return result;
578     }
579
580     OCStackResult OCSecureResource::provisionPairwiseDevices(const Credential &cred,
581             const OicSecAcl_t* acl1, const OCSecureResource &device2, const OicSecAcl_t* acl2,
582             ResultCallBack resultCallback)
583     {
584         if (!resultCallback)
585         {
586             oclog() << "Result callback can not be null";
587             return OC_STACK_INVALID_CALLBACK;
588         }
589
590         OCStackResult result;
591         auto cLock = m_csdkLock.lock();
592
593         if (cLock)
594         {
595             ProvisionContext* context = new ProvisionContext(resultCallback);
596
597             std::lock_guard<std::recursive_mutex> lock(*cLock);
598             result = OCProvisionPairwiseDevices(static_cast<void*>(context),
599                     cred.getCredentialType(),
600                     cred.getCredentialKeySize(),
601                     devPtr, const_cast<OicSecAcl_t*>(acl1),
602                     device2.getDevPtr(), const_cast<OicSecAcl_t*>(acl2),
603                     &OCSecureResource::callbackWrapper);
604         }
605         else
606         {
607             oclog() <<"Mutex not found";
608             result = OC_STACK_ERROR;
609         }
610         return result;
611     }
612
613     OCStackResult OCSecureResource::unlinkDevices(const OCSecureResource &device2,
614             ResultCallBack resultCallback)
615     {
616         if (!resultCallback)
617         {
618             oclog() << "Result calback can't be null";
619             return OC_STACK_INVALID_CALLBACK;
620         }
621
622         OCStackResult result;
623         auto cLock = m_csdkLock.lock();
624
625         if (cLock)
626         {
627             ProvisionContext* context = new ProvisionContext(resultCallback);
628
629             std::lock_guard<std::recursive_mutex> lock(*cLock);
630
631             result = OCUnlinkDevices(static_cast<void*>(context),
632                     devPtr, device2.getDevPtr(), &OCSecureResource::callbackWrapper);
633         }
634         else
635         {
636             oclog() <<"Mutex not found";
637             result = OC_STACK_ERROR;
638         }
639         return result;
640     }
641
642     OCStackResult OCSecureResource::removeDevice(unsigned short waitTimeForOwnedDeviceDiscovery,
643             ResultCallBack resultCallback)
644     {
645         if (!resultCallback)
646         {
647             oclog() << "Result calback can't be null";
648             return OC_STACK_INVALID_CALLBACK;
649         }
650
651         OCStackResult result;
652         auto cLock = m_csdkLock.lock();
653
654         if (cLock)
655         {
656             ProvisionContext* context = new ProvisionContext(resultCallback);
657
658             std::lock_guard<std::recursive_mutex> lock(*cLock);
659
660             result = OCRemoveDevice(static_cast<void*>(context), waitTimeForOwnedDeviceDiscovery,
661                     devPtr, &OCSecureResource::callbackWrapper);
662         }
663         else
664         {
665             oclog() <<"Mutex not found";
666             result = OC_STACK_ERROR;
667         }
668         return result;
669     }
670
671     OCStackResult OCSecureResource::getLinkedDevices(UuidList_t &uuidList)
672     {
673         OCStackResult result;
674         size_t numOfDevices = -1;
675         auto devUuid = devPtr->doxm->deviceID;
676         auto cLock = m_csdkLock.lock();
677
678         if (cLock)
679         {
680             std::lock_guard<std::recursive_mutex> lock(*cLock);
681
682             OCUuidList_t* linkedDevs = nullptr, *tmp = nullptr;
683             result = OCGetLinkedStatus(&devUuid, &linkedDevs, &numOfDevices);
684             if (result == OC_STACK_OK)
685             {
686                 for (tmp = linkedDevs; tmp; tmp = tmp->next)
687                 {
688                     uuidList.push_back(tmp->dev);
689                 }
690                 OCDeleteUuidList(linkedDevs);
691             }
692         }
693         else
694         {
695             oclog() <<"Mutex not found";
696             result = OC_STACK_ERROR;
697         }
698         return result;
699     }
700
701     OCStackResult OCSecureResource::provisionDirectPairing( const OicSecPconf_t* pconf,
702             ResultCallBack resultCallback)
703     {
704         if (!pconf)
705         {
706             oclog() <<"PCONF can't be null";
707             return OC_STACK_INVALID_PARAM;
708         }
709         if (!resultCallback)
710         {
711             oclog() <<"result callback can not be null";
712             return OC_STACK_INVALID_CALLBACK;
713         }
714
715         OCStackResult result;
716         auto cLock = m_csdkLock.lock();
717
718         if (cLock)
719         {
720             ProvisionContext* context = new ProvisionContext(resultCallback);
721
722             std::lock_guard<std::recursive_mutex> lock(*cLock);
723             result = OCProvisionDirectPairing(static_cast<void*>(context),
724                     devPtr, const_cast<OicSecPconf_t*>(pconf),
725                     &OCSecureResource::callbackWrapper);
726         }
727         else
728         {
729             oclog() <<"Mutex not found";
730             result = OC_STACK_ERROR;
731         }
732         return result;
733     }
734
735 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
736     OCStackResult OCSecureResource::provisionTrustCertChain(OicSecCredType_t type, uint16_t credId,
737                     ResultCallBack resultCallback)
738     {
739         if (SIGNED_ASYMMETRIC_KEY != type)
740         {
741             oclog() <<"Invalid key type";
742             return OC_STACK_INVALID_PARAM;
743         }
744         if (!resultCallback)
745         {
746             oclog() <<"result callback can not be null";
747             return OC_STACK_INVALID_CALLBACK;
748         }
749
750         OCStackResult result;
751         auto cLock = m_csdkLock.lock();
752
753         if (cLock)
754         {
755             ProvisionContext* context = new ProvisionContext(resultCallback);
756
757             std::lock_guard<std::recursive_mutex> lock(*cLock);
758             result = OCProvisionTrustCertChain(static_cast<void*>(context),
759                     type, credId, devPtr,
760                     &OCSecureResource::callbackWrapper);
761         }
762         else
763         {
764             oclog() <<"Mutex not found";
765             result = OC_STACK_ERROR;
766         }
767         return result;
768     }
769 #endif // __WITH_DTLS__ or __WITH_TLS__
770
771     std::string OCSecureResource::getDeviceID()
772     {
773         std::ostringstream deviceId("");
774         char *devID = nullptr;
775
776         validateSecureResource();
777
778         if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
779         {
780             deviceId << devID;
781             free(devID);
782         }
783         else
784         {
785             oclog() <<"Can not convert uuid to struuid";
786         }
787         return deviceId.str();
788     }
789
790     OCProvisionDev_t* OCSecureResource::getDevPtr() const
791     {
792         return devPtr;
793     }
794
795     std::string OCSecureResource::getDevAddr()
796     {
797         validateSecureResource();
798         std::string ipAddr(devPtr->endpoint.addr);
799         return ipAddr;
800     }
801
802     int OCSecureResource::getDeviceStatus()
803     {
804         validateSecureResource();
805         return (int)devPtr->devStatus;
806     }
807
808     bool OCSecureResource::getOwnedStatus()
809     {
810         validateSecureResource();
811         return devPtr->doxm->owned;
812     }
813
814     void OCSecureResource::validateSecureResource()
815     {
816         if (!devPtr)
817         {
818             throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);
819         }
820     }
821 }