iotivity 0.9.0
[platform/upstream/iotivity.git] / service / things-manager / sdk / src / GroupSynchronization.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 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 /// @file    GroupSynchronization.cpp
22 /// @brief
23
24 #include "GroupSynchronization.h"
25
26 using namespace OC;
27
28 namespace OIC
29 {
30
31 GroupSynchronization* GroupSynchronization::groupSyncnstance = NULL;
32
33 GroupSynchronization* GroupSynchronization::getInstance()
34 {
35     if (groupSyncnstance == NULL)
36     {
37         groupSyncnstance = new GroupSynchronization();
38     }
39     return groupSyncnstance;
40 }
41
42 void GroupSynchronization::deleteInstance()
43 {
44     if (groupSyncnstance)
45     {
46         delete groupSyncnstance;
47         groupSyncnstance = NULL;
48     }
49 }
50
51 OCStackResult GroupSynchronization::findGroup(
52         std::vector< std::string > collectionResourceTypes, FindCallback callback)
53 {
54     cout << "GroupSynchronization::findGroup" << endl;
55
56     foundGroupResourceList.clear();
57
58     findCallback = callback;
59
60     for (unsigned int i = 0; i < collectionResourceTypes.size(); ++i)
61     {
62         std::string query = "coap://224.0.1.187/oc/core?rt=";
63         query.append(collectionResourceTypes.at(i));
64         cout << "GroupSynchronization::findGroup - " << query << endl;
65
66         OCPlatform::findResource("", query,
67                 std::bind(&GroupSynchronization::onFindGroup, this, std::placeholders::_1));
68     }
69
70     // thread to check if GroupSynchronization::onFoundGroup is called or not.
71     std::thread t(std::bind(&GroupSynchronization::checkFindGroup, this));
72     t.detach();
73
74     return OC_STACK_OK;
75 }
76
77 OCStackResult GroupSynchronization::createGroup(std::string collectionResourceType)
78 {
79     foundGroupResourceList.clear();
80
81     OCResourceHandle collectionResHandle = NULL;
82     OCResourceHandle groupSyncResHandle = NULL;
83
84     if (0 != collectionResourceType.length())
85     {
86         cout << "GroupSynchronization::createGroup - The created group is added." << endl;
87
88         OCStackResult result;
89
90         // creating master collection resource
91         std::string collectionUri = "/" + collectionResourceType;
92         int i;
93         while ((i = collectionUri.find(".")) != std::string::npos)
94         {
95             collectionUri.replace(i, 1, "/");
96         }
97         cout << "GroupSynchronization::createGroup : collection uri - " << collectionUri
98                 << ", type - " << collectionResourceType << endl;
99
100         std::string resourceInterface = DEFAULT_INTERFACE;
101
102         result = OCPlatform::registerResource(collectionResHandle, collectionUri,
103                 collectionResourceType, resourceInterface, NULL,
104                 OC_DISCOVERABLE | OC_OBSERVABLE);
105         if (result != OC_STACK_OK)
106         {
107             cout << "To register resource (" << collectionUri << ") was unsuccessful. result - "
108                     << result << endl;
109             goto Error;
110         }
111
112         OCPlatform::bindInterfaceToResource(collectionResHandle, GROUP_INTERFACE);
113         if (result != OC_STACK_OK)
114         {
115             cout << "To bind Interface (collection) was unsuccessful. result - " << result
116                     << endl;
117         }
118
119         collectionResourceHandleList[collectionResourceType] = collectionResHandle;
120
121         // creating master group sync resource
122         std::string groupSyncUri = collectionUri + "/groupsync";
123         std::string groupSyncResType = collectionResourceType + ".groupsync";
124
125 //        cout << "GroupSynchronization::createGroup : groupSync uri - " << groupSyncUri
126 //                << ", type - " << collectionResourceType << endl;
127
128         result = OCPlatform::registerResource(groupSyncResHandle, groupSyncUri,
129                 groupSyncResType, resourceInterface,
130                 std::bind(&GroupSynchronization::groupEntityHandler, this,
131                         std::placeholders::_1), OC_DISCOVERABLE | OC_OBSERVABLE);
132         if (result != OC_STACK_OK)
133         {
134             cout << "To register resource (groupsync) was unsuccessful. result - " << result
135                     << endl;
136             goto Error;
137         }
138
139         groupSyncResourceHandleList[collectionResourceType] = groupSyncResHandle;
140
141         return OC_STACK_OK;
142     }
143     else
144     {
145         cout << "GroupSynchronization::createGroup : Error! Input params are wrong." << endl;
146         return OC_STACK_INVALID_PARAM;
147     }
148
149     Error:
150
151     if (collectionResHandle)
152     {
153         OCPlatform::unregisterResource(collectionResHandle);
154         auto iterator = collectionResourceHandleList.find(collectionResourceType);
155         if (iterator != collectionResourceHandleList.end())
156         {
157             collectionResourceHandleList.erase(iterator);
158         }
159     }
160
161     if (groupSyncResHandle)
162     {
163         OCPlatform::unregisterResource(groupSyncResHandle);
164         auto iterator = groupSyncResourceHandleList.find(collectionResourceType);
165         if (iterator != groupSyncResourceHandleList.end())
166         {
167             groupSyncResourceHandleList.erase(iterator);
168         }
169     }
170
171     return OC_STACK_NO_RESOURCE;
172 }
173
174 OCStackResult GroupSynchronization::joinGroup(std::string collectionResourceType,
175         OCResourceHandle resourceHandle)
176 {
177     if ((0 != collectionResourceType.length()) && (resourceHandle))
178     {
179         auto resIt = collectionResourceHandleList.find(collectionResourceType);
180         if (resIt == groupSyncResourceHandleList.end())
181         {
182             cout << "GroupSynchronization::joinGroup : error! There is no collection to join"
183                     << endl;
184             return OC_STACK_INVALID_PARAM;
185         }
186
187         OCResourceHandle collectionResHandle = resIt->second;
188
189         OCStackResult result = OCPlatform::bindResource(collectionResHandle, resourceHandle);
190         if (result != OC_STACK_OK)
191         {
192             cout << "GroupSynchronization::joinGroup : To bind resource was unsuccessful."
193                     << "result - " << result << endl;
194             return OC_STACK_ERROR;
195         }
196         cout << "GroupSynchronization::joinGroup : "
197                 << "To bind collectionResHandle and resourceHandle" << endl;
198
199         std::vector< OCResourceHandle > childHandleList;
200
201         auto childIt = childResourceHandleList.find(collectionResHandle);
202         if (childIt != childResourceHandleList.end())
203         {
204             childHandleList = childIt->second;
205         }
206
207         childHandleList.push_back(resourceHandle);
208         childResourceHandleList[collectionResHandle] = childHandleList;
209
210         deviceResourceHandleList.push_back(resourceHandle);
211
212         debugGroupSync();
213     }
214     else
215     {
216         cout << "GroupSynchronization::joinGroup : Error! input params are wrong." << endl;
217         return OC_STACK_INVALID_PARAM;
218     }
219
220     return OC_STACK_OK;
221 }
222
223 OCStackResult GroupSynchronization::joinGroup(const std::shared_ptr< OCResource > resource,
224         OCResourceHandle resourceHandle)
225 {
226     if ((resource) && (resourceHandle))
227     {
228         cout << "GroupSynchronization::joinGroup" << endl;
229
230         // making representation to join group
231         std::string method = "joinGroup";
232         std::vector< std::string > type = resource->getResourceTypes();
233         std::string resourceType;
234         resourceType.append(OCGetResourceTypeName(resourceHandle, 0));
235
236         OCRepresentation rep;
237         rep.setValue("method", method);
238         rep.setValue("collectionResourceType", type[0]);
239         rep.setValue("resourceType", resourceType);
240
241         cout << "\tmethod - " << method << endl;
242         cout << "\tcollectionResourceType - " << type[0] << endl;
243         cout << "\tresourceType - " << resourceType << endl;
244
245         // creating group sync resource with the received collection resource.
246         // entity handler of group sync is used to join group.
247         std::string host = resource->host();
248         std::string uri = resource->uri() + "/groupsync";
249
250         std::vector< std::string > resourceTypes;
251         std::string temp;
252         for (unsigned int i = 0; i < type.size(); ++i)
253         {
254             temp = type[0] + ".groupsync";
255             resourceTypes.push_back(temp);
256         }
257
258         std::vector< std::string > resourceInterface;
259         resourceInterface.push_back(DEFAULT_INTERFACE);
260
261         OCResource::Ptr groupSyncResource = OCPlatform::constructResourceObject(host, uri, 1,
262                 resourceTypes, resourceInterface);
263         groupSyncResourceList[type[0]] = groupSyncResource;
264
265         cout << "GroupSynchronization::joinGroup : creating groupSyncResource." << endl;
266
267         // Create QueryParameters Map and add query params (if any)
268         QueryParamsMap queryParamsMap;
269
270         // request to join group to the remote group sync resource
271         OCStackResult result = groupSyncResource->put(rep, queryParamsMap,
272                 std::bind(&GroupSynchronization::onJoinGroup, this, std::placeholders::_1,
273                         std::placeholders::_2, std::placeholders::_3));
274         if (OC_STACK_OK == result)
275         {
276             cout << "GroupSynchronization::joinGroup : groupSyncResource->put was successful."
277                     << endl;
278         }
279         else
280         {
281             cout << "GroupSynchronization::joinGroup : "
282                     << "groupSyncResource->put was unsuccessful. result - " << result << endl;
283         }
284
285         // saving the remote collection resource.
286         // It is used in onJoinGroup() and onGetJoinedRemoteChild().
287         remoteCollectionResource = resource;
288
289         // saving the resource handle to join. It is used in onGetJoinedRemoteChild()
290         deviceResourceHandle = resourceHandle;
291
292         return OC_STACK_OK;
293     }
294     else
295     {
296         cout << "GroupSynchronization::joinGroup : Error! Input params are wrong." << endl;
297         return OC_STACK_INVALID_PARAM;
298     }
299 }
300
301 OCStackResult GroupSynchronization::leaveGroup(std::string collectionResourceType,
302         OCResourceHandle resourceHandle)
303 {
304     if ((0 != collectionResourceType.length()) && (resourceHandle))
305     {
306         cout << "GroupSynchronization::leaveGroup : collectionResourceType - "
307                 << collectionResourceType << endl;
308
309         OCResourceHandle collectionResHandle;
310
311         auto handleIt = groupSyncResourceHandleList.find(collectionResourceType);
312
313         // if groupSyncResourceHandleList has resourceType,
314         // this app created collection resource handle.
315         if (handleIt != groupSyncResourceHandleList.end())
316         {
317             handleIt = collectionResourceHandleList.find(collectionResourceType);
318             if (handleIt == collectionResourceHandleList.end())
319             {
320                 cout << "GroupSynchronization::leaveGroup : "
321                         << "Error! There is no collection resource handle to leave." << endl;
322                 return OC_STACK_INVALID_PARAM;
323             }
324
325             collectionResHandle = handleIt->second;
326 //            cout << "GroupSynchronization::leaveGroup : collection handle uri - "
327 //                    << OCGetResourceUri(collectionResHandle) << endl;
328
329             OCStackResult result = OCPlatform::unbindResource(collectionResHandle,
330                     resourceHandle);
331             if (OC_STACK_OK == result)
332             {
333                 cout << "GroupSynchronization::leaveGroup : "
334                         << "To unbind resource was successful." << endl;
335             }
336             else
337             {
338                 cout << "GroupSynchronization::leaveGroup : "
339                         << "To unbind resource was unsuccessful. result - " << result << endl;
340             }
341
342             auto It = std::find(deviceResourceHandleList.begin(),
343                     deviceResourceHandleList.end(), resourceHandle);
344             if (It == deviceResourceHandleList.end()) // there is no resource handle to find
345             {
346                 result = OCPlatform::unregisterResource(resourceHandle);
347                 if (OC_STACK_OK == result)
348                 {
349                     cout << "GroupSynchronization::leaveGroup : "
350                             << "To unregister resource was successful." << endl;
351                 }
352                 else
353                 {
354                     cout << "GroupSynchronization::leaveGroup : "
355                             << "To unregister resource was unsuccessful. result - " << result
356                             << endl;
357                 }
358             }
359             else
360             {
361                 cout << "GroupSynchronization::leaveGroup : "
362                         << "This resource cannot be unregistered." << endl;
363                 deviceResourceHandleList.erase(It);
364             }
365
366             auto handleListIt = childResourceHandleList.find(collectionResHandle);
367             if (handleListIt == childResourceHandleList.end())
368             {
369                 cout << "GroupSynchronization::leaveGroup : "
370                         << "Error! There is no child resource list to delete." << endl;
371                 return OC_STACK_INVALID_PARAM;
372             }
373
374             std::vector< OCResourceHandle > childList = handleListIt->second;
375             auto childIt = std::find(childList.begin(), childList.end(), resourceHandle);
376             if (childIt != childList.end())
377             {
378                 cout << "GroupSynchronization::groupEntityHandler : "
379                         << "Found! The resource to leave is found." << endl;
380                 childList.erase(childIt);
381             }
382
383             childResourceHandleList[collectionResHandle] = childList;
384
385             debugGroupSync();
386         }
387         else // requesting to unbind this resourceHandle to the remote collection resource
388         {
389             auto resourceIt = groupSyncResourceList.find(collectionResourceType);
390
391             if (resourceIt == groupSyncResourceList.end())
392             {
393                 cout << "GroupSynchronization::leaveGroup : "
394                         << "Error! There is no collectin resource type to leave." << endl;
395                 return OC_STACK_INVALID_PARAM;
396             }
397
398             std::shared_ptr< OCResource > resource = resourceIt->second;
399 //            cout << "GroupSynchronization::leaveGroup : group sync resource uri - "
400 //                    << resource->uri() << endl;
401
402             handleIt = collectionResourceHandleList.find(collectionResourceType);
403             if (handleIt == collectionResourceHandleList.end())
404             {
405                 cout << "GroupSynchronization::leaveGroup : "
406                         << "Error! There is no collection resource handle to leave." << endl;
407                 return OC_STACK_INVALID_PARAM;
408             }
409
410             collectionResHandle = handleIt->second;
411
412             // making representation to leave group
413             std::string method = "leaveGroup";
414             std::string type = OCGetResourceTypeName(collectionResHandle, 0);
415             std::string resourceType;
416             resourceType.append(OCGetResourceTypeName(resourceHandle, 0));
417
418             OCRepresentation rep;
419             rep.setValue("method", method);
420             rep.setValue("collectionResourceType", type);
421             rep.setValue("resourceType", resourceType);
422
423             cout << "\tmethod - " << method << endl;
424             cout << "\tcollectionResourceType - " << type << endl;
425             cout << "\tresourceType - " << resourceType << endl;
426
427             QueryParamsMap queryParamsMap;
428
429             // request to leave group to the remote group sync resource
430             OCStackResult result = resource->put(rep, queryParamsMap,
431                     std::bind(&GroupSynchronization::onLeaveGroup, this, std::placeholders::_1,
432                             std::placeholders::_2, std::placeholders::_3));
433             if (OC_STACK_OK == result)
434             {
435                 cout << "GroupSynchronization::leaveGroup : "
436                         << "groupSyncResource->put was successful." << endl;
437             }
438             else
439             {
440                 cout << "GroupSynchronization::leaveGroup : "
441                         << "groupSyncResource->put was unsuccessful. result - " << result
442                         << endl;
443             }
444
445             // deleting all remote resources. These are copied in onGetJoinedRemoteChild()
446             deleteGroup(collectionResourceType);
447         }
448     }
449     else
450     {
451         cout << "GroupSynchronization::leaveGroup : Error! Input params are wrong." << endl;
452         return OC_STACK_INVALID_PARAM;
453     }
454
455     return OC_STACK_OK;
456 }
457
458 void GroupSynchronization::deleteGroup(std::string collectionResourceType)
459 {
460     if (0 != collectionResourceType.length())
461     {
462         cout << "GroupSynchronization::deleteGroup" << endl;
463
464         OCStackResult result;
465
466         auto handleIt = collectionResourceHandleList.find(collectionResourceType);
467         if (handleIt == collectionResourceHandleList.end())
468         {
469             cout << "GroupSynchronization::deleteGroup : "
470                     << "Error! There is no collection resource handle to delete." << endl;
471             return;
472         }
473         OCResourceHandle collectionResHandle = handleIt->second;
474
475         collectionResourceHandleList.erase(handleIt);
476
477         auto handleListIt = childResourceHandleList.find(collectionResHandle);
478         if (handleListIt == childResourceHandleList.end())
479         {
480             cout << "GroupSynchronization::deleteGroup : "
481                     << "Error! There is no child resource list to delete." << endl;
482             return;
483         }
484         std::vector< OCResourceHandle > childList = handleListIt->second;
485
486         childResourceHandleList.erase(handleListIt);
487
488         result = OCPlatform::unbindResources(collectionResHandle, childList);
489         if (OC_STACK_OK == result)
490         {
491             cout << "GroupSynchronization::deleteGroup : "
492                     << "To unbind resources was successful." << endl;
493         }
494         else
495         {
496             cout << "GroupSynchronization::deleteGroup : "
497                     << "To unbind resources was unsuccessful. result - " << result << endl;
498         }
499
500         result = OCPlatform::unregisterResource(collectionResHandle);
501         if (result != OC_STACK_OK)
502         {
503             cout << "GroupSynchronization::deleteGroup : "
504                     << "To unregister collection resource handle was successful." << endl;
505         }
506         else
507         {
508             cout << "GroupSynchronization::deleteGroup : "
509                     << " To unregister collection resource handle was unsuccessful. result - "
510                     << result << endl;
511         }
512
513         OCResourceHandle resourceHandle;
514         std::vector< OCResourceHandle >::iterator It;
515
516         for (unsigned int i = 0; i < childList.size(); i++)
517         {
518             resourceHandle = childList.at(i);
519
520             It = std::find(deviceResourceHandleList.begin(), deviceResourceHandleList.end(),
521                     resourceHandle);
522             if (It != deviceResourceHandleList.end()) // find !!
523             {
524                 deviceResourceHandleList.erase(It);
525             }
526             else
527             {
528                 result = OCPlatform::unregisterResource(resourceHandle);
529                 if (OC_STACK_OK == result)
530                 {
531                     cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i + 1
532                             << ") was successful." << endl;
533                 }
534                 else
535                 {
536                     cout << "GroupSynchronization::deleteGroup : UnregisterResource(" << i + 1
537                             << ") was unsuccessful. result - " << result << endl;
538                 }
539             }
540         }
541
542         handleIt = groupSyncResourceHandleList.find(collectionResourceType);
543
544         // if groupSyncResourceHandleList has resourceType,
545         // group sync of this app created collection resource.
546         if (handleIt != groupSyncResourceHandleList.end())
547         {
548             resourceHandle = handleIt->second; // group sync resource handle
549             result = OCPlatform::unregisterResource(resourceHandle);
550             if (OC_STACK_OK == result)
551             {
552                 cout << "GroupSynchronization::deleteGroup : "
553                         << "To unregister group sync resource handle was successful." << endl;
554             }
555             else
556             {
557                 cout << "GroupSynchronization::deleteGroup : "
558                         << "To unregister group sync resource handle was unsuccessful. "
559                         << "result - " << result << endl;
560             }
561
562             groupSyncResourceHandleList.erase(handleIt);
563         }
564
565         auto resourceIt = groupSyncResourceList.find(collectionResourceType);
566         if (resourceIt != groupSyncResourceList.end())
567         {
568             groupSyncResourceList.erase(resourceIt);
569         }
570
571         debugGroupSync();
572     }
573     else
574     {
575         cout << "GroupSynchronization::deleteGroup : Error! Input params are wrong." << endl;
576     }
577 }
578
579 std::map< std::string, OCResourceHandle > GroupSynchronization::getGroupList()
580 {
581     return collectionResourceHandleList;
582 }
583
584 OCEntityHandlerResult GroupSynchronization::groupEntityHandler(
585         const std::shared_ptr< OCResourceRequest > request)
586 {
587     cout << "GroupSynchronization::groupEntityHandler\n";
588
589     if (request)
590     {
591         // Get the request type and request flag
592         std::string requestType = request->getRequestType();
593         int requestFlag = request->getRequestHandlerFlag();
594
595         if (requestFlag == RequestHandlerFlag::InitFlag)
596         {
597             cout << "\trequestFlag : Init\n";
598
599             // entity handler to perform resource initialization operations
600         }
601         else if (requestFlag == RequestHandlerFlag::RequestFlag)
602         {
603             cout << "\trequestFlag : Request\n";
604
605             // If the request type is GET
606             if (requestType == "GET")
607             {
608                 cout << "\t\trequestType : GET\n";
609             }
610             else if (requestType == "PUT")
611             {
612                 cout << "\t\trequestType : PUT\n";
613
614                 //get method name, group resource type and resource type to join group
615                 OCRepresentation rp = request->getResourceRepresentation();
616                 std::string methodType = rp.getValue< std::string >("method");
617                 std::string collectionResourceType = rp.getValue< std::string >(
618                         "collectionResourceType");
619                 std::string resourceType = rp.getValue< std::string >("resourceType");
620
621                 cout << "\t\t\tmethod : " << methodType << endl;
622                 cout << "\t\t\tcollection resourceType : " << collectionResourceType << endl;
623                 cout << "\t\t\tresourceType : " << resourceType << endl;
624
625                 auto handleIt = collectionResourceHandleList.find(collectionResourceType);
626                 if (handleIt == collectionResourceHandleList.end())
627                 {
628                     cout << "GroupSynchronization::groupEntityHandler : "
629                             << "Error! There is no collection resource handle to delete."
630                             << endl;
631                     return OC_EH_ERROR;
632                 }
633                 collectionResourceHandle = handleIt->second;
634                 // in case of join group it is used in onFindResource()
635
636                 if (methodType == "joinGroup")
637                 {
638                     std::string resourceName = "coap://224.0.1.187/oc/core?rt=";
639                     resourceName += resourceType;
640                     cout << "\t\t\tresourceName : " << resourceName << endl;
641
642                     resourceRequest = request;
643
644                     OCPlatform::findResource("", resourceName,
645                             std::bind(&GroupSynchronization::onFindResource, this,
646                                     std::placeholders::_1));
647                 }
648                 else if (methodType == "leaveGroup")
649                 {
650                     auto it = childResourceHandleList.find(collectionResourceHandle);
651                     if (it == childResourceHandleList.end())
652                     {
653                         cout << "GroupSynchronization::groupEntityHandler : "
654                                 << "Error! There is no child resource list." << endl;
655                         return OC_EH_ERROR;
656                     }
657
658                     std::vector< OCResourceHandle > childList = it->second;
659                     OCResourceHandle resourceHandle;
660                     for (auto childIt = childList.begin(); childIt != childList.end();)
661                     {
662                         resourceHandle = (*childIt);
663                         char* type = (char*) OCGetResourceTypeName(resourceHandle, 0);
664
665                         if (0 == resourceType.compare(type))
666                         {
667                             cout << "GroupSynchronization::groupEntityHandler : "
668                                     << "Found! The resource to leave is found. - " << type
669                                     << endl;
670
671                             childIt = childList.erase(childIt++);
672
673                             OCStackResult result = OCPlatform::unbindResource(
674                                     collectionResourceHandle, resourceHandle);
675                             if (OC_STACK_OK == result)
676                             {
677                                 cout << "GroupSynchronization::groupEntityHandler : "
678                                         << "To unbind resource was successful." << endl;
679                             }
680                             else
681                             {
682                                 cout << "GroupSynchronization::groupEntityHandler : "
683                                         << "To unbind resource was unsuccessful. result - "
684                                         << result << endl;
685                             }
686
687                             result = OCPlatform::unregisterResource(resourceHandle);
688                             if (OC_STACK_OK == result)
689                             {
690                                 cout << "GroupSynchronization::groupEntityHandler : "
691                                         << "To unregister resource was successful." << endl;
692                             }
693                             else
694                             {
695                                 cout << "GroupSynchronization::groupEntityHandler : "
696                                         << "To unregister resource was unsuccessful. result - "
697                                         << result << endl;
698                             }
699
700 //                            break;
701                         }
702                         else
703                         {
704                             ++childIt;
705                         }
706
707                     }
708
709                     childResourceHandleList[collectionResourceHandle] = childList;
710
711                     debugGroupSync();
712
713                     auto pResponse = std::make_shared< OC::OCResourceResponse >();
714                     pResponse->setRequestHandle(request->getRequestHandle());
715                     pResponse->setResourceHandle(request->getResourceHandle());
716                     pResponse->setErrorCode(200);
717                     pResponse->setResponseResult(OC_EH_OK);
718
719                     OCRepresentation rep = request->getResourceRepresentation();
720                     pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
721                     if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
722                     {
723                         cout << "GroupSynchronization::groupEntityHandler : "
724                                 << "sendResponse is successful." << endl;
725                     }
726                 }
727
728                 if (methodType != "") //TODO: Check groupmethodtype NULL
729                 {
730                 }
731             }
732             else if (requestType == "POST")
733             {
734                 // POST request operations
735             }
736             else if (requestType == "DELETE")
737             {
738                 // DELETE request operations
739             }
740         }
741         else if (requestFlag == RequestHandlerFlag::ObserverFlag)
742         {
743             cout << "\trequestFlag : Observer\n";
744         }
745     }
746     else
747     {
748         std::cout << "Request invalid" << std::endl;
749     }
750
751     return OC_EH_OK;
752 }
753
754 void GroupSynchronization::onFindGroup(std::shared_ptr< OCResource > resource)
755 {
756     cout << "GroupSynchronization::onFindGroup" << endl;
757
758     try
759     {
760         if (resource)
761         {
762 //////////////////////////////////////////////////////////////////////////////////////////////////
763 ////////////debugging
764             std::string resourceURI;
765             std::string hostAddress;
766
767             // Get the resource URI
768             resourceURI = resource->uri();
769             cout << "\tURI of the resource: " << resourceURI << endl;
770
771             // Get the resource host address
772             hostAddress = resource->host();
773             cout << "\tHost address of the resource: " << hostAddress << endl;
774
775             hostAddress.append(resourceURI);
776
777             // Get the resource types
778             cout << "\tList of resource types: " << endl;
779
780             for (auto &resourceTypes : resource->getResourceTypes())
781             {
782                 cout << "\t\t" << resourceTypes << endl;
783             }
784
785             // Get the resource interfaces
786             cout << "\tList of resource interfaces: " << endl;
787             for (auto &resourceInterfaces : resource->getResourceInterfaces())
788             {
789                 cout << "\t\t" << resourceInterfaces << endl;
790             }
791 //////////////////////////////////////////////////////////////////////////////////////////////////
792
793             if (false == IsSameGroup(resource))
794             {
795                 saveGroup(resource);
796                 findCallback(resource);
797             }
798         }
799         else
800         {
801             // Resource is invalid
802             cout << "Resource is invalid" << endl;
803             findCallback(NULL);
804         }
805
806     }
807     catch (std::exception& e)
808     {
809         //log(e.what());
810     }
811 }
812
813 void GroupSynchronization::checkFindGroup(void)
814 {
815     cout << "GroupSynchronization::checkFindGroup" << endl;
816
817     for (int i = 0; i < 15; i++)
818     {
819         std::chrono::milliseconds workTime(300);
820         std::this_thread::sleep_for(workTime);
821
822         std::lock_guard < std::mutex > guard(foundGroupMutex);
823
824         if (false == foundGroupResourceList.empty())
825         {
826             cout << "GroupSynchronization::checkFoundGroup : " << "Some group is received."
827                     << endl;
828             return;
829         }
830     }
831
832     cout << "GroupSynchronization::checkFoundGroup : "
833             << "It is failed to find resource within 3s." << endl;
834
835     onFindGroup(NULL);
836     return;
837 }
838
839 bool GroupSynchronization::IsSameGroup(std::shared_ptr< OCResource > resource)
840 {
841     std::lock_guard < std::mutex > guard(foundGroupMutex);
842
843     if (true == foundGroupResourceList.empty())
844     {
845         cout << "GroupSynchronization::IsSameGroup : There is no found group." << endl;
846         return false;
847     }
848
849     std::string foundHostAddress, savedHostAddress;
850     foundHostAddress = resource->host();
851 //    foundHostAddress.append (resource->uri());
852
853     for (unsigned int i = 0; i < foundGroupResourceList.size(); ++i)
854     {
855         savedHostAddress = (foundGroupResourceList.at(i))->host();
856 //        savedHostAddress.append ((foundGroupResourceList.at(i))->uri());
857 //        cout << "GroupSynchronization::IsSameGroup : foundHostAddress - " << foundHostAddress
858 //                << ", savedHostAddress - " << savedHostAddress << endl;
859
860         if (0 == foundHostAddress.compare(savedHostAddress.c_str()))
861         {
862             cout << "GroupSynchronization::IsSameGroup : Found! The same group is found."
863                     << endl;
864             return true;
865         }
866     }
867
868     cout << "GroupSynchronization::IsSameGroup :  There is no same group." << endl;
869     return false;
870 }
871
872 void GroupSynchronization::saveGroup(std::shared_ptr< OCResource > resource)
873 {
874     cout << "GroupSynchronization::saveGroup" << endl;
875
876     std::lock_guard < std::mutex > guard(foundGroupMutex);
877
878     foundGroupResourceList.push_back(resource);
879 }
880
881 void GroupSynchronization::onJoinGroup(const HeaderOptions& headerOptions,
882         const OCRepresentation& rep, const int eCode)
883 {
884     if (eCode == OC_STACK_OK)
885     {
886         cout << "GroupSynchronization::onJoinGroup : " << endl;
887
888         if (remoteCollectionResource)
889         {
890             std::string resourceInterface = DEFAULT_INTERFACE;
891             QueryParamsMap queryParamsMap;
892
893             OCStackResult result = remoteCollectionResource->get("", resourceInterface,
894                     queryParamsMap,
895                     std::bind(&GroupSynchronization::onGetJoinedRemoteChild, this,
896                             std::placeholders::_1, std::placeholders::_2,
897                             std::placeholders::_3));
898             if (OC_STACK_OK == result)
899             {
900                 cout << "GroupSynchronization::onJoinGroup : "
901                         << "remoteCollectionResource->get was successful." << endl;
902             }
903             else
904             {
905                 cout << "GroupSynchronization::onJoinGroup : "
906                         << "remoteCollectionResource->get was unsuccessful. result - " << result
907                         << endl;
908             }
909         }
910     }
911     else
912     {
913         cout << "GroupSynchronization::onJoinGroup : error - " << eCode << endl;
914     }
915 }
916
917 void GroupSynchronization::onFindResource(std::shared_ptr< OCResource > resource)
918 {
919     cout << "GroupSynchronization::onFindResource" << endl;
920
921     if (resource)
922     {
923 //////////////////////////////////////////////////////////////////////////////////////////////////
924 ////////// debugging
925         std::string resourceURI;
926         std::string hostAddress;
927
928         // Get the resource URI
929         resourceURI = resource->uri();
930         cout << "\tURI of the resource: " << resourceURI << endl;
931
932         // Get the resource host address
933         hostAddress = resource->host();
934         cout << "\tHost address of the resource: " << hostAddress << endl;
935
936         hostAddress.append(resourceURI);
937
938         // Get the resource types
939         cout << "\tList of resource types: " << endl;
940
941         for (auto &resourceTypes : resource->getResourceTypes())
942         {
943             cout << "\t\t" << resourceTypes << endl;
944         }
945
946         // Get the resource interfaces
947         cout << "\tList of resource interfaces: " << endl;
948         for (auto &resourceInterfaces : resource->getResourceInterfaces())
949         {
950             cout << "\t\t" << resourceInterfaces << endl;
951         }
952 //////////////////////////////////////////////////////////////////////////////////////////////////
953
954         OCResourceHandle resourceHandle;
955         OCStackResult result = OCPlatform::registerResource(resourceHandle, resource);
956         if (result != OC_STACK_OK)
957         {
958             cout << "GroupSynchronization::"
959                     << "onFindResource - Resource to join creation was unsuccessful. result - "
960                     << result << endl;
961             return;
962         }
963 //        cout << "GroupSynchronization::onFindResource : creating resourceHandle. resource type - "
964 //                << OCGetResourceTypeName(resourceHandle, 0) << endl;
965
966         result = OCPlatform::bindResource(collectionResourceHandle, resourceHandle);
967         if (result != OC_STACK_OK)
968         {
969             cout << "GroupSynchronization::onFindResource : "
970                     << "To bind resource was unsuccessful. result - " << result << endl;
971             return;
972         }
973         cout << "GroupSynchronization::onFindResource : "
974                 << "To bind joinGroupHandle and resourceHandle was successful." << endl;
975
976         auto it = childResourceHandleList.find(collectionResourceHandle);
977         std::vector< OCResourceHandle > childHandleList;
978         if (it != childResourceHandleList.end())
979         {
980             childHandleList = it->second;
981         }
982
983         childHandleList.push_back(resourceHandle);
984         childResourceHandleList[collectionResourceHandle] = childHandleList;
985
986         auto pResponse = std::make_shared< OC::OCResourceResponse >();
987         pResponse->setRequestHandle(resourceRequest->getRequestHandle());
988         pResponse->setResourceHandle(resourceRequest->getResourceHandle());
989         pResponse->setErrorCode(200);
990         pResponse->setResponseResult(OC_EH_OK);
991
992         OCRepresentation rep = resourceRequest->getResourceRepresentation();
993         pResponse->setResourceRepresentation(rep, DEFAULT_INTERFACE);
994         if (OC_STACK_OK == OCPlatform::sendResponse(pResponse))
995         {
996             cout << "GroupSynchronization::onFindResource : sendResponse is successful."
997                     << endl;
998         }
999     }
1000     else
1001     {
1002         cout << "GroupSynchronization::onFindResource : "
1003                 << "Resource is invalid. So a new Group Resource has to be created." << endl;
1004     }
1005
1006     debugGroupSync();
1007 }
1008
1009 void GroupSynchronization::onGetJoinedRemoteChild(const HeaderOptions& headerOptions,
1010         const OCRepresentation& rep, const int eCode)
1011 {
1012     if (eCode == OC_STACK_OK)
1013     {
1014         cout << "GroupSynchronization::onGetJoinedRemoteChild" << endl;
1015
1016 //////////////////////////////////////////////////////////////////////////////////////////////////
1017 ////////// debugging
1018         std::string resourceURI;
1019
1020         // Get the resource URI
1021         resourceURI = rep.getUri();
1022         cout << "\tURI of the resource: " << resourceURI << endl;
1023
1024         // Get the resource types
1025         cout << "\tList of resource types: " << endl;
1026
1027         for (auto &resourceTypes : rep.getResourceTypes())
1028         {
1029             cout << "\t\t" << resourceTypes << endl;
1030         }
1031
1032         // Get the resource interfaces
1033         cout << "\tList of resource interfaces: " << endl;
1034         for (auto &resourceInterfaces : rep.getResourceInterfaces())
1035         {
1036             cout << "\t\t" << resourceInterfaces << endl;
1037         }
1038
1039         std::vector< OCRepresentation > childList = rep.getChildren();
1040         OCRepresentation child;
1041         for (unsigned int i = 0; i < childList.size(); ++i)
1042         {
1043             cout << "\n\tchild resource - " << i + 1 << endl;
1044
1045             child = childList.at(i);
1046             resourceURI = child.getUri();
1047             cout << "\t\tURI of the resource: " << resourceURI << endl;
1048
1049             cout << "\t\tList of resource types: " << endl;
1050             for (auto &types : child.getResourceTypes())
1051             {
1052                 cout << "\t\t\t" << types << endl;
1053             }
1054
1055             cout << "\tList of resource interfaces: " << endl;
1056             for (auto &interfaces : child.getResourceInterfaces())
1057             {
1058                 cout << "\t\t\t" << interfaces << endl;
1059             }
1060         }
1061 //////////////////////////////////////////////////////////////////////////////////////////////////
1062
1063         // creating remote collection resource handle
1064         OCResourceHandle remoteCollectionResourceHandle;
1065         resourceURI = remoteCollectionResource->uri();
1066         std::vector< std::string > types = remoteCollectionResource->getResourceTypes();
1067         std::vector< std::string > interfaces =
1068                 remoteCollectionResource->getResourceInterfaces();
1069
1070         OCStackResult result = OCPlatform::registerResource(remoteCollectionResourceHandle,
1071                 resourceURI, types[0], interfaces[0], NULL, OC_OBSERVABLE);
1072         if (result != OC_STACK_OK)
1073         {
1074             cout << "GroupSynchronization::onGetJoinedRemoteChild - "
1075                     << "To register remoteCollectionResourceHandle"
1076                     << " was unsuccessful. result - " << result << endl;
1077             return;
1078         }
1079         cout << "GroupSynchronization::onGetJoinedRemoteChild : "
1080                 "To register remoteCollectionResourceHandle was successful." << endl;
1081
1082         // binding remote collection resource handle and resource handle to join
1083         collectionResourceHandleList[types[0]] = remoteCollectionResourceHandle;
1084
1085         result = OCPlatform::bindResource(remoteCollectionResourceHandle, deviceResourceHandle);
1086         if (OC_STACK_OK == result)
1087         {
1088             cout << "GroupSynchronization::onGetJoinedRemoteChild : "
1089                     << "binding remoteCollectionResourceHandle and deviceResourceHandle"
1090                     << endl;
1091         }
1092         else
1093         {
1094             cout << "GroupSynchronization::onGetJoinedRemoteChild - "
1095                     << "To bind remoteCollectionResourceHandle and deviceResourceHandle "
1096                     << "was unsuccessful. result - " << result << endl;
1097         }
1098
1099         std::vector< OCResourceHandle > childHandleList;
1100         childHandleList.push_back(deviceResourceHandle);
1101         deviceResourceHandleList.push_back(deviceResourceHandle);
1102
1103         // binding copied remote collection resource handle and copied remote resource
1104         OCResourceHandle resourceHandle;
1105         for (unsigned int i = 0; i < childList.size(); ++i)
1106         {
1107             cout << "\tremote resource - " << i + 1 << endl;
1108
1109             child = childList.at(i);
1110             resourceURI = child.getUri();
1111             types = child.getResourceTypes();
1112             interfaces = child.getResourceInterfaces();
1113
1114             if (0 == types[0].compare(OCGetResourceTypeName(deviceResourceHandle, 0)))
1115             {
1116                 cout << "GroupSynchronization::onGetJoinedRemoteChild : " << types[0]
1117                         << " is bind already." << endl;
1118                 continue;
1119             }
1120
1121             result = OCPlatform::registerResource(resourceHandle, resourceURI, types[0],
1122                     interfaces[0], NULL, OC_OBSERVABLE);
1123             if (OC_STACK_OK == result)
1124             {
1125                 result = OCPlatform::bindResource(remoteCollectionResourceHandle,
1126                         resourceHandle);
1127                 if (result != OC_STACK_OK)
1128                 {
1129                     cout << "GroupSynchronization::onGetJoinedRemoteChild - "
1130                             << "binding remoteCollectionResourceHandle and resourceHandle "
1131                             << "was unsuccessful. result - " << result << endl;
1132                     OCPlatform::unregisterResource(resourceHandle);
1133                 }
1134
1135                 childHandleList.push_back(resourceHandle);
1136                 cout << "GroupSynchronization::onGetJoinedRemoteChild : "
1137                         << "binding remoteCollectionResourceHandle and resourceHandle" << endl;
1138             }
1139             else
1140             {
1141                 cout << "GroupSynchronization::onGetJoinedRemoteChild - "
1142                         << "To register remoteCollectionResourceHandle was unsuccessful."
1143                         << " result - " << result << endl;
1144             }
1145         }
1146
1147         childResourceHandleList[remoteCollectionResourceHandle] = childHandleList;
1148         // this handle list is used to leave group
1149     }
1150     else
1151     {
1152         cout << "GroupSynchronization::onGetJoinedRemoteChild : error - " << eCode << endl;
1153     }
1154
1155     debugGroupSync();
1156 }
1157
1158 void GroupSynchronization::onLeaveGroup(const HeaderOptions& headerOptions,
1159         const OCRepresentation& rep, const int eCode)
1160 {
1161     if (eCode == OC_STACK_OK)
1162     {
1163         cout << "GroupSynchronization::onLeaveGroup" << endl;
1164     }
1165     else
1166     {
1167         cout << "GroupSynchronization::onLeaveGroup : error - " << eCode << endl;
1168     }
1169     debugGroupSync();
1170 }
1171
1172 void GroupSynchronization::debugGroupSync(void)
1173 {
1174     cout << "GroupSynchronization::debugGroupSync" << endl;
1175
1176     unsigned int i;
1177     std::map< std::string, OCResourceHandle >::iterator handleIt;
1178     std::map< OCResourceHandle, std::vector< OCResourceHandle > >::iterator childIt;
1179     std::string type;
1180     OCResourceHandle resourceHandle;
1181     std::vector< OCResourceHandle > handleList;
1182     std::shared_ptr< OCResource > resource;
1183
1184     cout << "Resource Handle Created by App" << endl;
1185     for (i = 0; i < deviceResourceHandleList.size(); i++)
1186     {
1187         resourceHandle = deviceResourceHandleList.at(i);
1188
1189         cout << i + 1 << ". details" << endl;
1190         cout << "  uri - " << OCGetResourceUri(resourceHandle) << endl;
1191         cout << "  resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl;
1192         cout << "  resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0)
1193                 << endl << endl;
1194     }
1195
1196     cout << "\nGroup Sync Resource Handle List. The number is "
1197             << groupSyncResourceHandleList.size() << endl;
1198     i = 1;
1199     for (handleIt = groupSyncResourceHandleList.begin();
1200             handleIt != groupSyncResourceHandleList.end(); ++handleIt)
1201     {
1202         type = handleIt->first;
1203         cout << "\t" << i << ". group sync resource type - " << type << endl;
1204         cout << "\t  details" << endl;
1205
1206         resourceHandle = handleIt->second;
1207         cout << "\t  uri - " << OCGetResourceUri(resourceHandle) << endl;
1208         cout << "\t  resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl;
1209         cout << "\t  resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0)
1210                 << endl << endl;
1211         ;
1212         i++;
1213     }
1214
1215     cout << "Copied Remote Group Sync Resource List. The number is "
1216             << groupSyncResourceList.size() << endl;
1217     std::vector< std::string > list;
1218     i = 1;
1219     for (auto resourceIt = groupSyncResourceList.begin();
1220             resourceIt != groupSyncResourceList.end(); ++resourceIt)
1221     {
1222         type = resourceIt->first;
1223         cout << "\t" << i << ". group sync resource type - " << type << endl;
1224         cout << "\t details" << endl;
1225
1226         resource = resourceIt->second;
1227         cout << "\t  host - " << resource->host() << endl;
1228         cout << "\t  uri - " << resource->uri() << endl;
1229         list = resource->getResourceTypes();
1230         cout << "\t  resource type - " << list[0] << endl;
1231         list = resource->getResourceInterfaces();
1232         cout << "\t  resource interface - " << list[0] << endl << endl;
1233         i++;
1234     }
1235
1236 //    cout << "The number of collection Resource Handle is " << collectionResourceHandleList.size()
1237 //            << endl;
1238 //    cout << "The number of child resource handle list is " << childResourceHandleList.size()
1239 //            << endl;
1240
1241     cout << "Collection Resource Handle List" << endl;
1242     i = 1;
1243     for (handleIt = collectionResourceHandleList.begin();
1244             handleIt != collectionResourceHandleList.end(); ++handleIt)
1245     {
1246         type = handleIt->first;
1247         cout << "\t" << i << ". collection resource type - " << type << endl;
1248         cout << "\t  details" << endl;
1249
1250         resourceHandle = handleIt->second;
1251         cout << "\t  uri - " << OCGetResourceUri(resourceHandle) << endl;
1252         cout << "\t  resource type - " << OCGetResourceTypeName(resourceHandle, 0) << endl;
1253         cout << "\t  resource interface - " << OCGetResourceInterfaceName(resourceHandle, 0)
1254                 << endl << endl;
1255
1256         childIt = childResourceHandleList.find(resourceHandle);
1257         if (childIt != childResourceHandleList.end())
1258         {
1259             handleList = childIt->second;
1260             for (unsigned int j = 0; j < handleList.size(); j++)
1261             {
1262
1263                 cout << "\t\t" << j + 1 << ". child resource details" << endl;
1264
1265                 resourceHandle = handleList.at(j);
1266                 cout << "\t\t  uri - " << OCGetResourceUri(resourceHandle) << endl;
1267                 cout << "\t\t  resource type - " << OCGetResourceTypeName(resourceHandle, 0)
1268                         << endl;
1269                 cout << "\t\t  resource interface - "
1270                         << OCGetResourceInterfaceName(resourceHandle, 0) << endl << endl;
1271             }
1272         }
1273
1274         i++;
1275     }
1276 }
1277 }