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