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