replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / resource / provisioning / examples / subownerclient.cpp
1 /* *****************************************************************
2  *
3  * Copyright 2016 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 <stdio.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <string>
25 #include <map>
26 #include <cstdlib>
27 #include <pthread.h>
28 #include <mutex>
29 #include <condition_variable>
30
31 #include "logger.h"
32 #include "oic_malloc.h"
33 #include "oic_string.h"
34 #include "OCPlatform.h"
35 #include "OCApi.h"
36 #include "OCProvisioningManager.hpp"
37 #include "oxmjustworks.h"
38 #include "oxmrandompin.h"
39 #include "aclresource.h"
40 #include "utlist.h"
41
42 #define MAX_PERMISSION_LENGTH (5)
43 #define ACL_RESRC_ARRAY_SIZE (3)
44 #define CREATE (1)
45 #define READ (2)
46 #define UPDATE (4)
47 #define DELETE (8)
48 #define NOTIFY (16)
49 #define DASH '-'
50 #define PREDEFINED_TIMEOUT (10)
51 #define MAX_OWNED_DEVICE (10)
52 #define TAG  "subownerclient"
53
54 #define JSON_DB_PATH "./oic_svr_db_subowner_client.json"
55 #define DAT_DB_PATH "./oic_svr_db_subowner_client.dat"
56 #define DEV_STATUS_ON "DEV_STATUS_ON"
57 #define DEV_STATUS_OFF "DEV_STATUS_OFF"
58
59 #define DISCOVERY_TIMEOUT 5
60
61 using namespace OC;
62
63 DeviceList_t pMOwnedDeviceList, pMOTEnabledDeviceList;
64 static int transferDevIdx, ask = 1;
65
66 static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
67 {
68     (void)UNUSED_PARAM;
69     return fopen(DAT_DB_PATH, mode);
70 }
71
72 void printMenu()
73 {
74     std::cout << "\nChoose an option:"<<std::endl;
75     std::cout << "   1. Discover Multiple Ownership Transfer Enabled Devices"<<std::endl;
76     std::cout << "   2. Discover Multiple Owned Devices"<<std::endl;
77     std::cout << "   3. Perform the Multiple Ownership Transfer"<<std::endl;
78     std::cout << "   4. Get LED resource"<<std::endl;
79     std::cout << "   5. Get PUT resource"<<std::endl;
80     std::cout << "  99. Exit loop"<<std::endl;
81 }
82
83 void moveTransferredDevice()
84 {
85     pMOwnedDeviceList.push_back(pMOTEnabledDeviceList[transferDevIdx]);
86     pMOTEnabledDeviceList.erase(pMOTEnabledDeviceList.begin() + transferDevIdx);
87 }
88
89 void InputPinCB(char* pinBuf, size_t bufSize)
90 {
91     if(pinBuf)
92     {
93         std::cout <<"INPUT PIN : ";
94         std::string ptr;
95         std::cin >> ptr;
96         OICStrcpy(pinBuf, bufSize, ptr.c_str());
97         return;
98     }
99 }
100
101 void printUuid(OicUuid_t uuid)
102 {
103     for (int i = 0; i < UUID_LENGTH; i++)
104     {
105         std::cout <<std::hex << uuid.id[i] << " ";
106     }
107     std::cout<<std::endl;
108 }
109
110 void multipleOwnershipTransferCB(PMResultList_t *result, int hasError)
111 {
112     if (hasError)
113     {
114         std::cout << "Error!!! in MultipleOwnershipTransfer"<<std::endl;
115     }
116     else
117     {
118         std::cout<< "\nTransferred MultipleOwnership successfuly for device : ";
119         printUuid(result->at(0).deviceId);
120         delete result;
121
122         moveTransferredDevice();
123     }
124     ask = 1;
125 }
126
127 void printStatus(int status)
128 {
129     static std::map<int, std::string> devStatus = {{1<<0, DEV_STATUS_ON}, {1<<1, DEV_STATUS_OFF}};
130
131     std::cout <<devStatus[status] <<std::endl;
132 }
133
134 void printDevices(DeviceList_t &list)
135 {
136    for (unsigned int i = 0; i < list.size(); i++ )
137    {
138       std::cout << "Device "<< i+1 <<" ID: ";
139       std::cout << list[i]->getDeviceID() << " From IP: ";
140       std::cout << list[i]->getDevAddr() << std::endl;
141    }
142 }
143
144 static void getCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
145 {
146     (void)(headerOptions);
147     try
148     {
149         if (OC_STACK_OK == eCode)
150         {
151             std::cout << "Callback Context for GET query recvd successfully" << std::endl;
152             std::cout << "Resource URI: " << rep.getUri() << std::endl;
153
154             bool state = false;
155             int power = 0;
156             rep.getValue("state", state);
157             rep.getValue("power", power);
158
159             std::cout << "\tstate: " << state << std::endl;
160             std::cout << "\tpower: " << power << std::endl;
161         }
162         else
163         {
164             std::cout << "getCallback Response error: " << eCode << std::endl;
165         }
166     }
167     catch(std::exception& e)
168     {
169         std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
170     }
171 }
172
173 void putCallback(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
174 {
175     if(eCode == 0)
176     {
177         std::cout << "PUT request was successful !!!!!!" << std::endl;
178     }
179     else
180     {
181         std::cout << "onPut Response error !!!!!: " << eCode << std::endl;
182     }
183 }
184
185 int main(void)
186 {
187     OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
188
189     // Create PlatformConfig object
190     PlatformConfig cfg {
191         OC::ServiceType::InProc,
192             OC::ModeType::Both,
193             "0.0.0.0",
194             0,
195             OC::QualityOfService::LowQos,
196             &ps
197     };
198
199     OCPlatform::Configure(cfg);
200
201     //set Input Pin callback
202     OCSecure::setInputPinCallback(InputPinCB);
203
204     try
205     {
206         int choice;
207         OicSecAcl_t *acl1 = nullptr, *acl2 = nullptr;
208         if (OCSecure::provisionInit("subowner_pdm.db") != OC_STACK_OK)
209         {
210             std::cout <<"PM Init failed"<< std::endl;
211             return 1;
212         }
213
214         for (int out = 0; !out;)
215         {
216             while (!ask)
217             {
218                 sleep(1);
219             }
220
221             printMenu();
222             std::cin >> choice;
223             switch(choice) {
224                 case 1:
225                     {
226                         pMOTEnabledDeviceList.clear();
227                         std::cout << "Started MOT enabled device discovery..." <<std::endl;
228                         OCStackResult result = OCSecure::discoverMultipleOwnerEnabledDevices(
229                                 DISCOVERY_TIMEOUT, pMOTEnabledDeviceList);
230                         if (result != OC_STACK_OK)
231                         {
232                             std::cout<< "!!Error - MOT enabled dev Discovery failed."<<std::endl;
233                         }
234                         else if (pMOTEnabledDeviceList.size())
235                         {
236                             std::cout <<"Found MOT enabled devices, count = " <<
237                                 pMOTEnabledDeviceList.size() << std::endl;
238                             printDevices(pMOTEnabledDeviceList);
239                         }
240                         else
241                         {
242                             std::cout <<"NO MOT enabled devices found"<<std::endl;
243                         }
244                         break;
245                     }
246                 case 2:
247                     {
248                         pMOwnedDeviceList.clear();
249                         std::cout << "Started Multiple Owned device discovery..." <<std::endl;
250                         OCStackResult result = OCSecure::discoverMultipleOwnerEnabledDevices(
251                                 DISCOVERY_TIMEOUT, pMOwnedDeviceList);
252                         if (result != OC_STACK_OK)
253                         {
254                             std::cout<< "!!Error - Multiple Owned dev Discovery failed."<<std::endl;
255                         }
256                         else if (pMOwnedDeviceList.size())
257                         {
258                             std::cout <<"Found Multiple Owned devices, count = " <<
259                                 pMOwnedDeviceList.size() << std::endl;
260                             printDevices(pMOwnedDeviceList);
261                         }
262                         else
263                         {
264                             std::cout <<"NO Multiple Owned devices found"<<std::endl;
265                         }
266                         break;
267                     }
268                 case 3:
269                     {  //Multiple Ownrship Trasfer
270                         unsigned int devNum;
271
272                         if (!pMOTEnabledDeviceList.size())
273                         {
274                             std::cout <<"There are no MOT enabled devices"<<std::endl;
275                             break;
276                         }
277
278                         for (unsigned int i = 0; i < pMOTEnabledDeviceList.size(); i++ )
279                         {
280                             std::cout << i+1 << ": "<< pMOTEnabledDeviceList[i]->getDeviceID();
281                             std::cout << " From IP:" << pMOTEnabledDeviceList[i]->getDevAddr() <<std::endl;
282                         }
283
284                         std::cout <<"Select device number: "<<std::endl;
285                         std::cin >> devNum;
286                         if (devNum > pMOTEnabledDeviceList.size())
287                         {
288                             std::cout <<"Invalid device number"<<std::endl;
289                             break;
290                         }
291                         transferDevIdx = devNum - 1;
292
293                         ask = 0;
294                         std::cout << "MOT for : "<<
295                             pMOTEnabledDeviceList[devNum-1]->getDeviceID()<<std::endl;
296                         if (pMOTEnabledDeviceList[devNum-1]->doMultipleOwnershipTransfer
297                                 (multipleOwnershipTransferCB)
298                                 != OC_STACK_OK)
299                         {
300                             std::cout<<"Multiple OwnershipTransferCallback is failed"<<std::endl;
301                             ask = 1;
302                         }
303                         break;
304                     }
305                 case 4:
306                     {
307                         std::cout << "- Send data(GET Request) to device(led server) -" << std::endl;
308                         printDevices(pMOwnedDeviceList);
309                         printMenu();
310                         std::cout << "Enter device number to GET data: ";
311                         std::cin >> choice;
312                         choice--;
313
314                         std::vector<std::string> ledTypes = {"core.led"};
315                         std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
316
317                         OCProvisionDev_t *selDev = pMOwnedDeviceList[choice]->getDevPtr();
318                         std::stringstream host;
319                         host << "coaps:://";
320                         host << pMOwnedDeviceList[choice]->getDevAddr();
321                         host << selDev->securePort;
322
323                         OCResource::Ptr led = OC::OCPlatform::constructResourceObject(
324                                 host.str(), "/a/led", selDev->connType, false, ledTypes, ifaces);
325
326                         if(!led)
327                         {
328                             std::cout << "Error: Led Object construction returned null" << std::endl;
329                             break;
330                         }
331                         OCStackResult res = led->get(QueryParamsMap(), getCallback);
332
333                         if (OC_STACK_OK != res)
334                         {
335                             std::cout << "Error: get Failed for Led" << std::endl;
336                         }
337                         break;
338                     }
339                     break;
340                 case 5:
341                     {
342                         std::cout << "- Send data(Put Request) to device(led server) -" << std::endl;
343                         printDevices(pMOwnedDeviceList);
344                         printMenu();
345                         std::cout << "Enter device number to GET data: ";
346                         std::cin >> choice;
347                         choice--;
348
349                         std::vector<std::string> ledTypes = {"core.led"};
350                         std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
351
352
353                         OCProvisionDev_t *selDev = pMOwnedDeviceList[choice]->getDevPtr();
354                         std::stringstream host;
355                         host << "coaps:://";
356                         host << pMOwnedDeviceList[choice]->getDevAddr();
357                         host << selDev->securePort;
358
359                         OCResource::Ptr led = OC::OCPlatform::constructResourceObject(host.str(),
360                                 "/a/led", selDev->connType, false, ledTypes, ifaces);
361
362                         if(!led)
363                         {
364                             std::cout << "Error: Led Object construction returned null" << std::endl;
365                             break;
366                         }
367                         OCRepresentation rep;
368                         bool state = true;
369                         int power = 39;
370                         rep.setValue("state", state);
371                         rep.setValue("power", power);
372                         OCStackResult res = led->put(rep, QueryParamsMap(), putCallback);
373
374                         if (OC_STACK_OK != res)
375                         {
376                             std::cout << "Error: put Failed for Led" << std::endl;
377                         }
378                         break;
379                     }
380                     break;
381                 case 99:
382                 default:
383                     out = 1;
384                     break;
385             }
386         }
387     }
388     catch(OCException& e)
389     {
390         oclog() << "Exception in main: "<<e.what();
391     }
392
393     return 0;
394 }