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