ce7f7e1065543f113441f3e71110c77ccc26485e
[platform/upstream/iotivity.git] / resource / csdk / security / provisioning / sample / cloud / cloudCommon.c
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 <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "ocstack.h"
25 #include "logger.h"
26 #include "camutex.h"
27 #include "cathreadpool.h"
28 #include "ocpayload.h"
29 #include "payload_logging.h"
30 #include "aclresource.h"
31 #include "crlresource.h"
32 #include "ocprovisioningmanager.h"
33 #include "casecurityinterface.h"
34 #include "mbedtls/ssl_ciphersuites.h"
35
36 #include "utils.h"
37 #include "cloudAuth.h"
38 #include "cloudCommon.h"
39 #include "cloudWrapper.h"
40 #include "cloudDiscovery.h"
41
42 #ifdef __unix__
43 #include <unistd.h> //for unlink
44 #endif
45
46 #define TAG "cloudCommon"
47
48 #define DEFAULT_HOST            "10.113.68.85"//"127.0.0.1"
49 #define DEFAULT_PORT            OC_MULTICAST_PORT
50 #define DEFAULT_AUTH_PROVIDER   "github"
51 #define DEFAULT_DB_FILE         "./cloud.dat"
52 #define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s
53
54 #define GITHUB_AUTH_LINK        "https://github.com/login?return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dea9c18f540323b0213d0%26redirect_uri%3Dhttp%253A%252F%252Fwww.example.com%252Foauth_callback%252F"
55
56 #define CLIENT_ONLY(mode)       if (OC_SERVER == (mode)) { wrongRequest(); sendDataToServer = false; break; }
57
58 static bool fExit = false;
59
60 static ca_thread_pool_t g_threadPoolHandle = NULL;
61 static OCDevAddr endPoint;
62 static char token[1024] = "";
63 static char authProvider[1024] = DEFAULT_AUTH_PROVIDER;
64 static char *fname = DEFAULT_DB_FILE;
65 static uint64_t timeout;
66 static uint16_t g_credId = 0;
67
68 static ca_cond cond;
69 static ca_mutex mutex;
70
71 typedef enum {
72     SIGN_UP       = 1,
73     SIGN_IN       = 2,
74     SIGN_OUT      = 3,
75
76     HOST          = 4,
77     PORT          = 5,
78     DB_FILE       = 6,
79     AUTH_PROVIDER = 7,
80     USE_RSA = 8,
81     SAVE_TRUST_CERT = 9,
82     USE_SECURE_CONN = 10,
83
84     DISCOVERY     = 13,
85     GET           = 14,
86     PUT           = 15,
87     POST          = 16,
88
89     CSR_SIGN      = 19,
90
91     CRL_GET       = 20,
92     CRL_POST      = 21,
93
94     ACL_ID_CREATE = 30,
95     ACL_ID_GET_BY_DEVICE = 31,
96     ACL_ID_DELETE = 32,
97
98     ACL_INDIVIDUAL_GET_INFO = 40,
99     ACL_INDIVIDUAL_UPDATE_ACE = 41,
100     ACL_INDIVIDUAL_UPDATE = 42,
101     ACL_INDIVIDUAL_DELETE = 43,
102     ACL_INDIVIDUAL_DELETE_ACE = 44,
103
104     ACL_GROUP_CREATE = 50,
105     ACL_GROUP_FIND   = 51,
106     ACL_GROUP_JOIN   = 52,
107     ACL_GROUP_OBSERVE= 53,
108     ACL_GROUP_DELETE = 54,
109
110     ACL_GROUP_SHARE_DEVICE  = 60,
111     ACL_GROUP_DELETE_DEVICE  = 61,
112     ACL_GROUP_GET_INFO  = 62,
113
114     ACL_POLICY_CHECK_REQUEST = 70,
115
116     ACL_GROUP_INVITE_USER = 80,
117     ACL_GROUP_GET_INVITE  = 81,
118     ACL_GROUP_DELETE_INVITE  = 82,
119     ACL_GROUP_CANCEL_INVITE  = 83,
120
121     EXIT          = 99
122 }CloudRequest;
123
124 static void printMenu(OCMode mode)
125 {
126     char *title = "Client";
127     if (OC_SERVER == mode)
128     {
129         title = "Server";
130     }
131     printf("************************************************************\n");
132     printf("****************** Cloud %s Requests *******************\n", title);
133     printf("************************************************************\n");
134     printf("** AUTHORIZATION\n");
135     printf("** %d - Sign Up request\n", SIGN_UP);
136     printf("** %d - Sign In request\n", SIGN_IN);
137     printf("** %d - Sign Out request\n", SIGN_OUT);
138
139     printf("** SETTINGS \n");
140     printf("** %d - Change default host\n", HOST);
141     printf("** %d - Change default port\n", PORT);
142     printf("** %d - Change default database filename\n", DB_FILE);
143     printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
144     printf("** %d - Change TLS cipher suite (ECDSA/RSA)\n", USE_RSA);
145     printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
146     printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
147
148     if (OC_CLIENT == mode)
149     {
150         printf("** DISCOVERY\n");
151         printf("** %d - Start Discovery\n", DISCOVERY);
152         printf("** %d - Get Request\n", GET);
153         printf("** %d - Put Request\n", PUT);
154         printf("** %d - Post Request\n", POST);
155     }
156
157     printf("** CERTIFICATE REQUEST\n");
158     printf("** %d - Certificate Request\n", CSR_SIGN);
159
160     printf("** CRL\n");
161     printf("** %d - CRL GET Request\n", CRL_GET);
162     printf("** %d - CRL POST Request\n", CRL_POST);
163
164     printf("** ACL MANAGER\n");
165     printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
166     printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
167     printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
168
169     printf("** ACL INDIVIDUAL\n");
170     printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
171     printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
172     printf("** %d - ACL individual update Request\n", ACL_INDIVIDUAL_UPDATE);
173     printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
174     printf("** %d - ACL individual delete ACE Request\n", ACL_INDIVIDUAL_DELETE_ACE);
175
176     printf("** ACL GROUP MANAGER\n");
177     printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
178     printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
179     printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
180     printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
181     printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
182
183     printf("** ACL INDIVIDUAL GROUP\n");
184     printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
185     printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
186     printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
187
188     printf("** ACL POLICY ENFORCEMENT\n");
189     printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
190
191     printf("** ACL MEMBER INVITATION\n");
192     printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
193     printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
194     printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
195     printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
196
197     printf("** EXIT\n");
198     printf("** %d - Exit cloud %s\n", EXIT, title);
199     printf("************************************************************\n");
200 }
201
202 void unlockMenu(void *data)
203 {
204     OICFree(data);
205
206     if (!fExit)
207     {
208         ca_mutex_lock(mutex);
209         ca_cond_signal(cond);
210         ca_mutex_unlock(mutex);
211     }
212 }
213
214 /**
215  * This is default callback to all requests
216  * Used to sync with main menu
217  *
218  * @param[in] ctx          context
219  * @param[in] result       result
220  * @param[in] data         data
221  */
222 static void handleCB(void* ctx, OCStackResult result, void* data)
223 {
224     OC_UNUSED(ctx);
225     OC_UNUSED(data);
226
227     OIC_LOG_V(INFO, TAG, "%s: Received result = %d", __func__, result);
228
229     unlockMenu(NULL);
230 }
231
232 /**
233  * This function prints Acl id and calls default callback function handleCB()
234  *
235  * @param[in] ctx          context
236  * @param[in] result       result
237  * @param[in] aclId        acl id
238  */
239 static void handleAclIdCB(void* ctx, OCStackResult result, void* aclId)
240 {
241     OIC_LOG_V(INFO, TAG, "Received Acl id = %s", (char *)aclId);
242     handleCB(ctx, result, aclId);
243     OICFree(aclId);
244 }
245
246 /**
247  * This function prints group id and calls default callback function handleCB()
248  *
249  * @param[in] ctx          context
250  * @param[in] result       result
251  * @param[in] groupId      group id
252  */
253 static void handleAclCreateGroupCB(void* ctx, OCStackResult result, void* groupId)
254 {
255     OIC_LOG_V(INFO, TAG, "Received gid = %s", (char *)groupId);
256     handleCB(ctx, result, groupId);
257     OICFree(groupId);
258 }
259
260 /**
261  * This function prints group policy and calls default callback function handleCB()
262  *
263  * @param[in] ctx          context
264  * @param[in] result       result
265  * @param[in] gp           group policy
266  */
267 static void handleAclPolicyCheckCB(void* ctx, OCStackResult result, void* gp)
268 {
269     OIC_LOG_V(INFO, TAG, "Received gp = %s", (char *)gp);
270     handleCB(ctx, result, gp);
271     OICFree(gp);
272 }
273
274 /**
275  * This function prints received acl and calls default callback function handleCB()
276  *
277  * @param[in] ctx          context
278  * @param[in] result       result
279  * @param[in] acl          acl
280  */
281 static void handleAclIndividualGetInfoCB(void* ctx, OCStackResult result, void* acl)
282 {
283     printACL((OicSecAcl_t* )acl);
284     handleCB(ctx, result, acl);
285     //can't delete acl here because its ACE's were added to gAcl
286     //TODO: changes in aclresources.c required to fix that
287 }
288
289 /**
290  * This function prints received group id list and calls default callback function handleCB()
291  *
292  * @param[in] ctx          context
293  * @param[in] result       result
294  * @param[in] gidList      group id list
295  */
296 static void handleAclFindMyGroupCB(void* ctx, OCStackResult result, void* gidList)
297 {
298     printStringArray((stringArray_t *)gidList);
299     handleCB(ctx, result, gidList);
300     clearStringArray((stringArray_t *)gidList);
301 }
302
303 /**
304  * This function prints received acl and calls default callback function handleCB()
305  *
306  * @param[in] ctx          context
307  * @param[in] result       result
308  * @param[in] crl          crl
309  */
310 static void handleGetCrlCB(void* ctx, OCStackResult result, void* crl)
311 {
312     printCrl((OicSecCrl_t *)crl);
313     handleCB(ctx, result, crl);
314     DeleteCrl((OicSecCrl_t *)crl);
315 }
316
317 /**
318  * This function prints received invitation response and calls default callback function handleCB()
319  *
320  * @param[in] ctx          context
321  * @param[in] result       result
322  * @param[in] invite       invitation response (it has inviteResponse_t* type)
323  */
324 static void handleAclGetInvitationCB(void* ctx, OCStackResult result, void* invite)
325 {
326     printInviteResponse((inviteResponse_t *)invite);
327     handleCB(ctx, result, invite);
328     clearInviteResponse((inviteResponse_t *)invite);
329     OICFree(invite);
330 }
331
332 static OCStackResult saveTrustCert(void)
333 {
334     OCStackResult res = OC_STACK_ERROR;
335     OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
336
337     ByteArray_t trustCertChainArray = {0, 0};
338     const char *filename = "rootca.crt";
339
340     if (!readFile(filename, (OCByteString *)&trustCertChainArray))
341     {
342         OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
343         OICFree(((OCByteString *)&trustCertChainArray)->bytes);
344         return OC_STACK_ERROR;
345     }
346     OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
347
348     res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
349
350     if (OC_STACK_OK != res)
351     {
352         OIC_LOG(ERROR, TAG, "OCSaveTrustCertChain API error");
353     }
354     else
355     {
356         OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
357     }
358     OICFree(trustCertChainArray.data);
359
360     return res;
361 }
362
363 static void wrongRequest()
364 {
365     printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
366 }
367
368 static void userRequests(void *data)
369 {
370     if (NULL == data)
371     {
372         OIC_LOG(ERROR, TAG, "Received NULL data");
373         return;
374     }
375
376     OCMode mode = *(OCMode*)data;
377
378     memset(&endPoint, 0, sizeof(endPoint));
379     strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
380     endPoint.port = DEFAULT_PORT;
381
382     mutex = ca_mutex_new();
383     cond = ca_cond_new();
384
385     while (false == fExit)
386     {
387         OCStackResult res = OC_STACK_ERROR;
388         bool sendDataToServer = true;
389         timeout = DEFAULT_RESPONSE_WAIT_TIME;
390         //startup report
391         printf("-----------------------------------------------------------\n");
392         printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
393         printf("via auth provider: %s\n", authProvider);
394         printf("srv file: %s\n", fname);
395         printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
396         printf("-----------------------------------------------------------\n");
397
398         printMenu(mode);
399
400         int request = 0;
401         readInteger(&request, "Menu number", "see above");
402
403         switch (request)
404         {
405         case SIGN_UP:
406             if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
407             {
408                 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
409             }
410             readString(token, sizeof(token), "auth token", "check link above");
411             res = CloudSignUp(&endPoint, authProvider, token);
412             break;
413         case SIGN_IN:
414             res = CloudSignIn(&endPoint);
415             break;
416         case SIGN_OUT:
417             res = CloudSignOut(&endPoint);
418             break;
419         case HOST:
420             readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
421             sendDataToServer = false;
422             break;
423         case PORT:
424         {
425             char example[8];
426             snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
427             int tmp = 0;
428             readInteger(&tmp, "port number", example);
429             endPoint.port = tmp;
430             sendDataToServer = false;
431         }
432         break;
433         case CRL_GET:
434             res = OCWrapperGetCRL(&endPoint, handleGetCrlCB);
435             break;
436         case CRL_POST:
437             res = OCWrapperPostCRL(&endPoint, handleCB);
438             break;
439         case ACL_GROUP_CREATE:
440             res = OCWrapperAclCreateGroup(&endPoint, handleAclCreateGroupCB);
441             break;
442         case ACL_GROUP_FIND:
443             res = OCWrapperAclFindMyGroup(&endPoint, handleAclFindMyGroupCB);
444             break;
445         case ACL_GROUP_DELETE:
446             res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
447             break;
448         case ACL_GROUP_JOIN:
449             res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
450             break;
451         case ACL_GROUP_OBSERVE:
452             res = OCWrapperAclObserveGroup(&endPoint, handleCB);
453             break;
454         case ACL_GROUP_SHARE_DEVICE:
455             res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
456             break;
457         case ACL_GROUP_DELETE_DEVICE:
458             res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
459             break;
460         case ACL_GROUP_GET_INFO:
461             res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
462             break;
463         case ACL_GROUP_INVITE_USER:
464             res = OCWrapperAclInviteUser(&endPoint, handleCB);
465             break;
466         case ACL_GROUP_GET_INVITE:
467             res = OCWrapperAclGetInvitation(&endPoint, handleAclGetInvitationCB);
468             break;
469         case ACL_GROUP_DELETE_INVITE:
470             res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
471             break;
472         case ACL_GROUP_CANCEL_INVITE:
473             res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
474             break;
475         case ACL_POLICY_CHECK_REQUEST:
476             res = OCWrapperAclPolicyCheck(&endPoint, handleAclPolicyCheckCB);
477             break;
478         case ACL_ID_GET_BY_DEVICE:
479             res = OCWrapperAclIdGetByDevice(&endPoint, handleAclIdCB);
480             break;
481         case ACL_ID_CREATE:
482             res = OCWrapperAclIdCreate(&endPoint, handleAclIdCB);
483             break;
484         case ACL_ID_DELETE:
485             res = OCWrapperAclIdDelete(&endPoint, handleCB);
486             break;
487         case ACL_INDIVIDUAL_GET_INFO:
488             res = OCWrapperAclIndividualGetInfo(&endPoint, handleAclIndividualGetInfoCB);
489             break;
490         case ACL_INDIVIDUAL_UPDATE_ACE:
491             res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
492             break;
493         case ACL_INDIVIDUAL_UPDATE:
494             res = OCWrapperAclIndividualUpdate(&endPoint, handleCB);
495             break;
496         case ACL_INDIVIDUAL_DELETE:
497             res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
498             break;
499         case ACL_INDIVIDUAL_DELETE_ACE:
500             res = OCWrapperAclIndividualDeleteAce(&endPoint, handleCB);
501             break;
502         case CSR_SIGN:
503             res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
504             break;
505         case DISCOVERY:
506             CLIENT_ONLY(mode);
507             res = InitDiscovery();
508             break;
509         case GET:
510             CLIENT_ONLY(mode);
511             res = InitRequest(OC_REST_GET);
512             break;
513         case PUT:
514             CLIENT_ONLY(mode);
515             res= InitRequest(OC_REST_PUT);
516             break;
517         case POST:
518             CLIENT_ONLY(mode);
519             res= InitRequest(OC_REST_POST);
520             break;
521         case USE_RSA:
522         {
523             int tmp = 0;
524             readInteger(&tmp, "Select Cipher Suite", "0 - ECDSA, other - RSA");
525             uint16_t cipher = tmp? MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA:
526                                    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
527             if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP))
528             {
529                 OIC_LOG(ERROR, TAG, "CASelectCipherSuite returned an error");
530             }
531             sendDataToServer = false;
532         }
533             break;
534         case SAVE_TRUST_CERT:
535             saveTrustCert();
536             sendDataToServer = false;
537             break;
538         case USE_SECURE_CONN:
539         {
540             int tmp = 0;
541             readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
542             setCoapPrefix(0 == tmp ? false : true);
543             sendDataToServer = false;
544         }
545             break;
546         case EXIT:
547             ca_mutex_free(mutex);
548             ca_cond_free(cond);
549             fExit = true;
550             sendDataToServer = false;
551             break;
552         default:
553             wrongRequest();
554             sendDataToServer = false;
555             break;
556         }
557
558         //if requests were sent then wait response
559         if (sendDataToServer)
560         {
561             if (OC_STACK_OK == res)
562             {
563                 ca_mutex_lock(mutex);
564                 ca_cond_wait_for(cond, mutex, timeout);
565                 ca_mutex_unlock(mutex);
566             }
567             else
568             {
569                 OIC_LOG_V(ERROR, TAG, "Request returned an error %d", res);
570             }
571         }
572     }
573 }
574
575 FILE* server_fopen(const char *path, const char *mode)
576 {
577     OC_UNUSED(path);
578     return fopen(fname, mode);
579 }
580
581 /**
582  * Check file accessibility
583  *
584  * @param[in] name        file path
585  * @return true           if check was successful
586  */
587 static bool checkConfig(const char *name)
588 {
589     FILE* file = fopen(name, "rb");
590
591     if (file)
592     {
593         fclose(file);
594         return true;
595     }
596     return false;
597 }
598
599 static void printUsage(char *name)
600 {
601     printf("Wrong arguments count!\n");
602     printf("Usage : %s <database_filename>\n", name);
603     printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
604 }
605
606 bool parseCommandLineArguments(int argc, char *argv[])
607 {
608     bool result = true;
609     if (2 == argc)
610     {
611         fname = argv[1];
612
613         if (!checkConfig(fname))
614         {
615             OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
616             result = false;
617         }
618     }
619     else if (argc > 2)
620     {
621         printUsage(argv[0]);
622         result = false;
623     }
624     return result;
625 }
626
627 OCStackResult initPersistentStorage()
628 {
629     //Initialize Persistent Storage for SVR database
630     static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
631
632     return OCRegisterPersistentStorageHandler(&ps);
633 }
634
635 OCStackResult startRequestsThread(OCMode *mode)
636 {
637     CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
638     if (CA_STATUS_OK != res)
639     {
640         OIC_LOG(ERROR, TAG, "thread pool initialize error.");
641         return res;
642     }
643
644     res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
645     if (CA_STATUS_OK != res)
646     {
647         OIC_LOG(ERROR, TAG, "thread pool add task error.");
648         ca_thread_pool_free(g_threadPoolHandle);
649     }
650     return res;
651 }
652
653 OCStackResult initProcess(OCMode mode)
654 {
655     return OCInit(NULL, 0, mode);
656 }
657
658 void startProcess()
659 {
660     while(false == fExit)
661     {
662         if (OCProcess() != OC_STACK_OK)
663         {
664             OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
665             break;
666         }
667     }
668
669     if (OCStop() != OC_STACK_OK)
670     {
671         OIC_LOG(ERROR, TAG, "OCStop process error\n");
672     }
673 }
674
675 void freeThreadResources()
676 {
677     if (g_threadPoolHandle)
678     {
679         ca_thread_pool_free(g_threadPoolHandle);
680     }
681 }