New APIs : hasAttribute, numberOfAttributes, erase in OCRepresentation.
[platform/upstream/iotivity.git] / examples / simpleclientserver.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH 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 /// This sample provides steps to define an interface for a resource
23 /// (properties and methods) and host this resource on the server.
24 /// Additionally, it'll have a client example to discover it as well.
25 ///
26 #include <memory>
27 #include <iostream>
28 #include <stdexcept>
29 #include <condition_variable>
30 #include <map>
31 #include <vector>
32 #include "OCPlatform.h"
33 #include "OCApi.h"
34 using namespace OC;
35
36 class ClientWorker
37 {
38 private:
39     bool m_isFoo;
40     int m_barCount;
41     void putResourceInfo(const OCRepresentation rep, const OCRepresentation rep2, const int eCode)
42     {
43        std::cout << "In PutResourceInfo" << std::endl;
44
45        std::cout <<"Clientside Put response to get was: "<<std::endl;
46        std::cout <<"ErrorCode: "<<eCode <<std::endl;
47
48        if(eCode == 0)
49        {
50             std::cout<<"Successful Put.  Attributes sent were: "<<std::endl;
51
52             rep.getValue("isFoo", m_isFoo);
53             rep.getValue("barCount", m_barCount);
54
55             std::cout << "\tisFoo: "<< m_isFoo << std::endl;
56             std::cout << "\tbarCount: "<< m_barCount << std::endl;
57
58             std::cout<<"Actual New values are: "<<std::endl;
59
60             rep.getValue("isFoo", m_isFoo);
61             rep.getValue("barCount", m_barCount);
62
63             std::cout << "\tisFoo: "<< m_isFoo << std::endl;
64             std::cout << "\tbarCount: "<< m_barCount << std::endl;
65
66             m_cv.notify_all();
67        }
68     }
69
70     void getResourceInfo(const OCRepresentation rep, const int eCode)
71     {
72         std::cout << "In getResourceInfo" << std::endl;
73
74         std::cout<<"Clientside response to get was: "<<std::endl;
75         std::cout<<"Error Code: "<<eCode<<std::endl;
76
77         if(eCode == 0)
78         {
79             std::cout <<"Successful Get.  Attributes are: "<<std::endl;
80
81             rep.getValue("isFoo", m_isFoo);
82             rep.getValue("barCount", m_barCount);
83
84             std::cout << "\tisFoo: "<< m_isFoo << std::endl;
85             std::cout << "\tbarCount: "<< m_barCount << std::endl;
86
87             std::cout << "Doing a put on q/foo" <<std::endl;
88             OCRepresentation rep2(rep);
89             m_isFoo = false;
90             m_barCount = 211;
91
92             rep2.setValue("isFoo", m_isFoo);
93             rep2.setValue("barCount", m_barCount);
94
95             m_resource->put(rep2, QueryParamsMap(), PutCallback(std::bind(&ClientWorker::putResourceInfo, this, rep2, std::placeholders::_1, std::placeholders::_2)));
96         }
97     }
98
99     void foundResource(std::shared_ptr<OCResource> resource)
100     {
101         std::cout << "In foundResource" << std::endl;
102         if(resource && resource->uri() == "/q/foo")
103         {
104             {
105                 std::lock_guard<std::mutex> lock(m_resourceLock);
106                 if(m_resource)
107                 {
108                     return;
109                 }
110
111                 m_resource = resource;
112             }
113
114             std::cout << "Found Resource: "<<std::endl;
115             std::cout << "\tHost: "<< resource->host()<<std::endl;
116             std::cout << "\tURI:  "<< resource->uri()<<std::endl;
117
118             // Get the resource types
119             std::cout << "\tList of resource types: " << std::endl;
120             for(auto &resourceTypes : resource->getResourceTypes())
121             {
122                 std::cout << "\t\t" << resourceTypes << std::endl;
123             }
124
125             // Get the resource interfaces
126             std::cout << "\tList of resource interfaces: " << std::endl;
127             for(auto &resourceInterfaces : resource->getResourceInterfaces())
128             {
129                 std::cout << "\t\t" << resourceInterfaces << std::endl;
130             }
131
132             std::cout<<"Doing a get on q/foo."<<std::endl;
133
134             resource->get(QueryParamsMap(), GetCallback(std::bind(&ClientWorker::getResourceInfo, this, std::placeholders::_1, std::placeholders::_2)));
135         }
136     }
137
138 public:
139     void start(OCPlatform& platform)
140     {
141         std::cout<<"Starting Client find:"<<std::endl;
142         FindCallback f (std::bind(&ClientWorker::foundResource, this, std::placeholders::_1));
143         std::cout<<"result:" << platform.findResource("", "coap://224.0.1.187/oc/core?rt=core.foo", f)<< std::endl;
144         std::cout<<"Finding Resource..."<<std::endl;
145
146         {
147             std::unique_lock<std::mutex> lk(m_mutex);
148             m_cv.wait(lk);
149         }
150     }
151 private:
152     std::mutex m_mutex;
153     std::mutex m_resourceLock;
154     std::condition_variable m_cv;
155     std::shared_ptr<OCResource> m_resource;
156 };
157
158 struct FooResource
159 {
160     bool m_isFoo;
161     int m_barCount;
162     OCResourceHandle m_resourceHandle;
163     OCRepresentation m_rep;
164
165     FooResource(): m_isFoo(true), m_barCount (0)
166     {
167         m_rep.setUri("/q/foo");
168         m_rep.setValue("isFoo", m_isFoo);
169         m_rep.setValue("barCount", m_barCount);
170     }
171
172     bool createResource(OCPlatform& platform)
173     {
174         std::string resourceURI = "/q/foo";
175         std::string resourceTypeName = "core.foo";
176         std::string resourceInterface = DEFAULT_INTERFACE;
177
178         uint8_t resourceProperty = OC_DISCOVERABLE;
179
180         RegisterCallback eh(std::bind(&FooResource::entityHandler, this, std::placeholders::_1, std::placeholders::_2));
181         OCStackResult result = platform.registerResource(m_resourceHandle, resourceURI, resourceTypeName,
182                                     resourceInterface,
183                                     eh, resourceProperty);
184         if(OC_STACK_OK != result)
185         {
186             std::cout<<"Resource creation unsuccessful"<<std::endl;
187             return false;
188         }
189
190         return true;
191     }
192
193     OCRepresentation get()
194     {
195         m_rep.setValue("isFoo", m_isFoo);
196         m_rep.setValue("barCount", m_barCount);
197
198         return m_rep;
199     }
200
201     void put(OCRepresentation& rep)
202     {
203         rep.getValue("isFoo", m_isFoo);
204         rep.getValue("barCount", m_barCount);
205     }
206
207     void entityHandler(std::shared_ptr<OCResourceRequest> request, std::shared_ptr<OCResourceResponse> response)
208     {
209         std::cout<<"\tConsumer Entity Handler:"<<std::endl;
210
211         if(request)
212         {
213             // Note: Most of the handlers are not here, since this is for demoing client/server co-process existence.
214             // See simpleserver for a more complete example.
215             if(request->getRequestHandlerFlag()  == RequestHandlerFlag::RequestFlag)
216             {
217                 std::cout << "\t\trequestFlag : Request"<<std::endl;
218
219                 if(request->getRequestType() == "GET")
220                 {
221                     std::cout<<"\t\t\trequestType : GET"<<std::endl;
222
223                     if(response)
224                     {
225                         response->setErrorCode(200);
226                         response->setResourceRepresentation(get(), "");
227                     }
228                 }
229                 else if (request->getRequestType() == "PUT")
230                 {
231                     std::cout<<"\t\t\trequestType : PUT"<<std::endl;
232
233                     OCRepresentation rep = request->getResourceRepresentation();
234                     put(rep);
235
236                     if(response)
237                     {
238                         response->setErrorCode(200);
239                         response->setResourceRepresentation(get(), "");
240                     }
241                 }
242                 else
243                 {
244                     std::cout<<"\t\t\trequestType : UNSUPPORTED: "<<request->getRequestType()<<std::endl;
245                 }
246             }
247             else
248             {
249                 std::cout <<"\t\trequestFlag : UNSUPPORTED: ";
250
251                 if(request->getRequestHandlerFlag()==RequestHandlerFlag::InitFlag)
252                 {
253                     std::cout<<"InitFlag"<<std::endl;
254                 }
255                 else if(request->getRequestHandlerFlag()== RequestHandlerFlag::ObserverFlag)
256                 {
257                     std::cout<<"ObserverFlag"<<std::endl;
258                 }
259             }
260         }
261         else
262         {
263             std::cout << "Request Invalid!"<<std::endl;
264         }
265     }
266
267 };
268 int main()
269 {
270     PlatformConfig cfg {
271         OC::ServiceType::InProc,
272         OC::ModeType::Both,
273         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
274         0,         // Uses randomly available port
275         OC::QualityOfService::NonConfirmable
276     };
277
278     FooResource fooRes;
279
280     try
281     {
282         OCPlatform platform(cfg);
283
284         if(!fooRes.createResource(platform))
285         {
286             return -1;
287         }
288
289         ClientWorker cw;
290         cw.start(platform);
291     }
292     catch(OCException& e)
293     {
294         std::cout<< "Exception in main: "<<e.what()<<std::endl;
295     }
296 }