aa124dcc1f7ad6eebad1e370a4ea9fbf57272eba
[platform/upstream/iotivity.git] / resource / provisioning / examples / cloudWrapper.cpp
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22
23 #include "logger.h"
24 #include "occloudprovisioning.h"
25 #include "OCCloudProvisioning.hpp"
26 #include "oic_malloc.h"
27 #include "oic_string.h"
28 #include "utils.h"
29
30 #define TAG "CLOUD-WRAPPER"
31
32 #define MAX_ID_LENGTH       (64)
33 #define MAX_STRING_LENGTH   (256)
34
35 #define UUID_EXAMPLE_1 "9cfbeb8e-5a1e-4d1c-9d01-2ae6fdb"
36 #define UUID_EXAMPLE_2 "123e4567-e89b-12d3-a456-4266554"
37 #define UUID_EXAMPLE_3 "987e6543-e21b-12d3-a456-4266554"
38 #define SUBJECT_ID_EXAMPLE "72616E64-5069-6E44-6576-557569643030"
39
40 #define ACL_ID_EXAMPLE "0f3d9f7fe5491d54077d"
41 #define ACE_ID_EXAMPLE "a0001"
42
43 #define ID_EXAMPLE_1   "78f98b4f25f21e2487e8"
44 #define ID_EXAMPLE_2   "6caa7009386290fd3681"
45
46 #define RESOURCE_URI_EXAMPLE "/a/light/0"
47 #define RESOURCE_TYPE_EXAMPLE "core.light"
48 #define INTERFACE_EXAMPLE "oic.if.baseline"
49
50 //in case of optional parameters absence should be sent NULL
51 #define OPTIONAL(str) (str[0] ? str : NULL)
52
53 using namespace OC;
54
55 static bool readOptional(const char* description)
56 {
57     if (NULL == description)
58     {
59         return false;
60     }
61
62     printf("Do you want to Enter %s (y/n):\n", description);
63     char choice = 0;
64
65     while(1)
66     {
67         scanf("%c", &choice);
68         getchar();
69
70         switch (choice)
71         {
72             case 'y': return true;
73             case 'n': return false;
74             default: printf("Wrong value entered. Please press 'y' or 'n'\n");
75         }
76     }
77     return false;
78 }
79
80 /**
81  * Read user input (expect string value)
82  *
83  * @param[out] item           string item to fill
84  * @param[in] length          max allowed string length
85  * @param[in] description     item description
86  * @param[in] example         item example
87  */
88 void readString(char* item, int length, const char* description, const char* example)
89 {
90     printf("Enter %s (f.e. %s):\n", description, example);
91     char temp[8] = { 0 };
92     snprintf(temp, sizeof(temp), "%%%ds", length - 1);
93     scanf(temp, item);
94     getchar();
95 }
96
97 /**
98  * Read user input (expect string value, but it is optional and can be skipped by user)
99  *
100  * @param[out] item           string item to fill
101  * @param[in] length          max allowed string length
102  * @param[in] description     item description
103  * @param[in] example         item example
104  */
105 static void readOptionalString(char* item, int length, const char* description, const char* example)
106 {
107     if (readOptional(description))
108     {
109         readString(item, length, description, example);
110     }
111 }
112
113 /**
114  * Read user input (expect integer value)
115  *
116  * @param[out] item           integer item to fill
117  * @param[in] description     item description
118  * @param[in] example         item example
119  */
120 void readInteger(int* item, const char* description, const char* example)
121 {
122     printf("Enter %s (f.e. %s):\n", description, example);
123     scanf("%d", item);
124     getchar();
125 }
126
127 /**
128  * Read user input (expect array of strings)
129  *
130  * @param[out] list           array of strings structure
131  * @param[in] length          max allowed array item length
132  * @param[in] description     whole array description
133  * @param[in] example         array item example
134  */
135 static void readStringArray(stringArray_t *list, int length, const char* description, const char* example)
136 {
137     int i = 0;
138     int count = 0;
139     char hint[MAX_STRING_LENGTH] = { 0 };
140
141     snprintf(hint, sizeof(hint), "%s items count", description);
142     readInteger(&count, hint, "2");
143
144     char **item = NULL;
145
146     if (0 >= count)
147     {
148         return;
149     }
150
151     item = (char**)OICCalloc(count, sizeof(char*));
152
153     if (NULL == item)
154     {
155         goto no_memory;
156     }
157
158     for (i = 0; i < count; i++)
159     {
160         item[i] = (char*)OICCalloc(length, sizeof(char));
161
162         if (NULL == item[i])
163         {
164             goto no_memory;
165         }
166
167         snprintf(hint, sizeof(hint), "%s %d item", description, i + 1);
168         readString(item[i], length, hint, example);
169     }
170     list->array  = item;
171     list->length = (size_t)count;
172     return;
173
174 no_memory:
175     //free already allocated memory here
176     for (int k = 0; k < i; k++)
177     {
178         OICFree(item[k]);
179     }
180     OICFree(item);
181 }
182
183 /**
184  * Read user input (expect array of strings)
185  * It is optional and can be skipped by user.
186  *
187  * @param[out] list           array of strings structure
188  * @param[in] length          max allowed array item length
189  * @param[in] description     whole array description
190  * @param[in] example         array item example
191  */
192 static void readOptionalStringArray(stringArray_t *list, int length, const char* description, const char* example)
193 {
194     if (readOptional(description))
195     {
196         readStringArray(list, length, description, example);
197     }
198 }
199
200 /**
201  * Copies whole binary file to crl variable
202  *
203  * @param[in] list           array of strings structure
204  * @param[out] crl           byte array to fill
205  * @return                   negative error code
206  * */
207 static int ReadFile(const char *name, OCByteString *crl)
208 {
209     FILE *file = NULL;
210     int length = 0;
211     uint8_t *buffer = NULL;
212     int result = 1;
213     size_t realLen = 0;
214
215     //Open file
216     file = fopen(name, "rb");
217     if (!file)
218     {
219         OIC_LOG_V(ERROR, TAG, "Unable to open file %s", name);
220         return result;
221     }
222
223     //Get file length
224     result = fseek(file, 0, SEEK_END);
225     if (result)
226     {
227         OIC_LOG(ERROR, TAG, "Failed to SEEK_END");
228         goto exit;
229     }
230
231     length = ftell(file);
232     if (length < 0)
233     {
234         OIC_LOG(ERROR, TAG, "Failed to ftell");
235         goto exit;
236     }
237
238     result = fseek(file, 0, SEEK_SET);
239     if (result)
240     {
241         OIC_LOG(ERROR, TAG, "Failed to SEEK_SET");
242         goto exit;
243     }
244
245     //Allocate memory
246     buffer = (uint8_t *)malloc(length);
247     if (!buffer)
248     {
249         OIC_LOG(ERROR, TAG, "Failed to allocate buffer");
250         goto exit;
251     }
252
253     //Read file contents into buffer
254     realLen = fread(buffer, length, 1, file);
255     if (realLen != (size_t)length)
256     {
257         OIC_LOG_V(ERROR, TAG, "Length mismatch: read %zu instead of %d bytes", realLen, length);
258         goto exit;
259     }
260
261     crl->bytes = buffer;
262     crl->len   = (size_t)length;
263
264     result = 0;
265 exit:
266     fclose(file);
267     return 0;
268 }
269
270 OCStackResult OCWrapperCertificateIssueRequest(OCCloudProvisioning& ptr, ResponseCallBack callback)
271 {
272     return ptr.requestCertificate(callback);
273 }
274
275 OCStackResult OCWrapperGetCRL(OCCloudProvisioning& ptr, ResponseCallBack callback)
276 {
277     return ptr.getCRL(callback);
278 }
279
280 OCStackResult OCWrapperPostCRL(OCCloudProvisioning& ptr, ResponseCallBack callback)
281 {
282     OCStackResult result = OC_STACK_ERROR;
283     OCByteString crlData = {0, 0};
284     char filename[64] = {0};
285     char thisUpdate[16] = { 0 };
286     char nextUpdate[16] = { 0 };
287     stringArray_t serialNumbers = {0, 0};
288     stringArray_t *rcsn = 0;
289     OCByteString *crl = 0;
290
291     readString(thisUpdate, sizeof(thisUpdate), "Crl's thisUpdate value", "20160727000000");
292     readString(nextUpdate, sizeof(nextUpdate), "Crl's nextUpdate value", "20161027000000");
293     readOptionalStringArray(&serialNumbers, 16, "Revoked serial numbers", "1234");
294
295     if (NULL == serialNumbers.array)
296     {
297         readString(filename, sizeof(filename),
298                    "filename from which binary Crl in DER format will be read", "crl");
299
300         if (ReadFile(filename, &crlData))
301         {
302             printf("Can't read crl from file %s\n", filename);
303             goto exit;
304         }
305     }
306     rcsn = serialNumbers.array? &serialNumbers : NULL;
307     crl = crlData.bytes? &crlData : NULL;
308
309     result = ptr.postCRL(thisUpdate, nextUpdate, crl, rcsn,
310                              callback);
311 exit:
312     clearStringArray(&serialNumbers);
313     OICFree(crlData.bytes);
314
315     return result;
316 }
317
318 OCStackResult OCWrapperAclIdGetByDevice(OCCloudProvisioning& ptr, AclIdResponseCallBack callback)
319 {
320     char di[MAX_ID_LENGTH] = { 0 };
321
322     readString(di, sizeof(di), "device id", UUID_EXAMPLE_1);
323
324     return ptr.getAclIdByDevice(di, callback);
325 }
326
327 OCStackResult OCWrapperAclIdCreate(const OCDevAddr *endPoint, OCCloudResponseCB callback)
328 {
329     char oid[MAX_ID_LENGTH]  = { 0 };
330     char di[MAX_ID_LENGTH]   = { 0 };
331
332     readString(oid, sizeof(oid), "owner id", UUID_EXAMPLE_2);
333     readString(di, sizeof(di), "device id", UUID_EXAMPLE_1);
334
335     return OCCloudAclIdCreate(NULL, oid, di, endPoint, callback);
336 }
337
338 OCStackResult OCWrapperAclIdDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback)
339 {
340     char aclid[MAX_ID_LENGTH] = { 0 };
341
342     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
343
344     return OCCloudAclIdDelete(NULL, aclid, endPoint, callback);
345 }
346
347 OCStackResult OCWrapperAclIndividualGetInfo(OCCloudProvisioning& ptr, ResponseCallBack callback)
348 {
349     char aclid[MAX_ID_LENGTH] = { 0 };
350
351     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
352
353     return ptr.getIndividualAclInfo(aclid, callback);
354 }
355
356 OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback)
357 {
358     OCStackResult result = OC_STACK_NO_MEMORY;
359     int i = 0, j = 0;
360     cloudAce_t *aces = NULL;
361
362     char aclid[MAX_ID_LENGTH] = { 0 };
363     readString(aclid, sizeof(aclid), "ace id", ACL_ID_EXAMPLE);
364
365     int acllist_count = 0;
366     readInteger(&acllist_count, "acl list count", "1");
367     if (0 >= acllist_count)
368     {
369         OIC_LOG(ERROR, TAG, "Wrong number of aclList");
370         goto exit;
371     }
372
373     aces = (cloudAce_t*)OICCalloc(acllist_count, sizeof(cloudAce_t));
374     if (!aces)
375     {
376         OIC_LOG(ERROR, TAG, "Can't allocate memory for aces");
377         goto exit;
378     }
379
380     for (i = 0; i < acllist_count; i++)
381     {
382         cloudAce_t *ace = &aces[i];
383         if (i != acllist_count - 1) ace->next = &aces[i + 1];
384
385         char aceid[MAX_ID_LENGTH] = { 0 };
386         char subjectuuid[MAX_ID_LENGTH] = { 0 };
387         int stype = 0;
388         int permission = 0;
389
390         readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
391         readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE);
392         readInteger(&stype, "subject type", "0 â€“ Device, 1 â€“ User, 2 - Group");
393         readInteger(&permission, "permission", "6");
394
395         ace->aceId = OICStrdup(aceid);
396         ace->stype = stype;
397         ace->permission = permission;
398         memcpy(&ace->subjectuuid, subjectuuid, sizeof(OicUuid_t));
399
400         int reslist_count = 0;
401         readInteger(&reslist_count, "resources list count", "1");
402
403         ace->resources = (OicSecRsrc_t*)OICCalloc(reslist_count, sizeof(OicSecRsrc_t));
404         if (!ace->resources)
405         {
406             OIC_LOG(ERROR, TAG, "Can't allocate memory for resources");
407             goto exit;
408         }
409
410         for (j = 0; j < reslist_count; j++)
411         {
412             OicSecRsrc_t *res = &ace->resources[j];
413             if (j != reslist_count - 1) res->next = &ace->resources[j + 1];
414
415             char href[32] = { 0 };
416             readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE);
417
418             stringArray_t rt = {0, 0};
419             readStringArray(&rt, MAX_ID_LENGTH, "resource type", RESOURCE_TYPE_EXAMPLE);
420
421             stringArray_t _if = {0, 0};
422             readStringArray(&_if, MAX_ID_LENGTH, "interface", INTERFACE_EXAMPLE);
423
424             res->href = OICStrdup(href);
425             res->types = rt.array;
426             res->typeLen = rt.length;
427             res->interfaces = _if.array;
428             res->interfaceLen = _if.length;
429         }
430     }
431
432     result = OCCloudAclIndividualUpdateAce(NULL, aclid, aces, endPoint, callback);
433 exit:
434     if (aces)
435     {
436         for (int k = 0; k < i; k++)
437         {
438             cloudAce_t *ace = &aces[k];
439             OICFree(ace->aceId);
440
441             if (ace->resources)
442             {
443                 for (int l = 0; l < j; l++)
444                 {
445                     OicSecRsrc_t *res = &ace->resources[l];
446                     OICFree(res->href);
447
448                     stringArray_t rt { res->types, res->typeLen};
449                     clearStringArray(&rt);
450
451                     stringArray_t _if {res->interfaces, res->interfaceLen};
452                     clearStringArray(&_if);
453                 }
454             }
455
456         }
457     }
458     return result;
459 }
460
461 OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback)
462 {
463     char aclid[MAX_ID_LENGTH] = { 0 };
464
465     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
466
467     return OCCloudAclIndividualDelete(NULL, aclid, endPoint, callback);
468 }
469
470 OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
471 {
472     char gtype[16] = { 0 };
473     char gmid[MAX_ID_LENGTH] = { 0 };
474
475     readString(gtype, sizeof(gtype), "Group type value", "Public");
476     readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
477
478     return OCCloudAclCreateGroup(NULL, gtype, OPTIONAL(gmid), endPoint, callback);
479 }
480
481 OCStackResult OCWrapperAclFindMyGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
482 {
483     char mid[MAX_ID_LENGTH]  = { 0 };
484
485     readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
486
487     return OCCloudAclFindMyGroup(NULL, OPTIONAL(mid), endPoint, callback);
488 }
489
490 OCStackResult OCWrapperAclDeleteGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
491 {
492     char gid[MAX_ID_LENGTH]  = { 0 };
493     char gmid[MAX_ID_LENGTH] = { 0 };
494
495     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
496
497     readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
498
499     return OCCloudAclDeleteGroup(NULL, gid, OPTIONAL(gmid), endPoint, callback);
500 }
501
502 OCStackResult OCWrapperAclJoinToInvitedGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
503 {
504     char gid[MAX_ID_LENGTH]  = { 0 };
505
506     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
507
508     return OCCloudAclJoinToInvitedGroup(NULL, gid, endPoint, callback);
509 }
510
511 OCStackResult OCWrapperAclObserveGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
512 {
513     char gid[MAX_ID_LENGTH]  = { 0 };
514
515     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
516
517     return OCCloudAclObserveGroup(NULL, gid, endPoint, callback);
518 }
519
520 OCStackResult OCWrapperAclShareDeviceIntoGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
521 {
522     OCStackResult result = OC_STACK_NO_MEMORY;
523     char gid[MAX_ID_LENGTH]  = { 0 };
524     stringArray_t midlist = {0,0};
525     stringArray_t dilist = {0,0};
526
527     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
528
529     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
530
531     readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1);
532
533     result = OCCloudAclShareDeviceIntoGroup(NULL, gid, &midlist, &dilist, endPoint, callback);
534
535     clearStringArray(&midlist);
536     clearStringArray(&dilist);
537
538     return result;
539 }
540
541 OCStackResult OCWrapperAclDeleteDeviceFromGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
542 {
543     OCStackResult result = OC_STACK_NO_MEMORY;
544     char gid[MAX_ID_LENGTH]  = { 0 };
545     stringArray_t midlist = {0,0};
546     stringArray_t dilist = {0,0};
547
548     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
549
550     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
551
552     readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1);
553
554     result = OCCloudAclDeleteDeviceFromGroup(NULL, gid, &midlist, &dilist, endPoint, callback);
555
556     clearStringArray(&midlist);
557     clearStringArray(&dilist);
558
559     return result;
560 }
561
562 OCStackResult OCWrapperAclGroupGetInfo(const OCDevAddr *endPoint, OCCloudResponseCB callback)
563 {
564     char gid[MAX_ID_LENGTH]  = { 0 };
565     char mid[MAX_ID_LENGTH]  = { 0 };
566
567     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
568
569     readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
570
571     return OCCloudAclGroupGetInfo(NULL, gid, OPTIONAL(mid), endPoint, callback);
572 }
573
574 OCStackResult OCWrapperAclInviteUser(const OCDevAddr *endPoint, OCCloudResponseCB callback)
575 {
576     OCStackResult result = OC_STACK_NO_MEMORY;
577     char uid[MAX_ID_LENGTH]  = { 0 };
578     stringArray_t midlist = {0,0};
579     stringArray_t gidlist = {0,0};
580
581     readOptionalString(uid, sizeof(uid), "user id value", UUID_EXAMPLE_2);
582
583     readStringArray(&gidlist, MAX_ID_LENGTH, "group id list", UUID_EXAMPLE_1);
584
585     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
586
587     result = OCCloudAclInviteUser(NULL, OPTIONAL(uid), &gidlist, &midlist, endPoint, callback);
588
589     clearStringArray(&midlist);
590     clearStringArray(&gidlist);
591
592     return result;
593 }
594
595 OCStackResult OCWrapperAclGetInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
596 {
597     char uid[MAX_ID_LENGTH]  = { 0 };
598
599     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
600
601     return OCCloudAclGetInvitation(NULL, OPTIONAL(uid), endPoint, callback);
602 }
603
604 OCStackResult OCWrapperAclDeleteInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
605 {
606     char uid[MAX_ID_LENGTH]  = { 0 };
607     char gid[MAX_ID_LENGTH]  = { 0 };
608
609     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
610     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
611
612     return OCCloudAclDeleteInvitation(NULL, OPTIONAL(uid), gid, endPoint, callback);
613 }
614
615 OCStackResult OCWrapperAclCancelInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
616 {
617     char uid[MAX_ID_LENGTH]  = { 0 };
618     char gid[MAX_ID_LENGTH]  = { 0 };
619     char mid[MAX_ID_LENGTH]  = { 0 };
620
621     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
622
623     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
624     readString(mid, sizeof(mid), "member id value", ID_EXAMPLE_1);
625
626     return OCCloudAclCancelInvitation(NULL, OPTIONAL(uid), gid, mid, endPoint, callback);
627 }
628
629 OCStackResult OCWrapperAclPolicyCheck(const OCDevAddr *endPoint, OCCloudResponseCB callback)
630 {
631     char sid[MAX_ID_LENGTH] = { 0 };
632     char di[MAX_ID_LENGTH]  = { 0 };
633     char rm[16]  = { 0 };
634     char user_uri[32] = { 0 };
635
636     readString(sid, sizeof(sid), "subject id", UUID_EXAMPLE_1);
637     readString(di, sizeof(di), "device id", UUID_EXAMPLE_2);
638     readString(rm, sizeof(rm), "request method", "GET or POST or DELETE");
639     readString(user_uri, sizeof(user_uri), "request uri", RESOURCE_URI_EXAMPLE);
640
641     return OCCloudAclPolicyCheck(NULL, sid, di, rm, user_uri, endPoint, callback);
642 }