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