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