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