1 //******************************************************************
3 // Copyright 2016 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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"
35 #include "cloudAuth.h"
36 #include "cloudCommon.h"
37 #include "cloudWrapper.h"
38 #include "cloudDiscovery.h"
41 #include <unistd.h> //for unlink
44 #define TAG "cloudCommon"
46 #define DEFAULT_HOST "10.113.68.85"//"127.0.0.1"
47 #define DEFAULT_PORT OC_MULTICAST_PORT
48 #define DEFAULT_AUTH_PROVIDER "github"
49 #define DEFAULT_DB_FILE "./cloud.dat"
50 #define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s
52 #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"
54 #define CLIENT_ONLY(mode) if (OC_SERVER == (mode)) { wrongRequest(); sendDataToServer = false; break; }
56 static bool fExit = false;
58 static ca_thread_pool_t g_threadPoolHandle = NULL;
59 static OCDevAddr endPoint;
60 static char token[1024] = "";
61 static char authProvider[1024] = DEFAULT_AUTH_PROVIDER;
62 static char *fname = DEFAULT_DB_FILE;
63 static uint64_t timeout;
64 static uint16_t g_credId = 0;
67 static ca_mutex mutex;
93 ACL_ID_GET_BY_DEVICE = 31,
96 ACL_INDIVIDUAL_GET_INFO = 40,
97 ACL_INDIVIDUAL_UPDATE_ACE = 41,
98 ACL_INDIVIDUAL_DELETE = 42,
100 ACL_GROUP_CREATE = 50,
103 ACL_GROUP_OBSERVE= 53,
104 ACL_GROUP_DELETE = 54,
106 ACL_GROUP_SHARE_DEVICE = 60,
107 ACL_GROUP_DELETE_DEVICE = 61,
108 ACL_GROUP_GET_INFO = 62,
110 ACL_POLICY_CHECK_REQUEST = 70,
112 ACL_GROUP_INVITE_USER = 80,
113 ACL_GROUP_GET_INVITE = 81,
114 ACL_GROUP_DELETE_INVITE = 82,
115 ACL_GROUP_CANCEL_INVITE = 83,
120 static void printMenu(OCMode mode)
122 char *title = "Client";
123 if (OC_SERVER == mode)
127 printf("************************************************************\n");
128 printf("****************** Cloud %s Requests *******************\n", title);
129 printf("************************************************************\n");
130 printf("** AUTHORIZATION\n");
131 printf("** %d - Sign Up request\n", SIGN_UP);
132 printf("** %d - Sign In request\n", SIGN_IN);
133 printf("** %d - Sign Out request\n", SIGN_OUT);
135 printf("** SETTINGS \n");
136 printf("** %d - Change default host\n", HOST);
137 printf("** %d - Change default port\n", PORT);
138 printf("** %d - Change default database filename\n", DB_FILE);
139 printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
140 printf("** %d - Change TLS cipher suite to RSA\n", USE_RSA);
141 printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
142 printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
144 if (OC_CLIENT == mode)
146 printf("** DISCOVERY\n");
147 printf("** %d - Start Discovery\n", DISCOVERY);
148 printf("** %d - Get Request\n", GET);
149 printf("** %d - Put Request\n", PUT);
150 printf("** %d - Post Request\n", POST);
153 printf("** CERTIFICATE REQUEST\n");
154 printf("** %d - Certificate Request\n", CSR_SIGN);
157 printf("** %d - CRL GET Request\n", CRL_GET);
158 printf("** %d - CRL POST Request\n", CRL_POST);
160 printf("** ACL MANAGER\n");
161 printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
162 printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
163 printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
165 printf("** ACL INDIVIDUAL\n");
166 printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
167 printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
168 printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
170 printf("** ACL GROUP MANAGER\n");
171 printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
172 printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
173 printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
174 printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
175 printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
177 printf("** ACL INDIVIDUAL GROUP\n");
178 printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
179 printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
180 printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
182 printf("** ACL POLICY ENFORCEMENT\n");
183 printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
185 printf("** ACL MEMBER INVITATION\n");
186 printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
187 printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
188 printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
189 printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
192 printf("** %d - Exit cloud %s\n", EXIT, title);
193 printf("************************************************************\n");
196 void unlockMenu(void *data)
202 ca_mutex_lock(mutex);
203 ca_cond_signal(cond);
204 ca_mutex_unlock(mutex);
209 * This is default callback to all requests
210 * Used to sync with main menu
212 * @param[in] ctx context
213 * @param[in] result result
214 * @param[in] data data
216 static void handleCB(void* ctx, OCStackResult result, void* data)
221 OIC_LOG_V(INFO, TAG, "%s: Received result = %d", __func__, result);
227 * This function prints Acl id and calls default callback function handleCB()
229 * @param[in] ctx context
230 * @param[in] result result
231 * @param[in] aclId acl id
233 static void handleAclIdCB(void* ctx, OCStackResult result, void* aclId)
235 OIC_LOG_V(INFO, TAG, "Received Acl id = %s", (char *)aclId);
236 handleCB(ctx, result, aclId);
241 * This function prints group id and calls default callback function handleCB()
243 * @param[in] ctx context
244 * @param[in] result result
245 * @param[in] groupId group id
247 static void handleAclCreateGroupCB(void* ctx, OCStackResult result, void* groupId)
249 OIC_LOG_V(INFO, TAG, "Received gid = %s", (char *)groupId);
250 handleCB(ctx, result, groupId);
255 * This function prints group policy and calls default callback function handleCB()
257 * @param[in] ctx context
258 * @param[in] result result
259 * @param[in] gp group policy
261 static void handleAclPolicyCheckCB(void* ctx, OCStackResult result, void* gp)
263 OIC_LOG_V(INFO, TAG, "Received gp = %s", (char *)gp);
264 handleCB(ctx, result, gp);
269 * This function prints received acl and calls default callback function handleCB()
271 * @param[in] ctx context
272 * @param[in] result result
275 static void handleAclIndividualGetInfoCB(void* ctx, OCStackResult result, void* acl)
277 printACL((OicSecAcl_t* )acl);
278 handleCB(ctx, result, acl);
279 //can't delete acl here because its ACE's were added to gAcl
280 //TODO: changes in aclresources.c required to fix that
284 * This function prints received group id list and calls default callback function handleCB()
286 * @param[in] ctx context
287 * @param[in] result result
288 * @param[in] gidList group id list
290 static void handleAclFindMyGroupCB(void* ctx, OCStackResult result, void* gidList)
292 printStringArray((stringArray_t *)gidList);
293 handleCB(ctx, result, gidList);
294 clearStringArray((stringArray_t *)gidList);
298 * This function prints received acl and calls default callback function handleCB()
300 * @param[in] ctx context
301 * @param[in] result result
304 static void handleGetCrlCB(void* ctx, OCStackResult result, void* crl)
306 printCrl((OicSecCrl_t *)crl);
307 handleCB(ctx, result, crl);
308 DeleteCrl((OicSecCrl_t *)crl);
312 * This function prints received invitation response and calls default callback function handleCB()
314 * @param[in] ctx context
315 * @param[in] result result
316 * @param[in] invite invitation response (it has inviteResponse_t* type)
318 static void handleAclGetInvitationCB(void* ctx, OCStackResult result, void* invite)
320 printInviteResponse((inviteResponse_t *)invite);
321 handleCB(ctx, result, invite);
322 clearInviteResponse((inviteResponse_t *)invite);
326 static OCStackResult saveTrustCert(void)
328 OCStackResult res = OC_STACK_ERROR;
329 OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
331 ByteArray_t trustCertChainArray = {0, 0};
332 const char *filename = "rootca.crt";
334 if (!readFile(filename, (OCByteString *)&trustCertChainArray))
336 OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
337 return OC_STACK_ERROR;
339 OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
341 res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
343 if (OC_STACK_OK != res)
345 OIC_LOG(ERROR, TAG, "OCSaveTrustCertChain API error");
349 OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
351 OICFree(trustCertChainArray.data);
356 static void wrongRequest()
358 printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
361 static void userRequests(void *data)
365 OIC_LOG(ERROR, TAG, "Received NULL data");
369 OCMode mode = *(OCMode*)data;
371 memset(&endPoint, 0, sizeof(endPoint));
372 strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
373 endPoint.port = DEFAULT_PORT;
375 mutex = ca_mutex_new();
376 cond = ca_cond_new();
378 while (false == fExit)
380 OCStackResult res = OC_STACK_ERROR;
381 bool sendDataToServer = true;
382 timeout = DEFAULT_RESPONSE_WAIT_TIME;
384 printf("-----------------------------------------------------------\n");
385 printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
386 printf("via auth provider: %s\n", authProvider);
387 printf("srv file: %s\n", fname);
388 printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
389 printf("-----------------------------------------------------------\n");
394 readInteger(&request, "Menu number", "see above");
399 if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
401 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
403 readString(token, sizeof(token), "auth token", "check link above");
404 res = CloudSignUp(&endPoint, authProvider, token);
407 res = CloudSignIn(&endPoint);
410 res = CloudSignOut(&endPoint);
413 readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
414 sendDataToServer = false;
419 snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
421 readInteger(&tmp, "port number", example);
423 sendDataToServer = false;
427 res = OCWrapperGetCRL(&endPoint, handleGetCrlCB);
430 res = OCWrapperPostCRL(&endPoint, handleCB);
432 case ACL_GROUP_CREATE:
433 res = OCWrapperAclCreateGroup(&endPoint, handleAclCreateGroupCB);
436 res = OCWrapperAclFindMyGroup(&endPoint, handleAclFindMyGroupCB);
438 case ACL_GROUP_DELETE:
439 res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
442 res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
444 case ACL_GROUP_OBSERVE:
445 res = OCWrapperAclObserveGroup(&endPoint, handleCB);
447 case ACL_GROUP_SHARE_DEVICE:
448 res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
450 case ACL_GROUP_DELETE_DEVICE:
451 res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
453 case ACL_GROUP_GET_INFO:
454 res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
456 case ACL_GROUP_INVITE_USER:
457 res = OCWrapperAclInviteUser(&endPoint, handleCB);
459 case ACL_GROUP_GET_INVITE:
460 res = OCWrapperAclGetInvitation(&endPoint, handleAclGetInvitationCB);
462 case ACL_GROUP_DELETE_INVITE:
463 res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
465 case ACL_GROUP_CANCEL_INVITE:
466 res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
468 case ACL_POLICY_CHECK_REQUEST:
469 res = OCWrapperAclPolicyCheck(&endPoint, handleAclPolicyCheckCB);
471 case ACL_ID_GET_BY_DEVICE:
472 res = OCWrapperAclIdGetByDevice(&endPoint, handleAclIdCB);
475 res = OCWrapperAclIdCreate(&endPoint, handleAclIdCB);
478 res = OCWrapperAclIdDelete(&endPoint, handleCB);
480 case ACL_INDIVIDUAL_GET_INFO:
481 res = OCWrapperAclIndividualGetInfo(&endPoint, handleAclIndividualGetInfoCB);
483 case ACL_INDIVIDUAL_UPDATE_ACE:
484 res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
486 case ACL_INDIVIDUAL_DELETE:
487 res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
490 res = OCWrapperCertificateIssueRequest(&endPoint, handleCB);
494 res = InitDiscovery();
498 res = InitRequest(OC_REST_GET);
502 res= InitRequest(OC_REST_PUT);
506 res= InitRequest(OC_REST_POST);
509 CASelectCipherSuite(0x35, CA_ADAPTER_TCP);
510 sendDataToServer = false;
512 case SAVE_TRUST_CERT:
514 sendDataToServer = false;
516 case USE_SECURE_CONN:
519 readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
520 setCoapPrefix(0 == tmp ? false : true);
521 sendDataToServer = false;
525 ca_mutex_free(mutex);
528 sendDataToServer = false;
532 sendDataToServer = false;
536 //if requests were sent then wait response
537 if (sendDataToServer)
539 if (OC_STACK_OK == res)
541 ca_mutex_lock(mutex);
542 ca_cond_wait_for(cond, mutex, timeout);
543 ca_mutex_unlock(mutex);
547 OIC_LOG_V(ERROR, TAG, "Request returned an error %d", res);
553 FILE* server_fopen(const char *path, const char *mode)
556 return fopen(fname, mode);
560 * Check file accessibility
562 * @param[in] name file path
563 * @return true if check was successful
565 static bool checkConfig(const char *name)
567 FILE* file = fopen(name, "rb");
577 static void printUsage(char *name)
579 printf("Wrong arguments count!\n");
580 printf("Usage : %s <database_filename>\n", name);
581 printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
584 bool parseCommandLineArguments(int argc, char *argv[])
591 if (!checkConfig(fname))
593 OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
605 OCStackResult initPersistentStorage()
607 //Initialize Persistent Storage for SVR database
608 static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
610 return OCRegisterPersistentStorageHandler(&ps);
613 OCStackResult startRequestsThread(OCMode *mode)
615 CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
616 if (CA_STATUS_OK != res)
618 OIC_LOG(ERROR, TAG, "thread pool initialize error.");
622 res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
623 if (CA_STATUS_OK != res)
625 OIC_LOG(ERROR, TAG, "thread pool add task error.");
626 ca_thread_pool_free(g_threadPoolHandle);
631 OCStackResult initProcess(OCMode mode)
633 return OCInit(NULL, 0, mode);
638 while(false == fExit)
640 if (OCProcess() != OC_STACK_OK)
642 OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
647 if (OCStop() != OC_STACK_OK)
649 OIC_LOG(ERROR, TAG, "OCStop process error\n");
653 void freeThreadResources()
655 if (g_threadPoolHandle)
657 ca_thread_pool_free(g_threadPoolHandle);