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