iotivity 0.9.0
[platform/upstream/iotivity.git] / resource / examples / fridgeclient.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 /// This fridgeclient represents a client trying to discover the associated
22 /// fridgeserver.  The device resource is the only one available for discovery
23 /// on the server, so we have to take the fact that we know the device tag
24 /// to then generate a Resource object
25
26 #include <iostream>
27 #include <stdexcept>
28 #include <condition_variable>
29 #include <mutex>
30 #include "OCPlatform.h"
31 #include "OCApi.h"
32
33 using namespace OC;
34 namespace PH = std::placeholders;
35
36 // Option ID for API version and client token
37 const uint16_t API_VERSION = 2048;
38 const uint16_t TOKEN = 3000;
39
40 class ClientFridge
41 {
42     public:
43     ClientFridge()
44     {
45         std::cout << "Fridge Client has started " <<std::endl;
46         FindCallback f (std::bind(&ClientFridge::foundDevice, this, PH::_1));
47
48         OCStackResult result = OCPlatform::findResource(
49                 "", "coap://224.0.1.187/oc/core?rt=intel.fridge", f);
50
51         if(OC_STACK_OK != result)
52         {
53             throw new std::runtime_error("Fridge Find Resource Failed");
54         }
55
56         std::cout << "Waiting to discover fridge... "<<std::endl;
57         {
58             // we want to block this thread until the client has finished
59             // its duties, so we block on the CV until we have completed
60             // what we are looking to do
61             std::unique_lock<std::mutex> lk(m_mutex);
62             m_cv.wait(lk);
63         }
64     }
65
66     private:
67     void foundDevice(std::shared_ptr<OCResource> resource)
68     {
69         using namespace OC::OCPlatform;
70         if(resource && resource->uri() == "/device")
71         {
72             std::cout << "Discovered a device object"<<std::endl;
73             std::cout << "\tHost: "<<resource->host()<<std::endl;
74             std::cout << "\tURI:  "<<resource->uri() <<std::endl;
75         }
76
77         // we have now found a resource, so lets create a few resource objects
78         // for the other resources that we KNOW are associated with the intel.fridge
79         // server, and query them.
80         std::vector<std::string> lightTypes = {"intel.fridge.light"};
81         std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
82         OCResource::Ptr light = constructResourceObject(resource->host(),
83                                 "/light", false, lightTypes, ifaces);
84
85         if(!light)
86         {
87             std::cout << "Error: Light Resource Object construction returned null\n";
88             return;
89         }
90
91         std::vector<std::string> doorTypes = {"intel.fridge.door"};
92
93         OCResource::Ptr leftdoor = constructResourceObject(resource->host(),
94                                 "/door/left", false, doorTypes, ifaces);
95         if(!leftdoor)
96         {
97             std::cout << "Error: Left Door Resource Object construction returned null\n";
98             return;
99         }
100
101         OCResource::Ptr rightdoor = constructResourceObject(resource->host(),
102                                 "/door/right", false, doorTypes, ifaces);
103         if(!rightdoor)
104         {
105             std::cout << "Error: Right Door Resource Object construction returned null\n";
106             return;
107         }
108
109         OCResource::Ptr randomdoor = constructResourceObject(resource->host(),
110                                 "/door/random", false, doorTypes, ifaces);
111         if(!randomdoor)
112         {
113             std::cout << "Error: Random Door Resource Object construction returned null\n";
114             return;
115         }
116
117         // Set header options with API version and token
118         HeaderOptions headerOptions;
119         try
120         {
121             // Set API version and client token
122             HeaderOption::OCHeaderOption apiVersion(API_VERSION, "v.1.0");
123             HeaderOption::OCHeaderOption clientToken(TOKEN, "21ae43gf");
124             headerOptions.push_back(apiVersion);
125             headerOptions.push_back(clientToken);
126         }
127         catch(OCException& e)
128         {
129             std::cout << "Error creating HeaderOption: " << e.what() << std::endl;
130         }
131
132
133         // Setting header options will send above options in all requests
134         // Header options are set per resource.
135         // Below, header options are set only for device resource
136         resource->setHeaderOptions(headerOptions);
137
138         resource->get(QueryParamsMap(), GetCallback(
139                 std::bind(&ClientFridge::getResponse, this, "Device", PH::_1,
140                     PH::_2, PH::_3, resource, 0)
141                 ));
142         light->get(QueryParamsMap(), GetCallback(
143                 std::bind(&ClientFridge::getResponse, this, "Fridge Light", PH::_1,
144                     PH::_2, PH::_3, light, 1)
145                 ));
146         leftdoor->get(QueryParamsMap(), GetCallback(
147                 std::bind(&ClientFridge::getResponse, this, "Left Door", PH::_1,
148                     PH::_2, PH::_3, leftdoor, 2)
149                 ));
150         rightdoor->get(QueryParamsMap(), GetCallback(
151                 std::bind(&ClientFridge::getResponse, this, "Right Door", PH::_1,
152                     PH::_2, PH::_3, rightdoor, 3)
153                 ));
154         randomdoor->get(QueryParamsMap(), GetCallback(
155                 std::bind(&ClientFridge::getResponse, this, "Random Door", PH::_1,
156                     PH::_2, PH::_3, randomdoor, 4)
157                 ));
158         resource->deleteResource(DeleteCallback(
159                 std::bind(&ClientFridge::deleteResponse, this, "Device", PH::_1,
160                     PH::_2, resource, 0)
161                 ));
162     }
163
164     // Note that resourceName, resource, and getId are all bound via the std::bind mechanism.
165     // it is possible to attach ANY arbitrary data to do whatever you would like here.  It may,
166     // however be a better fit to wrap each call in an object so a fuller context (and additional
167     // requests) can be easily made inside of a simple context
168     void getResponse(const std::string& resourceName, const HeaderOptions& headerOptions,
169                 const OCRepresentation rep, const int eCode, OCResource::Ptr resource, int getId)
170     {
171         std::cout << "Got a response from get from the " << resourceName << std::endl;
172         std::cout << "Get ID is "<<getId<<" and resource URI is " << resource->uri() << std::endl;
173
174         printHeaderOptions(headerOptions);
175
176         std::cout << "The Attribute Data is: "<<std::endl;
177
178         switch(getId)
179         {
180             case 0:
181                 {
182                     // Get on device
183                     std::string name;
184                     rep.getValue("device_name", name);
185                     std::cout << "Name of device: "<< name << std::endl;
186                     break;
187                 }
188             case 1:
189                 {
190                     bool isOn = false;
191                     rep.getValue("on",isOn);
192                     std::cout<<"The fridge light is "<< ((isOn)?"":"not ") <<"on"<<std::endl;
193                 }
194                 break;
195             case 2:
196             case 3:
197                 {
198                     bool isOpen = false;
199                     std::string side;
200                     rep.getValue("open", isOpen);
201                     rep.getValue("side", side);
202                     std::cout << "Door is "<<isOpen<<" and is on the "<<side<<std::endl;
203                 }
204                 break;
205             case 4:
206                 {
207                     // Get on random resource called.
208                     std::string name;
209                     rep.getValue("device_name", name);
210                     std::cout << "Name of fridge: "<< name << std::endl;
211                     break;
212                 }
213         }
214     }
215
216     //Callback function to handle response for deleteResource call.
217     void deleteResponse(const std::string& resourceName, const HeaderOptions& headerOptions,
218                 const int eCode, OCResource::Ptr resource, int deleteId)
219     {
220         std::cout << "Got a response from delete from the "<< resourceName << std::endl;
221         std::cout << "Delete ID is "<<deleteId<<" and resource URI is "<<resource->uri()<<std::endl;
222         printHeaderOptions(headerOptions);
223     }
224
225     //Function to print the headerOptions received from the server
226     void printHeaderOptions(const HeaderOptions& headerOptions)
227     {
228         for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it)
229         {
230             if(it->getOptionID() == API_VERSION)
231             {
232                 std::cout << "Server API version in GET response: " <<
233                         it->getOptionData() << std::endl;
234             }
235         }
236     }
237
238     std::mutex m_mutex;
239     std::condition_variable m_cv;
240 };
241
242 int main()
243 {
244     PlatformConfig cfg
245     {
246         ServiceType::InProc,
247         ModeType::Client,
248         "0.0.0.0",
249         0,
250         QualityOfService::LowQos
251     };
252
253     OCPlatform::Configure(cfg);
254     ClientFridge cf;
255     return 0;
256 }