2 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "ACLManager.h"
19 #define MAC_ADDRESS_LEN 17
20 #define PASSKEY_DATAS 11
24 conv::acl_manager::PopupCallback callback;
28 usercallback_info *info = NULL;
30 static char passkey[5];
32 ACLResult conv::acl_manager::PasskeyChecker(char *input_passkey)
34 bool isShowPopup = false;
35 const char *app_id = "org.tizen.d2d-conv-syspopup";
37 int ret = app_manager_is_running(app_id, &isShowPopup);
38 if (ret != APP_MANAGER_ERROR_NONE){
39 _D("app_manager_is_running() is error.");
40 return ACLResult_Error;
43 if(isShowPopup == true) {
44 _D("org.tizen.d2d-conv-syspopup is running.");
46 if (!strcmp(passkey, input_passkey)){
52 return ACLResult_Error;
56 _D("org.tizen.d2d-conv-syspopup is closed.");
57 return ACLResult_Close;
63 char token[PASSKEY_DATAS] = "0123456789";
64 unsigned int time_seed = (unsigned int)time(NULL);
68 for (int index = 0; index < PASSKEY_LEN; index++) {
69 int random_num = rand_r(&time_seed) % (PASSKEY_DATAS - 1);
70 passkey[index] = token[random_num];
73 passkey[PASSKEY_LEN] = '\0';
76 static void LaunchPasskeyInputPopupCallback(app_control_h request, app_control_h reply, app_control_result_e result_e, void *user_data)
78 usercallback_info *info = (usercallback_info *)user_data;
84 app_control_get_extra_data(reply, "REPLY_MESSAGE", &reply_message);
86 if (!strcmp(reply_message, "CONNECT")) {
87 result = ACLResult_Connect;
88 app_control_get_extra_data(reply, "PASSKEY", &passkey);
89 } else if (!strcmp(reply_message, "CANCEL")) {
90 result = ACLResult_Cancel;
91 } else if (!strcmp(reply_message, "CLOSE")) {
92 result = ACLResult_Close;
95 info->callback(info->userdata, result, passkey);
98 void conv::acl_manager::LaunchPasskeyInputPopup(PopupCallback callback, void *userdata)
102 bundle_add(b, "TYPE", "PASSKEY_INPUT_POPUP");
104 int ret = syspopup_launch((char *)"d2d-conv-syspopup", b);
106 _E("syspopup_launch Error (%d).", ret);
111 info = (usercallback_info *)malloc(sizeof(usercallback_info)*1);
112 info->callback = callback;
113 info->userdata = userdata;
115 app_control_h app_control;
116 app_control_create(&app_control);
117 app_control_set_app_id(app_control, "org.tizen.d2d-conv-syspopup");
118 app_control_add_extra_data(app_control, "MESSAGE", "REGIST_CALLBACK");
119 app_control_send_launch_request(app_control, LaunchPasskeyInputPopupCallback, info);
120 app_control_destroy(app_control);
123 void conv::acl_manager::LaunchPasskeyShowPopup(const char *deviceName)
129 bundle_add(b, "TYPE", "PASSKEY_SHOW_POPUP");
130 bundle_add(b, "DATA_PASSKEY", passkey);
131 bundle_add(b, "DATA_DEVICE_NAME", deviceName);
133 int ret = syspopup_launch((char *)"d2d-conv-syspopup", b);
135 _E("syspopup_launch Error (%d).", ret);
141 static void LaunchToast(char *type)
143 app_control_h app_control;
144 app_control_create(&app_control);
145 app_control_set_app_id(app_control, "org.tizen.d2d-conv-syspopup");
146 app_control_add_extra_data(app_control, "MESSAGE", type);
147 app_control_send_launch_request(app_control, LaunchPasskeyInputPopupCallback, info);
148 app_control_destroy(app_control);
151 void conv::acl_manager::LaunchPopupCancelToast()
153 LaunchToast((char*)"CANCEL");
156 void conv::acl_manager::LaunchPasskeyWrongToast()
158 LaunchToast((char*)"WRONG_PASSKEY");
161 void conv::acl_manager::LaunchAccessAllowedToast()
163 LaunchToast((char*)"ACCESS_ALLOWED");
166 void conv::acl_manager::LaunchAccessRejectedToast()
168 LaunchToast((char*)"REJECTED");
171 static char convert_mac(char c)
174 if ((convertC >= 'A') && (convertC <= 'F')) {
175 convertC = ((((convertC - 'A') + 10) | 0x02) - 10) + 'A';
176 } else if ((convertC >= '0') && (convertC <= '9')) {
177 convertC = ((convertC - '0') | 0x02);
179 convertC = convertC + '0';
181 convertC = 'A' + (convertC - 10);
183 _E("wrong byte for mac!");
188 static int database_initialize(sqlite3 **database, sqlite3_stmt **stmt, const char *query)
190 int ret = sqlite3_open(DB_FILE_NAME, &(*database));
191 if (ret != SQLITE_OK) {
192 _E("Open the database is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
197 const char *create_table_query = "create table if not exists DEVICES_INFO(MAC_ADDRESS text(100) NOT NULL PRIMARY KEY, DEVICE_TYPE text(20) NOT NULL, DEVICE_NAME text(50) NOT NULL, ACL_STATE int NOT NULL);";
198 ret = sqlite3_exec(*database, create_table_query, NULL, NULL, NULL);
199 if (ret != SQLITE_OK) {
200 _E("Create the database table is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
201 sqlite3_close(*database);
207 ret = sqlite3_exec(*database, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL);
208 if (ret != SQLITE_BUSY) {
209 if (ret == SQLITE_ERROR) {
210 _E("Transaction begin is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
211 sqlite3_close(*database);
218 ret = sqlite3_prepare(*database, query, -1, &(*stmt), NULL);
219 if (ret != SQLITE_OK) {
220 _E("Statement prepare is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
224 ret = sqlite3_reset(*stmt);
225 if (ret != SQLITE_OK) {
226 _E("Statement reset is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
230 ret = sqlite3_clear_bindings(*stmt);
231 if (ret != SQLITE_OK) {
232 _E("Statement binding clear is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
239 static int database_finalize(sqlite3 *database, sqlite3_stmt *stmt)
241 int ret = sqlite3_finalize(stmt);
242 if (ret != SQLITE_OK) {
243 _E("Statement free is fail. (%d: %s)", ret, sqlite3_errmsg(database));
244 sqlite3_close(database);
249 ret = sqlite3_exec(database, "COMMIT TRANSACTION", NULL, NULL, NULL);
250 if (ret != SQLITE_BUSY) {
251 if (ret == SQLITE_ERROR) {
252 _E("Transaction commit is fail. (%d: %s)", ret, sqlite3_errmsg(database));
253 sqlite3_close(database);
260 ret = sqlite3_close(database);
261 if (ret != SQLITE_OK) {
262 _E("Close the database is fail. (%d: %s)", ret, sqlite3_errmsg(database));
269 ACLResult conv::acl_manager::SetDeviceInfoAndACL(const char *macAddress, const char *deviceType, const char *deviceName, const char *deviceIP, ACManagerPolicy aclState)
271 sqlite3 *database = NULL;
272 sqlite3_stmt *stmt = NULL;
273 const char *insert_device_info_query = "insert into DEVICES_INFO (MAC_ADDRESS, DEVICE_TYPE, DEVICE_NAME, ACL_STATE) values (?, ?, ?, ?);";
275 int ret = database_initialize(&database, &stmt, insert_device_info_query);
276 if (ret != SQLITE_OK) {
277 return ACLResult_Error;
280 char _mac[MAC_ADDRESS_LEN + 1];
281 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
282 _mac[1] = convert_mac(_mac[1]);
283 _mac[MAC_ADDRESS_LEN] = '\0';
285 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
286 if (ret != SQLITE_OK) {
287 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
290 ret = sqlite3_bind_text(stmt, 2, deviceType, strlen(deviceType), SQLITE_TRANSIENT);
291 if (ret != SQLITE_OK) {
292 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
295 ret = sqlite3_bind_text(stmt, 3, deviceName, strlen(deviceName), SQLITE_TRANSIENT);
296 if (ret != SQLITE_OK) {
297 _E("Statement binding the deviceName text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
300 ret = sqlite3_bind_int(stmt, 4, aclState);
301 if (ret != SQLITE_OK) {
302 _E("Statement binding the aclState integer is fail. (%d: %s)", ret, sqlite3_errmsg(database));
305 ret = sqlite3_step(stmt);
306 if (ret != SQLITE_DONE) {
307 _E("Statement step is fail. (%d: %s)", ret, sqlite3_errmsg(database));
310 ret = database_finalize(database, stmt);
311 if (ret != SQLITE_OK) {
312 return ACLResult_Error;
318 ACLResult conv::acl_manager::GetACLState(const char *macAddress, ACManagerPolicy *aclState)
320 sqlite3 *database = NULL;
321 sqlite3_stmt *stmt = NULL;
322 const char *get_acl_state_query = "select ACL_STATE from DEVICES_INFO where MAC_ADDRESS=?;";
324 int ret = database_initialize(&database, &stmt, get_acl_state_query);
325 if (ret != SQLITE_OK) {
326 return ACLResult_Error;
329 char _mac[MAC_ADDRESS_LEN + 1];
330 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
331 _mac[1] = convert_mac(_mac[1]);
332 _mac[MAC_ADDRESS_LEN] = '\0';
334 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
335 if (ret != SQLITE_OK) {
336 _E("MacAddress Bind fail. (%d: %s)", ret, sqlite3_errmsg(database));
339 while (sqlite3_step(stmt) == SQLITE_ROW) {
340 *aclState = static_cast<ACManagerPolicy> (sqlite3_column_int(stmt, 0));
343 ret = database_finalize(database, stmt);
344 if (ret != SQLITE_OK) {
345 return ACLResult_Error;
351 ACLResult conv::acl_manager::AddACLDevice(const char *macAddress, const char *deviceName, const char *deviceIP, ACManagerPolicy *aclState)
353 if (aclState == NULL || macAddress == NULL || deviceName == NULL || deviceIP == NULL) {
354 return ACLResult_Error;
357 *aclState = ACMANAGER_POLICY_U2;
359 int ret = conv::acl_manager::GetACLState(macAddress, aclState);
360 if (ret != ACLResult_OK) {
361 return ACLResult_Error;
367 static void RegistACLDevice(conv::Request *requestObj, const char *macAddress, const char *deviceType, const char *deviceName, ACManagerPolicy aclState)
369 int ret = conv::acl_manager::SetDeviceInfoAndACL(macAddress, deviceType, deviceName, NULL, aclState);
370 if (ret != ACLResult_OK) {
371 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
376 requestObj->reply(CONV_ERROR_NONE);
380 static void ChangeACLState(conv::Request *requestObj, const char *macAddress, const char *deviceName, ACManagerPolicy aclState)
382 sqlite3 *database = NULL;
383 sqlite3_stmt *stmt = NULL;
384 const char *set_acl_state_query = "update DEVICES_INFO SET DEVICE_NAME=?, ACL_STATE=? where MAC_ADDRESS=?;";
386 int ret = database_initialize(&database, &stmt, set_acl_state_query);
387 if (ret != SQLITE_OK) {
388 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
393 ret = sqlite3_bind_text(stmt, 1, deviceName, strlen(deviceName), SQLITE_TRANSIENT);
394 if (ret != SQLITE_OK) {
395 _E("Statement binding the deviceName text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
398 ret = sqlite3_bind_int(stmt, 2, aclState);
399 if (ret != SQLITE_OK) {
400 _E("Statement binding the aclState integer is fail. (%d: %s)", ret, sqlite3_errmsg(database));
403 char _mac[MAC_ADDRESS_LEN + 1];
404 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
405 _mac[1] = convert_mac(_mac[1]);
406 _mac[MAC_ADDRESS_LEN] = '\0';
408 ret = sqlite3_bind_text(stmt, 3, _mac, strlen(_mac), SQLITE_TRANSIENT);
409 if (ret != SQLITE_OK) {
410 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
413 ret = sqlite3_step(stmt);
414 if (ret != SQLITE_DONE) {
415 _E("Statement step is fail. (%d: %s)", ret, sqlite3_errmsg(database));
418 ret = database_finalize(database, stmt);
419 if (ret != SQLITE_OK) {
420 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
425 requestObj->reply(CONV_ERROR_NONE);
429 static void SetACLState(conv::Request *requestObj, const char *macAddress, const char *deviceType, const char *deviceName, ACManagerPolicy aclState)
431 sqlite3 *database = NULL;
432 sqlite3_stmt *stmt = NULL;
434 const char *is_exist_query = "select count(*) from DEVICES_INFO where MAC_ADDRESS=?;";
436 int ret = database_initialize(&database, &stmt, is_exist_query);
437 if (ret != SQLITE_OK) {
438 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
443 char _mac[MAC_ADDRESS_LEN + 1];
444 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
445 _mac[1] = convert_mac(_mac[1]);
446 _mac[MAC_ADDRESS_LEN] = '\0';
448 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
449 if (ret != SQLITE_OK) {
450 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
455 while (sqlite3_step(stmt) == SQLITE_ROW) {
456 count = sqlite3_column_int(stmt, 0);
459 ret = database_finalize(database, stmt);
460 if (ret != SQLITE_OK){
461 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
468 case 0 : RegistACLDevice(requestObj, macAddress, deviceType, deviceName, aclState); break;
469 case 1 : ChangeACLState(requestObj, macAddress, deviceName, aclState); break;
473 static void RemoveACLDevice(conv::Request *requestObj, const char *macAddress)
475 sqlite3 *database = NULL;
476 sqlite3_stmt *stmt = NULL;
477 const char *remove_acl_device_query = "delete from DEVICES_INFO WHERE MAC_ADDRESS=?;";
479 int ret = database_initialize(&database, &stmt, remove_acl_device_query);
480 if (ret != SQLITE_OK) {
481 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
486 char _mac[MAC_ADDRESS_LEN + 1];
487 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
488 _mac[1] = convert_mac(_mac[1]);
489 _mac[MAC_ADDRESS_LEN] = '\0';
491 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
492 if (ret != SQLITE_OK) {
493 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
496 ret = sqlite3_step(stmt);
497 if (ret != SQLITE_DONE) {
498 _E("Statement step is fail. (%d: %s)", ret, sqlite3_errmsg(database));
501 ret = database_finalize(database, stmt);
502 if (ret != SQLITE_OK) {
503 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
508 requestObj->reply(CONV_ERROR_NONE);
512 static void GetACLDeviceList(conv::Request *requestObj)
514 sqlite3 *database = NULL;
515 sqlite3_stmt *stmt = NULL;
516 const char *get_acl_device_list_query = "select MAC_ADDRESS, DEVICE_TYPE, DEVICE_NAME, ACL_STATE from DEVICES_INFO;";
518 int ret = database_initialize(&database, &stmt, get_acl_device_list_query);
519 if (ret != SQLITE_OK) {
520 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
525 while (sqlite3_step(stmt) == SQLITE_ROW) {
526 char *macAddress = (char *)sqlite3_column_text(stmt, 0);
527 char *deviceType = (char *)sqlite3_column_text(stmt, 1);
528 char *deviceName = (char *)sqlite3_column_text(stmt, 2);
529 ACManagerPolicy aclState = static_cast<ACManagerPolicy> (sqlite3_column_int(stmt, 3));
531 _I("[ACL] MacAddress:%s, DeviceType:%s, DeviceName:%s, State:%d", macAddress, deviceType, deviceName, aclState);
533 conv::Json result_data;
534 result_data.set(NULL, CONV_JSON_DEVICE_ID, macAddress);
535 result_data.set(NULL, CONV_JSON_DEVICE_TYPE, deviceType);
536 result_data.set(NULL, CONV_JSON_DEVICE_NAME, deviceName);
537 result_data.set(NULL, CONV_JSON_ACCESS_CONTROL_STATE, aclState);
538 requestObj->publish(CONV_ERROR_NONE, result_data);
541 ret = database_finalize(database, stmt);
542 if (ret != SQLITE_OK) {
543 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
548 requestObj->reply(CONV_ERROR_NONE);
552 int conv::acl_manager::handleRequest(conv::Request *requestObj) {
553 if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_REGIST)) {
554 std::string mac_address;
555 std::string device_type;
556 std::string device_name;
559 conv::Json output_data = requestObj->getDescription();
560 output_data.get(NULL, CONV_JSON_DEVICE_ID, &mac_address);
561 output_data.get(NULL, CONV_JSON_DEVICE_TYPE, &device_type);
562 output_data.get(NULL, CONV_JSON_DEVICE_NAME, &device_name);
563 output_data.get(NULL, CONV_JSON_ACCESS_CONTROL_STATE, &state);
565 ACManagerPolicy aclState = ACMANAGER_POLICY_U2;
568 case 0 : aclState = ACMANAGER_POLICY_P; break;
569 case 1 : aclState = ACMANAGER_POLICY_D; break;
572 RegistACLDevice(requestObj, (const char*)mac_address.c_str(), (const char*)device_type.c_str(), (const char*)device_name.c_str(), aclState);
574 } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_SET)) {
575 std::string mac_address;
576 std::string device_type;
577 std::string device_name;
580 conv::Json output_data = requestObj->getDescription();
581 output_data.get(NULL, CONV_JSON_DEVICE_ID, &mac_address);
582 output_data.get(NULL, CONV_JSON_DEVICE_TYPE, &device_type);
583 output_data.get(NULL, CONV_JSON_DEVICE_NAME, &device_name);
584 output_data.get(NULL, CONV_JSON_ACCESS_CONTROL_STATE, &state);
586 ACManagerPolicy aclState = static_cast<ACManagerPolicy> (state);
587 SetACLState(requestObj, (const char*)mac_address.c_str(), (const char*)device_type.c_str(), (const char*)device_name.c_str(), aclState);
589 } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_REMOVE)) {
590 std::string mac_address;
591 conv::Json output_data = requestObj->getDescription();
592 output_data.get(NULL, CONV_JSON_DEVICE_ID, &mac_address);
593 RemoveACLDevice(requestObj, (const char*)mac_address.c_str());
595 } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_GET)) {
596 GetACLDeviceList(requestObj);
599 return CONV_ERROR_NONE;