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