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