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