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