60d575799f2ce2fc25f5c64c3ca99a2e12475c34
[platform/upstream/iotivity.git] / 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         std::vector<std::string> doorTypes = {"intel.fridge.door"};
86
87         OCResource::Ptr leftdoor = constructResourceObject(resource->host(),
88                                 "/door/left", false, doorTypes, ifaces);
89         OCResource::Ptr rightdoor = constructResourceObject(resource->host(),
90                                 "/door/right", false, doorTypes, ifaces);
91         OCResource::Ptr randomdoor = constructResourceObject(resource->host(),
92                                 "/door/random", false, doorTypes, ifaces);
93
94         // Set header options with API version and token
95         HeaderOptions headerOptions;
96         try
97         {
98             // Set API version and client token
99             HeaderOption::OCHeaderOption apiVersion(API_VERSION, "v.1.0");
100             HeaderOption::OCHeaderOption clientToken(TOKEN, "21ae43gf");
101             headerOptions.push_back(apiVersion);
102             headerOptions.push_back(clientToken);
103         }
104         catch(OCException& e)
105         {
106             std::cout << "Error creating HeaderOption: " << e.what() << std::endl;
107         }
108
109
110         // Setting header options will send above options in all requests
111         // Header options are set per resource.
112         // Below, header options are set only for device resource
113         resource->setHeaderOptions(headerOptions);
114
115         resource->get(QueryParamsMap(), GetCallback(
116                 std::bind(&ClientFridge::getResponse, this, "Device", PH::_1,
117                     PH::_2, PH::_3, resource, 0)
118                 ));
119         light->get(QueryParamsMap(), GetCallback(
120                 std::bind(&ClientFridge::getResponse, this, "Fridge Light", PH::_1,
121                     PH::_2, PH::_3, light, 1)
122                 ));
123         leftdoor->get(QueryParamsMap(), GetCallback(
124                 std::bind(&ClientFridge::getResponse, this, "Left Door", PH::_1,
125                     PH::_2, PH::_3, leftdoor, 2)
126                 ));
127         rightdoor->get(QueryParamsMap(), GetCallback(
128                 std::bind(&ClientFridge::getResponse, this, "Right Door", PH::_1,
129                     PH::_2, PH::_3, rightdoor, 3)
130                 ));
131         randomdoor->get(QueryParamsMap(), GetCallback(
132                 std::bind(&ClientFridge::getResponse, this, "Random Door", PH::_1,
133                     PH::_2, PH::_3, randomdoor, 4)
134                 ));
135         resource->deleteResource(DeleteCallback(
136                 std::bind(&ClientFridge::deleteResponse, this, "Device", PH::_1,
137                     PH::_2, resource, 0)
138                 ));
139     }
140
141     // Note that resourceName, resource, and getId are all bound via the std::bind mechanism.
142     // it is possible to attach ANY arbitrary data to do whatever you would like here.  It may,
143     // however be a better fit to wrap each call in an object so a fuller context (and additional
144     // requests) can be easily made inside of a simple context
145     void getResponse(const std::string& resourceName, const HeaderOptions& headerOptions,
146                 const OCRepresentation rep, const int eCode, OCResource::Ptr resource, int getId)
147     {
148         std::cout << "Got a response from get from the " << resourceName << std::endl;
149         std::cout << "Get ID is "<<getId<<" and resource URI is " << resource->uri() << std::endl;
150
151         printHeaderOptions(headerOptions);
152
153         std::cout << "The Attribute Data is: "<<std::endl;
154
155         switch(getId)
156         {
157             case 0:
158                 {
159                     // Get on device
160                     std::string name;
161                     rep.getValue("device_name", name);
162                     std::cout << "Name of device: "<< name << std::endl;
163                     break;
164                 }
165             case 1:
166                 {
167                     bool isOn;
168                     rep.getValue("on",isOn);
169                     std::cout<<"The fridge light is "<< ((isOn)?"":"not ") <<"on"<<std::endl;
170                 }
171                 break;
172             case 2:
173             case 3:
174                 {
175                     bool isOpen;
176                     std::string side;
177                     rep.getValue("open", isOpen);
178                     rep.getValue("side", side);
179                     std::cout << "Door is "<<isOpen<<" and is on the "<<side<<std::endl;
180                 }
181                 break;
182             case 4:
183                 {
184                     // Get on random resource called.
185                     std::string name;
186                     rep.getValue("device_name", name);
187                     std::cout << "Name of fridge: "<< name << std::endl;
188                     break;
189                 }
190         }
191     }
192
193     //Callback function to handle response for deleteResource call.
194     void deleteResponse(const std::string& resourceName, const HeaderOptions& headerOptions,
195                 const int eCode, OCResource::Ptr resource, int deleteId)
196     {
197         std::cout << "Got a response from delete from the "<< resourceName << std::endl;
198         std::cout << "Delete ID is "<<deleteId<<" and resource URI is "<<resource->uri()<<std::endl;
199         printHeaderOptions(headerOptions);
200     }
201
202     //Function to print the headerOptions received from the server
203     void printHeaderOptions(const HeaderOptions& headerOptions)
204     {
205         for (auto it = headerOptions.begin(); it != headerOptions.end(); ++it)
206         {
207             if(it->getOptionID() == API_VERSION)
208             {
209                 std::cout << "Server API version in GET response: " <<
210                         it->getOptionData() << std::endl;
211             }
212         }
213     }
214
215     std::mutex m_mutex;
216     std::condition_variable m_cv;
217 };
218
219 int main()
220 {
221     PlatformConfig cfg
222     {
223         ServiceType::InProc,
224         ModeType::Client,
225         "0.0.0.0",
226         0,
227         QualityOfService::LowQos
228     };
229
230     OCPlatform::Configure(cfg);
231     ClientFridge cf;
232     return 0;
233 }