Added lock logic in findResource callback for C++ samples
[platform/upstream/iotivity.git] / resource / examples / groupclient.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 #include "OCPlatform.h"
22 #include "OCApi.h"
23 #include "logger.h"
24
25 #include <functional>
26 #include <pthread.h>
27 #include <mutex>
28 #include <condition_variable>
29 #include <iostream>
30 #include <mutex>
31
32 using namespace std;
33 using namespace OC;
34 namespace PH = std::placeholders;
35 std::mutex resourceLock;
36
37 OCResourceHandle resourceHandle;
38 shared_ptr< OCResource > g_resource;
39 vector< string > lights;
40 std::mutex blocker;
41 std::condition_variable cv;
42
43 bool isReady = false;
44
45 void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode);
46
47 void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
48
49 void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
50
51 void foundResource(std::shared_ptr< OCResource > resource)
52 {
53     std::lock_guard<std::mutex> lock(resourceLock);
54     if(g_resource)
55     {
56         std::cout << "Found another resource, ignoring"<<std::endl;
57         return;
58     }
59
60     std::string resourceURI;
61     std::string hostAddress;
62
63     try
64     {
65         cout << "FOUND Resource" << endl;
66
67         if (resource)
68         {
69             string resourceURI = resource->uri();
70             cout << resourceURI << endl;
71             cout << "HOST :: " << resource->host() << endl;
72             if (resourceURI == "/core/a/collection")
73             {
74                 g_resource = resource;
75                 resource->get("", DEFAULT_INTERFACE, QueryParamsMap(), onGet);
76             }
77         }
78     }
79     catch (std::exception& e)
80     {
81         std::cout << "" << std::endl;
82     }
83 }
84
85 void onGet(const HeaderOptions& opt, const OCRepresentation &rep, const int eCode)
86 {
87     // printf("onGet\n");
88
89     std::vector< OCRepresentation > children = rep.getChildren();
90
91     cout << "\n\n\nCHILD RESOURCE OF GROUP" << endl;
92     for (auto iter = children.begin(); iter != children.end(); ++iter)
93     {
94         lights.push_back((*iter).getUri());
95         cout << "\tURI :: " << (*iter).getUri() << endl;
96     }
97
98     isReady = true;
99     cv.notify_one();
100 }
101
102 void onPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
103 {
104     printf("\nonPut\n");
105 }
106
107 void onPost(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
108 {
109     printf("\nonPost\n");
110
111     std::vector< OCRepresentation > children = rep.getChildren();
112
113     cout << "\n\n\nCHILD RESOURCE OF GROUP" << endl;
114     for (auto iter = children.begin(); iter != children.end(); ++iter)
115     {
116         std::string power;
117         (*iter).getValue("power", power);
118
119         cout << "\tURI :: " << (*iter).getUri() << endl;
120         cout << "\t\tpower :: " << power << endl;
121     }
122
123     if (rep.hasAttribute("ActionSet"))
124     {
125         std::string plainText;
126
127         rep.getValue("ActionSet", plainText);
128
129         printf("\tPlain Text :: %s\n", plainText.c_str());
130     }
131     else
132     {
133         printf("Not found ActionSet\n");
134     }
135 }
136
137 string buildActionSetDesc()
138 {
139     string actionsetDesc = "";
140     //"movieTime*uri=coap://10.251.44.228:49858/a/light|power=10*uri=coap:
141     //10.251.44.228:49858/a/light|power=10|";
142     actionsetDesc = "allbulboff";
143     actionsetDesc.append("*");
144     for (auto iter = lights.begin(); iter != lights.end(); ++iter)
145     {
146         actionsetDesc.append("uri=").append((*iter));
147         actionsetDesc.append("|");
148         actionsetDesc.append("power=");
149         actionsetDesc.append("off");
150         if ((iter + 1) != lights.end())
151         {
152             actionsetDesc.append("*");
153         }
154     }
155     return actionsetDesc;
156 }
157
158 bool isResourceReady()
159 {
160     return isReady;
161 }
162 int main()
163 {
164     PlatformConfig config
165     { OC::ServiceType::InProc, ModeType::Client, "0.0.0.0", 0, OC::QualityOfService::LowQos };
166
167     bool isRun = true;
168
169     try
170     {
171         OCPlatform::Configure(config);
172
173         string resourceTypeName = "a.collection";
174         OCPlatform::findResource("", "coap://224.0.1.187/oc/core?rt=a.collection", &foundResource);
175
176         //Non-intensive block util foundResource callback is called by OCPlatform
177         //and onGet gets resource.
178         //isResourceReady takes care of spurious wake-up
179
180         std::unique_lock<std::mutex> lock(blocker);
181         cv.wait(lock, isResourceReady);
182
183         while (isRun)
184         {
185             usleep(100);
186             int selectedMenu;
187
188             cout << endl
189                  << "0 :: Quit 1 :: CREATE ACTIONSET 2 :: EXECUTE ACTION SET \n";
190             cout << "3 :: GET ACTIONSET 4 :: DELETE ACTIONSET \n" << endl;
191
192             cin >> selectedMenu;
193
194             OCRepresentation rep;
195             string actionsetDesc;
196             switch(selectedMenu)
197             {
198                 case 0:
199                     isRun = false;
200                     break;
201                 case 1:
202                     actionsetDesc = buildActionSetDesc();
203
204                     if(!actionsetDesc.empty())
205                     {
206                         cout << "ActionSet :: " << actionsetDesc << endl;
207                         rep.setValue("ActionSet", actionsetDesc);
208                     }
209
210                     if (g_resource)
211                     {
212                         g_resource->put("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
213                                 &onPut);
214                     }
215                     break;
216                 case 2:
217                     rep.setValue("DoAction", std::string("allbulboff"));
218                     if (g_resource)
219                     {
220                         g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
221                             &onPost);
222                     }
223                     break;
224                 case 3:
225                     rep.setValue("GetActionSet", std::string("allbulboff"));
226                     if (g_resource)
227                     {
228                         g_resource->post("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
229                             &onPost);
230                     }
231                     break;
232                 case 4:
233                     rep.setValue("DelActionSet", std::string("allbulboff"));
234                     if (g_resource)
235                     {
236                         g_resource->put("a.collection", GROUP_INTERFACE, rep, QueryParamsMap(),
237                             &onPut);
238                     }
239                     break;
240                 default:
241                     cout << "Incorrect option" << endl;
242                     break;
243
244             }
245             fflush(stdin);
246         }
247     }
248     catch (OCException& e)
249     {
250         cout << e.what() << endl;
251     }
252
253     return 0;
254 }