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 "ocprovisioningmanager.h"
33 #include "cloudAuth.h"
34 #include "cloudWrapper.h"
36 #include "OCCloudProvisioning.hpp"
39 #include <unistd.h> //for unlink
42 #define TAG "cloudClient"
45 #define DEFAULT_HOST "127.0.0.1"
46 #define DEFAULT_PORT OC_MULTICAST_PORT
47 #define DEFAULT_DEVICEID "6A757374-776F-726B-4465-765575696430"
48 #define DEFAULT_USERID "6A757374-776F-726B-4465-765575696430"
49 #define DEFAULT_AUTH_PROVIDER "github"
50 #define DEFAULT_DB_FILE "./cloud.dat"
51 #define DEFAULT_RESPONSE_WAIT_TIME (10 * 1000000) //10s
53 #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 static bool fExit = false;
57 static OCDevAddr endPoint;
58 static char token[1024];
59 static char authProvider[1024];
60 static const char *fname = DEFAULT_DB_FILE;
61 static uint64_t timeout;
62 static uint16_t g_credId = 0;
66 std::string ip(DEFAULT_HOST);
67 OCCloudProvisioning g_cloudProv(ip, (uint16_t)DEFAULT_PORT);
88 ACL_ID_GET_BY_DEVICE = 31,
91 ACL_INDIVIDUAL_GET_INFO = 40,
92 ACL_INDIVIDUAL_UPDATE_ACE = 41,
93 ACL_INDIVIDUAL_DELETE = 42,
95 ACL_GROUP_CREATE = 50,
98 ACL_GROUP_OBSERVE= 53,
99 ACL_GROUP_DELETE = 54,
101 ACL_GROUP_SHARE_DEVICE = 60,
102 ACL_GROUP_DELETE_DEVICE = 61,
103 ACL_GROUP_GET_INFO = 62,
105 ACL_POLICY_CHECK_REQUEST = 70,
107 ACL_GROUP_INVITE_USER = 80,
108 ACL_GROUP_GET_INVITE = 81,
109 ACL_GROUP_DELETE_INVITE = 82,
110 ACL_GROUP_CANCEL_INVITE = 83,
117 printf("************************************************************\n");
118 printf("****************** Cloud Client Requests *******************\n");
119 printf("************************************************************\n");
120 printf("** AUTHORIZATION\n");
121 printf("** %d - Sign Up request\n", SIGN_UP);
122 printf("** %d - Sign In request\n", SIGN_IN);
123 printf("** %d - Sign Out request\n", SIGN_OUT);
125 printf("** SETTINGS \n");
126 printf("** %d - Change default host\n", HOST);
127 printf("** %d - Change default port\n", PORT);
128 printf("** %d - Change default database filename\n", DB_FILE);
129 printf("** %d - Change default auth provider\n", AUTH_PROVIDER);
130 printf("** %d - Change TLS cipher suite to RSA\n", USE_RSA);
131 printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
132 printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
134 printf("** CERTIFICATE REQUEST\n");
135 printf("** %d - Certificate Request\n", CSR_SIGN);
138 printf("** %d - CRL GET Request\n", CRL_GET);
139 printf("** %d - CRL POST Request\n", CRL_POST);
141 printf("** ACL MANAGER\n");
142 printf("** %d - ACL id create Request\n", ACL_ID_CREATE);
143 printf("** %d - ACL id retrieve by device Request\n", ACL_ID_GET_BY_DEVICE);
144 printf("** %d - ACL id delete Request\n", ACL_ID_DELETE);
146 printf("** ACL INDIVIDUAL\n");
147 printf("** %d - ACL individual get info Request\n", ACL_INDIVIDUAL_GET_INFO);
148 printf("** %d - ACL individual update ACE Request\n", ACL_INDIVIDUAL_UPDATE_ACE);
149 printf("** %d - ACL individual delete Request\n", ACL_INDIVIDUAL_DELETE);
151 printf("** ACL GROUP MANAGER\n");
152 printf("** %d - ACL Create Group Request\n", ACL_GROUP_CREATE);
153 printf("** %d - ACL Find Group Request\n", ACL_GROUP_FIND);
154 printf("** %d - ACL Join to invited Group Request\n", ACL_GROUP_JOIN);
155 printf("** %d - ACL Observe Group Request\n", ACL_GROUP_OBSERVE);
156 printf("** %d - ACL Delete Group Request\n", ACL_GROUP_DELETE);
158 printf("** ACL INDIVIDUAL GROUP\n");
159 printf("** %d - ACL Share device into Group Request\n", ACL_GROUP_SHARE_DEVICE);
160 printf("** %d - ACL Delete device from Group Request\n", ACL_GROUP_DELETE_DEVICE);
161 printf("** %d - ACL Get Group Info Request\n", ACL_GROUP_GET_INFO);
163 printf("** ACL POLICY ENFORCEMENT\n");
164 printf("** %d - ACL Check Permissions Request\n", ACL_POLICY_CHECK_REQUEST);
166 printf("** ACL MEMBER INVITATION\n");
167 printf("** %d - ACL Invite user to group Request\n", ACL_GROUP_INVITE_USER);
168 printf("** %d - ACL Retrieve invitation Request\n", ACL_GROUP_GET_INVITE);
169 printf("** %d - ACL Delete invitation Request\n", ACL_GROUP_DELETE_INVITE);
170 printf("** %d - ACL Cancel invitation Request\n", ACL_GROUP_CANCEL_INVITE);
173 printf("** %d - Exit cloud client\n\n", EXIT);
174 printf("************************************************************\n");
176 printf(">> Enter Menu number:\n");
180 * This is default callback to all requests
181 * Used to sync with main menu
183 * @param[in] ctx context
184 * @param[in] result result
185 * @param[in] data data
187 void handleCB(void* ctx, OCStackResult result, void* data)
192 printf("Cloud request Result is == %d", result);
193 oc_mutex_lock(mutex);
194 oc_cond_signal(cond);
195 oc_mutex_unlock(mutex);
198 void handleCB1(OCStackResult result, void *data)
202 printf("Cloud request Result is == %d", result);
203 oc_mutex_lock(mutex);
204 oc_cond_signal(cond);
205 oc_mutex_unlock(mutex);
208 void handleCB2(OCStackResult result, std::string data)
210 printf("Cloud request Result is == %d", result);
211 printf("ACL ID for the device is == %s", data.c_str());
213 oc_mutex_lock(mutex);
214 oc_cond_signal(cond);
215 oc_mutex_unlock(mutex);
218 static int saveTrustCert(void)
220 OCStackResult res = OC_STACK_ERROR;
221 OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
223 ByteArray trustCertChainArray = {0, 0};
225 FILE *fp = fopen("rootca.crt", "rb+");
230 if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp)) > 0)
232 trustCertChainArray.data = (uint8_t*)OICCalloc(1, fsize);
233 trustCertChainArray.len = fsize;
234 if (NULL == trustCertChainArray.data)
236 OIC_LOG(ERROR,TAG,"Failed to allocate memory");
241 if (fsize != fread(trustCertChainArray.data, 1, fsize, fp))
243 OIC_LOG(ERROR, TAG, "Certiface not read completely");
248 OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
250 res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
252 if(OC_STACK_OK != res)
254 OIC_LOG(ERROR, TAG, "OCSaveTrustCertChainBin API error");
257 OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
262 static void userRequests(void *data)
266 memset(token, 0, sizeof(token));
267 memset(authProvider, 0, sizeof(authProvider));
268 strncpy(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider));
269 memset(&endPoint, 0, sizeof(endPoint));
270 strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
271 endPoint.port = DEFAULT_PORT;
273 mutex = oc_mutex_new();
274 cond = oc_cond_new();
276 while (false == fExit)
278 OCStackResult res = OC_STACK_ERROR;
279 timeout = DEFAULT_RESPONSE_WAIT_TIME;
281 printf("-----------------------------------------------------------\n");
282 printf("Connecting to: %s:%d\n", endPoint.addr, endPoint.port);
283 printf("via auth provider: %s\n", authProvider);
284 printf("srv file: %s\n", fname);
285 printf("CoAP prefix: %s\n", DEFAULT_PREFIX);
286 printf("-----------------------------------------------------------\n");
292 for (int ret = 0; 1 != ret; )
294 ret = scanf("%d", &request);
295 for( ; 0x20 <= getchar(); );
301 if (0 == strncmp(authProvider, DEFAULT_AUTH_PROVIDER, sizeof(authProvider)))
303 printf("Paste to browser %s and get auth code\n", GITHUB_AUTH_LINK);
305 readString(token, sizeof(token), "auth token", "check link above");
306 res = CloudSignUp(&endPoint, authProvider, token, handleCloudSignUpResponse);
309 res = CloudSignIn(&endPoint, handleCloudSignInResponse);
312 res = CloudSignOut(&endPoint, handleCloudSignOutResponse);
316 readString(endPoint.addr, sizeof(endPoint.addr), "host ip address", DEFAULT_HOST);
317 std::string str(endPoint.addr);
318 g_cloudProv.setIpAddr(str);
324 snprintf(example, sizeof(example), "%d", DEFAULT_PORT);
326 readInteger(&tmp, "port number", example);
328 g_cloudProv.setPort((uint16_t)tmp);
332 res = OCWrapperGetCRL( g_cloudProv, handleCB1);
335 res = OCWrapperPostCRL( g_cloudProv, handleCB1);
337 case ACL_GROUP_CREATE:
338 res = OCWrapperAclCreateGroup(&endPoint, handleCB);
341 res = OCWrapperAclFindMyGroup(&endPoint, handleCB);
343 case ACL_GROUP_DELETE:
344 res = OCWrapperAclDeleteGroup(&endPoint, handleCB);
347 res = OCWrapperAclJoinToInvitedGroup(&endPoint, handleCB);
349 case ACL_GROUP_OBSERVE:
350 res = OCWrapperAclObserveGroup(&endPoint, handleCB);
352 case ACL_GROUP_SHARE_DEVICE:
353 res = OCWrapperAclShareDeviceIntoGroup(&endPoint, handleCB);
355 case ACL_GROUP_DELETE_DEVICE:
356 res = OCWrapperAclDeleteDeviceFromGroup(&endPoint, handleCB);
358 case ACL_GROUP_GET_INFO:
359 res = OCWrapperAclGroupGetInfo(&endPoint, handleCB);
361 case ACL_GROUP_INVITE_USER:
362 res = OCWrapperAclInviteUser(&endPoint, handleCB);
364 case ACL_GROUP_GET_INVITE:
365 res = OCWrapperAclGetInvitation(&endPoint, handleCB);
367 case ACL_GROUP_DELETE_INVITE:
368 res = OCWrapperAclDeleteInvitation(&endPoint, handleCB);
370 case ACL_GROUP_CANCEL_INVITE:
371 res = OCWrapperAclCancelInvitation(&endPoint, handleCB);
373 case ACL_POLICY_CHECK_REQUEST:
374 res = OCWrapperAclPolicyCheck(&endPoint, handleCB);
376 case ACL_ID_GET_BY_DEVICE:
377 res = OCWrapperAclIdGetByDevice( g_cloudProv, handleCB2);
380 res = OCWrapperAclIdCreate(&endPoint, handleCB);
383 res = OCWrapperAclIdDelete(&endPoint, handleCB);
385 case ACL_INDIVIDUAL_GET_INFO:
386 res = OCWrapperAclIndividualGetInfo( g_cloudProv, handleCB1);
388 case ACL_INDIVIDUAL_UPDATE_ACE:
389 res = OCWrapperAclIndividualUpdateAce(&endPoint, handleCB);
391 case ACL_INDIVIDUAL_DELETE:
392 res = OCWrapperAclIndividualDelete(&endPoint, handleCB);
395 res = OCWrapperCertificateIssueRequest( g_cloudProv, handleCB1);
398 res = CAManager::setCipherSuite(0x35, OC_ADAPTER_TCP);
400 case SAVE_TRUST_CERT:
403 case USE_SECURE_CONN:
406 readInteger(&tmp, "CoAP protocol type", "0 - non-secure, 1 - secure");
407 setCoapPrefix(0 == tmp ? false : true);
411 oc_mutex_free(mutex);
416 printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
420 //if requests were sent then wait response
421 if (res == OC_STACK_OK)
423 oc_mutex_lock(mutex);
424 oc_cond_wait_for(cond, mutex, timeout);
425 oc_mutex_unlock(mutex);
432 FILE* server_fopen(const char *path, const char *mode)
435 return fopen(fname, mode);
439 * Check file accessibility
441 * @param[in] name file path
442 * @return true if check was successful
444 static bool checkConfig(const char *name)
446 FILE* file = fopen(name, "rb");
456 static void printUsage(char *name)
458 printf("Wrong arguments count!\n");
459 printf("Usage : %s <database_filename>\n", name);
460 printf("Examples : 1) %s 2) %s cloud.dat\n", name, name);
463 //==============================================================
464 int main(int argc, char *argv[])
473 if (!checkConfig(fname))
475 OIC_LOG_V(ERROR, TAG, "Can't open database file %s, exit!", fname);
484 //Initialize Persistent Storage for SVR database
485 OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
487 OCRegisterPersistentStorageHandler(&ps);
489 OCMode stackMode = OC_CLIENT_SERVER;
490 if (OCInit(NULL, 0, stackMode) != OC_STACK_OK)
492 OIC_LOG(ERROR, TAG, "OCStack init error, exit\n");
496 ca_thread_pool_t g_threadPoolHandle = NULL;
497 CAResult_t res = ca_thread_pool_init(1, &g_threadPoolHandle);
498 if (CA_STATUS_OK != res)
500 OIC_LOG(ERROR, TAG, "thread pool initialize error.");
504 res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, NULL, NULL);
505 if (CA_STATUS_OK != res)
507 OIC_LOG(ERROR, TAG, "thread pool add task error.");
511 while(false == fExit)
513 if (OCProcess() != OC_STACK_OK)
515 OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
520 if (OCStop() != OC_STACK_OK)
522 OIC_LOG(ERROR, TAG, "OCStop process error\n");
526 if (g_threadPoolHandle)
528 ca_thread_pool_free(g_threadPoolHandle);