[IOT-2912]cloud sample
[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  * Read user input (expect integer value)
135  *
136  * @param[out] item           size_t item to fill
137  * @param[in] description     item description
138  * @param[in] example         item example
139  */
140 void readSize(size_t* item, const char* description, const char* example)
141 {
142     printf("Enter %s (f.e. %s):\n", description, example);
143     if (scanf("%zd", item))
144     {
145         getchar();
146     }
147 }
148
149
150 /**
151  * Read user input (expect array of strings)
152  *
153  * @param[out] list           array of strings structure
154  * @param[in] length          max allowed array item length
155  * @param[in] description     whole array description
156  * @param[in] example         array item example
157  */
158 static void readStringArray(stringArray_t *list, int length, const char* description, const char* example)
159 {
160     size_t i = 0;
161     size_t count = 0;
162     char hint[MAX_STRING_LENGTH] = { 0 };
163
164     snprintf(hint, sizeof(hint), "%s items count", description);
165     readSize(&count, hint, "2");
166
167     char **item = NULL;
168
169     if (0 == count || 10 * 1024 < count)
170     {
171         return;
172     }
173
174     item = (char**)OICCalloc(count, sizeof(char*));
175
176     if (NULL == item)
177     {
178         goto no_memory;
179     }
180
181     for (i = 0; i < count; i++)
182     {
183         item[i] = (char*)OICCalloc(length, sizeof(char));
184
185         if (NULL == item[i])
186         {
187             goto no_memory;
188         }
189
190         snprintf(hint, sizeof(hint), "%s %zd item", description, i + 1);
191         readString(item[i], length, hint, example);
192     }
193     list->array  = item;
194     list->length = count;
195     return;
196
197 no_memory:
198     //free already allocated memory here
199     for (size_t k = 0; k < i; k++)
200     {
201         OICFree(item[k]);
202     }
203     OICFree(item);
204 }
205
206 /**
207  * Read user input (expect array of strings)
208  * It is optional and can be skipped by user.
209  *
210  * @param[out] list           array of strings structure
211  * @param[in] length          max allowed array item length
212  * @param[in] description     whole array description
213  * @param[in] example         array item example
214  */
215 static void readOptionalStringArray(stringArray_t *list, int length, const char* description, const char* example)
216 {
217     if (readOptional(description))
218     {
219         readStringArray(list, length, description, example);
220     }
221 }
222
223 /**
224  * Copies whole binary file to crl variable
225  *
226  * @param[in] list           array of strings structure
227  * @param[out] crl           byte array to fill
228  * @return                   negative error code
229  * */
230 static int ReadFile(const char *name, OCByteString *crl)
231 {
232     FILE *file = NULL;
233     int length = 0;
234     uint8_t *buffer = NULL;
235     int result = 1;
236     size_t realLen = 0;
237
238     //Open file
239     file = fopen(name, "rb");
240     if (!file)
241     {
242         OIC_LOG_V(ERROR, TAG, "Unable to open file %s", name);
243         return result;
244     }
245
246     //Get file length
247     result = fseek(file, 0, SEEK_END);
248     if (result)
249     {
250         OIC_LOG(ERROR, TAG, "Failed to SEEK_END");
251         goto exit;
252     }
253
254     length = ftell(file);
255     if (length < 0)
256     {
257         OIC_LOG(ERROR, TAG, "Failed to ftell");
258         goto exit;
259     }
260
261     result = fseek(file, 0, SEEK_SET);
262     if (result)
263     {
264         OIC_LOG(ERROR, TAG, "Failed to SEEK_SET");
265         goto exit;
266     }
267
268     //Allocate memory
269     buffer = (uint8_t *)malloc(length);
270     if (!buffer)
271     {
272         OIC_LOG(ERROR, TAG, "Failed to allocate buffer");
273         goto exit;
274     }
275
276     //Read file contents into buffer
277     realLen = fread(buffer, length, 1, file);
278     if (realLen != (size_t)length)
279     {
280         OIC_LOG_V(ERROR, TAG, "Length mismatch: read %" PRIuPTR " instead of %d bytes", realLen, length);
281         goto exit;
282     }
283
284     crl->bytes = buffer;
285     crl->len   = (size_t)length;
286
287     result = 0;
288 exit:
289     fclose(file);
290     return 0;
291 }
292
293 OCStackResult OCWrapperCertificateIssueRequest(OCCloudProvisioning& ptr, ResponseCallBack callback)
294 {
295     return ptr.requestCertificate(callback);
296 }
297
298 OCStackResult OCWrapperGetCRL(OCCloudProvisioning& ptr, ResponseCallBack callback)
299 {
300     return ptr.getCRL(callback);
301 }
302
303 OCStackResult OCWrapperPostCRL(OCCloudProvisioning& ptr, ResponseCallBack callback)
304 {
305     OCStackResult result = OC_STACK_ERROR;
306     OCByteString crlData = {0, 0};
307     char filename[64] = {0};
308     char thisUpdate[16] = { 0 };
309     char nextUpdate[16] = { 0 };
310     stringArray_t serialNumbers = {0, 0};
311     stringArray_t *rcsn = 0;
312     OCByteString *crl = 0;
313
314     readString(thisUpdate, sizeof(thisUpdate), "Crl's thisUpdate value", "20160727000000");
315     readString(nextUpdate, sizeof(nextUpdate), "Crl's nextUpdate value", "20161027000000");
316     readOptionalStringArray(&serialNumbers, 16, "Revoked serial numbers", "1234");
317
318     if (NULL == serialNumbers.array)
319     {
320         readString(filename, sizeof(filename),
321                    "filename from which binary Crl in DER format will be read", "crl");
322
323         if (ReadFile(filename, &crlData))
324         {
325             printf("Can't read crl from file %s\n", filename);
326             goto exit;
327         }
328     }
329     rcsn = serialNumbers.array? &serialNumbers : NULL;
330     crl = crlData.bytes? &crlData : NULL;
331
332     result = ptr.postCRL(thisUpdate, nextUpdate, crl, rcsn,
333                              callback);
334 exit:
335     clearStringArray(&serialNumbers);
336     OICFree(crlData.bytes);
337
338     return result;
339 }
340
341 OCStackResult OCWrapperAclIdGetByDevice(OCCloudProvisioning& ptr, AclIdResponseCallBack callback)
342 {
343     char di[MAX_ID_LENGTH] = { 0 };
344
345     readString(di, sizeof(di), "device id", UUID_EXAMPLE_1);
346
347     return ptr.getAclIdByDevice(di, callback);
348 }
349
350 OCStackResult OCWrapperAclIdCreate(const OCDevAddr *endPoint, OCCloudResponseCB callback)
351 {
352     char oid[MAX_ID_LENGTH]  = { 0 };
353     char di[MAX_ID_LENGTH]   = { 0 };
354
355     readString(oid, sizeof(oid), "owner id", UUID_EXAMPLE_2);
356     readString(di, sizeof(di), "device id", UUID_EXAMPLE_1);
357
358     return OCCloudAclIdCreate(NULL, oid, di, endPoint, callback);
359 }
360
361 OCStackResult OCWrapperAclIdDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback)
362 {
363     char aclid[MAX_ID_LENGTH] = { 0 };
364
365     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
366
367     return OCCloudAclIdDelete(NULL, aclid, endPoint, callback);
368 }
369
370 OCStackResult OCWrapperAclIndividualGetInfo(OCCloudProvisioning& ptr, ResponseCallBack callback)
371 {
372     char aclid[MAX_ID_LENGTH] = { 0 };
373
374     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
375
376     return ptr.getIndividualAclInfo(aclid, callback);
377 }
378
379 OCStackResult OCWrapperAclIndividualUpdateAce(const OCDevAddr *endPoint, OCCloudResponseCB callback)
380 {
381     OCStackResult result = OC_STACK_NO_MEMORY;
382     int i = 0, j = 0;
383     cloudAce_t *aces = NULL;
384
385     char aclid[MAX_ID_LENGTH] = { 0 };
386     readString(aclid, sizeof(aclid), "ace id", ACL_ID_EXAMPLE);
387
388     int acllist_count = 0;
389     readInteger(&acllist_count, "acl list count", "1");
390     if (0 >= acllist_count || 1024 < acllist_count)
391     {
392         OIC_LOG(ERROR, TAG, "Wrong number of aclList");
393         goto exit;
394     }
395
396     aces = (cloudAce_t*)OICCalloc(acllist_count, sizeof(cloudAce_t));
397     if (!aces)
398     {
399         OIC_LOG(ERROR, TAG, "Can't allocate memory for aces");
400         goto exit;
401     }
402
403     for (i = 0; i < acllist_count; i++)
404     {
405         cloudAce_t *ace = &aces[i];
406         if (i != acllist_count - 1) ace->next = &aces[i + 1];
407
408         char aceid[MAX_ID_LENGTH] = { 0 };
409         char subjectuuid[MAX_ID_LENGTH] = { 0 };
410         int stype = 0;
411         int permission = 0;
412
413         readString(aceid, sizeof(aceid), "ace id", ACE_ID_EXAMPLE);
414         readString(subjectuuid, sizeof(subjectuuid), "subjectuuid", SUBJECT_ID_EXAMPLE);
415         readInteger(&stype, "subject type", "0 – Device, 1 – User, 2 - Group");
416         readInteger(&permission, "permission", "6");
417
418         ace->aceId = OICStrdup(aceid);
419         ace->stype = stype;
420         ace->permission = permission;
421         memcpy(&ace->subjectuuid, subjectuuid, sizeof(OicUuid_t));
422
423         int reslist_count = 0;
424         readInteger(&reslist_count, "resources list count", "1");
425
426         ace->resources = (OicSecRsrc_t*)OICCalloc(reslist_count, sizeof(OicSecRsrc_t));
427         if (!ace->resources)
428         {
429             OIC_LOG(ERROR, TAG, "Can't allocate memory for resources");
430             goto exit;
431         }
432
433         for (j = 0; j < reslist_count; j++)
434         {
435             OicSecRsrc_t *res = &ace->resources[j];
436             if (j != reslist_count - 1) res->next = &ace->resources[j + 1];
437
438             char href[32] = { 0 };
439             readString(href, sizeof(href), "href", RESOURCE_URI_EXAMPLE);
440
441             stringArray_t rt = {0, 0};
442             readStringArray(&rt, MAX_ID_LENGTH, "resource type", RESOURCE_TYPE_EXAMPLE);
443
444             stringArray_t _if = {0, 0};
445             readStringArray(&_if, MAX_ID_LENGTH, "interface", INTERFACE_EXAMPLE);
446
447             res->href = OICStrdup(href);
448             res->types = rt.array;
449             res->typeLen = rt.length;
450             res->interfaces = _if.array;
451             res->interfaceLen = _if.length;
452         }
453     }
454
455     result = OCCloudAclIndividualAclUpdate(NULL, aclid, aces, endPoint, callback);
456 exit:
457     if (aces)
458     {
459         for (int k = 0; k < i; k++)
460         {
461             cloudAce_t *ace = &aces[k];
462             OICFree(ace->aceId);
463
464             if (ace->resources)
465             {
466                 for (int l = 0; l < j; l++)
467                 {
468                     OicSecRsrc_t *res = &ace->resources[l];
469                     OICFree(res->href);
470
471                     stringArray_t rt {res->types, res->typeLen};
472                     clearStringArray(&rt);
473
474                     stringArray_t _if {res->interfaces, res->interfaceLen};
475                     clearStringArray(&_if);
476                 }
477             }
478
479         }
480     }
481     return result;
482 }
483
484 OCStackResult OCWrapperAclIndividualDelete(const OCDevAddr *endPoint, OCCloudResponseCB callback)
485 {
486     char aclid[MAX_ID_LENGTH] = { 0 };
487
488     readString(aclid, sizeof(aclid), "acl id", ACL_ID_EXAMPLE);
489
490     return OCCloudAclAcesDelete(NULL, aclid, endPoint, callback);
491 }
492
493 OCStackResult OCWrapperAclCreateGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
494 {
495     char gtype[16] = { 0 };
496     char gmid[MAX_ID_LENGTH] = { 0 };
497
498     readString(gtype, sizeof(gtype), "Group type value", "Public");
499     readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
500
501     return OCCloudAclCreateGroup(NULL, gtype, OPTIONAL(gmid), endPoint, callback);
502 }
503
504 OCStackResult OCWrapperAclFindMyGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
505 {
506     char mid[MAX_ID_LENGTH]  = { 0 };
507
508     readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
509
510     return OCCloudAclFindMyGroup(NULL, OPTIONAL(mid), endPoint, callback);
511 }
512
513 OCStackResult OCWrapperAclDeleteGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
514 {
515     char gid[MAX_ID_LENGTH]  = { 0 };
516     char gmid[MAX_ID_LENGTH] = { 0 };
517
518     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
519
520     readOptionalString(gmid, sizeof(gmid), "group member id value", UUID_EXAMPLE_2);
521
522     return OCCloudAclDeleteGroup(NULL, gid, OPTIONAL(gmid), endPoint, callback);
523 }
524
525 OCStackResult OCWrapperAclJoinToInvitedGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
526 {
527     char gid[MAX_ID_LENGTH]  = { 0 };
528
529     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
530
531     return OCCloudAclJoinToInvitedGroup(NULL, gid, endPoint, callback);
532 }
533
534 OCStackResult OCWrapperAclObserveGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
535 {
536     char gid[MAX_ID_LENGTH]  = { 0 };
537
538     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
539
540     return OCCloudAclObserveGroup(NULL, gid, endPoint, callback);
541 }
542
543 OCStackResult OCWrapperAclShareDeviceIntoGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
544 {
545     OCStackResult result = OC_STACK_NO_MEMORY;
546     char gid[MAX_ID_LENGTH]  = { 0 };
547     stringArray_t midlist = {0,0};
548     stringArray_t dilist = {0,0};
549
550     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
551
552     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
553
554     readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1);
555
556     result = OCCloudAclShareDeviceIntoGroup(NULL, gid, &midlist, &dilist, endPoint, callback);
557
558     clearStringArray(&midlist);
559     clearStringArray(&dilist);
560
561     return result;
562 }
563
564 OCStackResult OCWrapperAclDeleteDeviceFromGroup(const OCDevAddr *endPoint, OCCloudResponseCB callback)
565 {
566     OCStackResult result = OC_STACK_NO_MEMORY;
567     char gid[MAX_ID_LENGTH]  = { 0 };
568     stringArray_t midlist = {0,0};
569     stringArray_t dilist = {0,0};
570
571     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
572
573     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
574
575     readStringArray(&dilist, MAX_ID_LENGTH, "device list", UUID_EXAMPLE_1);
576
577     result = OCCloudAclDeleteDeviceFromGroup(NULL, gid, &midlist, &dilist, endPoint, callback);
578
579     clearStringArray(&midlist);
580     clearStringArray(&dilist);
581
582     return result;
583 }
584
585 OCStackResult OCWrapperAclGroupGetInfo(const OCDevAddr *endPoint, OCCloudResponseCB callback)
586 {
587     char gid[MAX_ID_LENGTH]  = { 0 };
588     char mid[MAX_ID_LENGTH]  = { 0 };
589
590     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
591
592     readOptionalString(mid, sizeof(mid), "member id value", UUID_EXAMPLE_2);
593
594     return OCCloudAclGroupGetInfo(NULL, gid, OPTIONAL(mid), endPoint, callback);
595 }
596
597 OCStackResult OCWrapperAclInviteUser(const OCDevAddr *endPoint, OCCloudResponseCB callback)
598 {
599     OCStackResult result = OC_STACK_NO_MEMORY;
600     char uid[MAX_ID_LENGTH]  = { 0 };
601     stringArray_t midlist = {0,0};
602     stringArray_t gidlist = {0,0};
603
604     readOptionalString(uid, sizeof(uid), "user id value", UUID_EXAMPLE_2);
605
606     readStringArray(&gidlist, MAX_ID_LENGTH, "group id list", UUID_EXAMPLE_1);
607
608     readStringArray(&midlist, MAX_ID_LENGTH, "member id list", UUID_EXAMPLE_2);
609
610     result = OCCloudAclInviteUser(NULL, OPTIONAL(uid), &gidlist, &midlist, endPoint, callback);
611
612     clearStringArray(&midlist);
613     clearStringArray(&gidlist);
614
615     return result;
616 }
617
618 OCStackResult OCWrapperAclGetInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
619 {
620     char uid[MAX_ID_LENGTH]  = { 0 };
621
622     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
623
624     return OCCloudAclGetInvitation(NULL, OPTIONAL(uid), endPoint, callback);
625 }
626
627 OCStackResult OCWrapperAclDeleteInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
628 {
629     char uid[MAX_ID_LENGTH]  = { 0 };
630     char gid[MAX_ID_LENGTH]  = { 0 };
631
632     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
633     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
634
635     return OCCloudAclDeleteInvitation(NULL, OPTIONAL(uid), gid, endPoint, callback);
636 }
637
638 OCStackResult OCWrapperAclCancelInvitation(const OCDevAddr *endPoint, OCCloudResponseCB callback)
639 {
640     char uid[MAX_ID_LENGTH]  = { 0 };
641     char gid[MAX_ID_LENGTH]  = { 0 };
642     char mid[MAX_ID_LENGTH]  = { 0 };
643
644     readOptionalString(uid, sizeof(uid), "user uuid value", UUID_EXAMPLE_2);
645
646     readString(gid, sizeof(gid), "Group id value", ID_EXAMPLE_1);
647     readString(mid, sizeof(mid), "member id value", ID_EXAMPLE_1);
648
649     return OCCloudAclCancelInvitation(NULL, OPTIONAL(uid), gid, mid, endPoint, callback);
650 }
651
652 OCStackResult OCWrapperAclPolicyCheck(const OCDevAddr *endPoint, OCCloudResponseCB callback)
653 {
654     char sid[MAX_ID_LENGTH] = { 0 };
655     char di[MAX_ID_LENGTH]  = { 0 };
656     char rm[16]  = { 0 };
657     char user_uri[32] = { 0 };
658
659     readString(sid, sizeof(sid), "subject id", UUID_EXAMPLE_1);
660     readString(di, sizeof(di), "device id", UUID_EXAMPLE_2);
661     readString(rm, sizeof(rm), "request method", "GET or POST or DELETE");
662     readString(user_uri, sizeof(user_uri), "request uri", RESOURCE_URI_EXAMPLE);
663
664     return OCCloudAclPolicyCheck(NULL, sid, di, rm, user_uri, endPoint, callback);
665 }