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
22 conv::acl_manager::PopupCallback callback;
26 usercallback_info *info = NULL;
28 static char passkey[5];
30 ACLResult conv::acl_manager::PasskeyChecker(char *input_passkey)
32 bool isShowPopup = false;
33 const char *app_id = "org.tizen.d2d-conv-syspopup";
35 int ret = app_manager_is_running(app_id, &isShowPopup);
36 if (ret != APP_MANAGER_ERROR_NONE){
37 _D("app_manager_is_running() is error.");
38 return ACLResult_Error;
41 if(isShowPopup == true) {
42 _D("org.tizen.d2d-conv-syspopup is running.");
44 if (!strcmp(passkey, input_passkey)){
50 return ACLResult_Error;
54 _D("org.tizen.d2d-conv-syspopup is closed.");
55 return ACLResult_Close;
61 char token[64] = "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
62 unsigned int time_seed = (unsigned int)time(NULL);
66 for (int i = 0; i < 4; i++) {
67 int random_num = rand_r(&time_seed) % 63;
68 passkey[i] = token[random_num];
74 static void LaunchPasskeyInputPopupCallback(app_control_h request, app_control_h reply, app_control_result_e result_e, void *user_data)
76 usercallback_info *info = (usercallback_info *)user_data;
82 app_control_get_extra_data(reply, "REPLY_MESSAGE", &reply_message);
84 if (!strcmp(reply_message, "CONNECT")) {
85 result = ACLResult_Connect;
86 app_control_get_extra_data(reply, "PASSKEY", &passkey);
87 } else if (!strcmp(reply_message, "CANCEL")) {
88 result = ACLResult_Cancel;
89 } else if (!strcmp(reply_message, "CLOSE")) {
90 result = ACLResult_Close;
93 info->callback(info->userdata, result, passkey);
96 void conv::acl_manager::LaunchPasskeyInputPopup(PopupCallback callback, void *userdata)
100 bundle_add(b, "TYPE", "PASSKEY_INPUT_POPUP");
102 int ret = syspopup_launch((char *)"d2d-conv-syspopup", b);
104 _E("syspopup_launch Error (%d).", ret);
109 info = (usercallback_info *)malloc(sizeof(usercallback_info)*1);
110 info->callback = callback;
111 info->userdata = userdata;
113 app_control_h app_control;
114 app_control_create(&app_control);
115 app_control_set_app_id(app_control, "org.tizen.d2d-conv-syspopup");
116 app_control_add_extra_data(app_control, "MESSAGE", "REGIST_CALLBACK");
117 app_control_send_launch_request(app_control, LaunchPasskeyInputPopupCallback, info);
118 app_control_destroy(app_control);
121 void conv::acl_manager::LaunchPasskeyShowPopup(const char *deviceName)
127 bundle_add(b, "TYPE", "PASSKEY_SHOW_POPUP");
128 bundle_add(b, "DATA_PASSKEY", passkey);
129 bundle_add(b, "DATA_DEVICE_NAME", deviceName);
131 int ret = syspopup_launch((char *)"d2d-conv-syspopup", b);
133 _E("syspopup_launch Error (%d).", ret);
139 static void LaunchToast(char *type)
141 app_control_h app_control;
142 app_control_create(&app_control);
143 app_control_set_app_id(app_control, "org.tizen.d2d-conv-syspopup");
144 app_control_add_extra_data(app_control, "MESSAGE", type);
145 app_control_send_launch_request(app_control, LaunchPasskeyInputPopupCallback, info);
146 app_control_destroy(app_control);
149 void conv::acl_manager::LaunchPopupCancelToast()
151 LaunchToast((char*)"CANCEL");
154 void conv::acl_manager::LaunchPasskeyWrongToast()
156 LaunchToast((char*)"WRONG_PASSKEY");
159 void conv::acl_manager::LaunchAccessAllowedToast()
161 LaunchToast((char*)"ACCESS_ALLOWED");
164 void conv::acl_manager::LaunchAccessRejectedToast()
166 LaunchToast((char*)"REJECTED");
169 static char convert_mac(char c)
172 if ((convertC >= 'A') && (convertC <= 'F')) {
173 convertC = ((((convertC - 'A') + 10) | 0x02) - 10) + 'A';
174 } else if ((convertC >= '0') && (convertC <= '9')) {
175 convertC = ((convertC - '0') | 0x02);
177 convertC = convertC + '0';
179 convertC = 'A' + (convertC - 10);
181 _E("wrong byte for mac!");
186 static int database_initialize(sqlite3 **database, sqlite3_stmt **stmt, const char *query)
188 int ret = sqlite3_open(DB_FILE_NAME, &(*database));
189 if (ret != SQLITE_OK) {
190 _E("Open the database is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
195 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);";
196 ret = sqlite3_exec(*database, create_table_query, NULL, NULL, NULL);
197 if (ret != SQLITE_OK) {
198 _E("Create the database table is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
199 sqlite3_close(*database);
205 ret = sqlite3_exec(*database, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL);
206 if (ret != SQLITE_BUSY) {
207 if (ret == SQLITE_ERROR) {
208 _E("Transaction begin is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
209 sqlite3_close(*database);
216 ret = sqlite3_prepare(*database, query, -1, &(*stmt), NULL);
217 if (ret != SQLITE_OK) {
218 _E("Statement prepare is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
222 ret = sqlite3_reset(*stmt);
223 if (ret != SQLITE_OK) {
224 _E("Statement reset is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
228 ret = sqlite3_clear_bindings(*stmt);
229 if (ret != SQLITE_OK) {
230 _E("Statement binding clear is fail. (%d: %s)", ret, sqlite3_errmsg(*database));
237 static int database_finalize(sqlite3 *database, sqlite3_stmt *stmt)
239 int ret = sqlite3_finalize(stmt);
240 if (ret != SQLITE_OK) {
241 _E("Statement free is fail. (%d: %s)", ret, sqlite3_errmsg(database));
242 sqlite3_close(database);
247 ret = sqlite3_exec(database, "COMMIT TRANSACTION", NULL, NULL, NULL);
248 if (ret != SQLITE_BUSY) {
249 if (ret == SQLITE_ERROR) {
250 _E("Transaction commit is fail. (%d: %s)", ret, sqlite3_errmsg(database));
251 sqlite3_close(database);
258 ret = sqlite3_close(database);
259 if (ret != SQLITE_OK) {
260 _E("Close the database is fail. (%d: %s)", ret, sqlite3_errmsg(database));
267 ACLResult conv::acl_manager::SetDeviceInfoAndACL(const char *macAddress, const char *deviceType, const char *deviceName, const char *deviceIP, ACManagerPolicy aclState)
269 sqlite3 *database = NULL;
270 sqlite3_stmt *stmt = NULL;
271 const char *insert_device_info_query = "insert into DEVICES_INFO (MAC_ADDRESS, DEVICE_TYPE, DEVICE_NAME, ACL_STATE) values (?, ?, ?, ?);";
273 int ret = database_initialize(&database, &stmt, insert_device_info_query);
274 if (ret != SQLITE_OK) {
275 return ACLResult_Error;
278 char _mac[MAC_ADDRESS_LEN + 1];
279 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
280 _mac[1] = convert_mac(_mac[1]);
281 _mac[MAC_ADDRESS_LEN] = '\0';
283 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
284 if (ret != SQLITE_OK) {
285 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
288 ret = sqlite3_bind_text(stmt, 2, deviceType, strlen(deviceType), SQLITE_TRANSIENT);
289 if (ret != SQLITE_OK) {
290 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
293 ret = sqlite3_bind_text(stmt, 3, deviceName, strlen(deviceName), SQLITE_TRANSIENT);
294 if (ret != SQLITE_OK) {
295 _E("Statement binding the deviceName text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
298 ret = sqlite3_bind_int(stmt, 4, aclState);
299 if (ret != SQLITE_OK) {
300 _E("Statement binding the aclState integer is fail. (%d: %s)", ret, sqlite3_errmsg(database));
303 ret = sqlite3_step(stmt);
304 if (ret != SQLITE_DONE) {
305 _E("Statement step is fail. (%d: %s)", ret, sqlite3_errmsg(database));
308 ret = database_finalize(database, stmt);
309 if (ret != SQLITE_OK) {
310 return ACLResult_Error;
316 ACLResult conv::acl_manager::GetACLState(const char *macAddress, ACManagerPolicy *aclState)
318 sqlite3 *database = NULL;
319 sqlite3_stmt *stmt = NULL;
320 const char *get_acl_state_query = "select ACL_STATE from DEVICES_INFO where MAC_ADDRESS=?;";
322 int ret = database_initialize(&database, &stmt, get_acl_state_query);
323 if (ret != SQLITE_OK) {
324 return ACLResult_Error;
327 char _mac[MAC_ADDRESS_LEN + 1];
328 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
329 _mac[1] = convert_mac(_mac[1]);
330 _mac[MAC_ADDRESS_LEN] = '\0';
332 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
333 if (ret != SQLITE_OK) {
334 _E("MacAddress Bind fail. (%d: %s)", ret, sqlite3_errmsg(database));
337 while (sqlite3_step(stmt) == SQLITE_ROW) {
338 *aclState = static_cast<ACManagerPolicy> (sqlite3_column_int(stmt, 0));
341 ret = database_finalize(database, stmt);
342 if (ret != SQLITE_OK) {
343 return ACLResult_Error;
349 ACLResult conv::acl_manager::AddACLDevice(const char *macAddress, const char *deviceName, const char *deviceIP, ACManagerPolicy *aclState)
351 if (aclState == NULL || macAddress == NULL || deviceName == NULL || deviceIP == NULL) {
352 return ACLResult_Error;
355 *aclState = ACMANAGER_POLICY_U2;
357 int ret = conv::acl_manager::GetACLState(macAddress, aclState);
358 if (ret != ACLResult_OK) {
359 return ACLResult_Error;
365 static void RegistACLDevice(conv::Request *requestObj, const char *macAddress, const char *deviceType, const char *deviceName, ACManagerPolicy aclState)
367 int ret = conv::acl_manager::SetDeviceInfoAndACL(macAddress, deviceType, deviceName, NULL, aclState);
368 if (ret != ACLResult_OK) {
369 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
374 requestObj->reply(CONV_ERROR_NONE);
378 static void ChangeACLState(conv::Request *requestObj, const char *macAddress, const char *deviceName, ACManagerPolicy aclState)
380 sqlite3 *database = NULL;
381 sqlite3_stmt *stmt = NULL;
382 const char *set_acl_state_query = "update DEVICES_INFO SET DEVICE_NAME=?, ACL_STATE=? where MAC_ADDRESS=?;";
384 int ret = database_initialize(&database, &stmt, set_acl_state_query);
385 if (ret != SQLITE_OK) {
386 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
391 ret = sqlite3_bind_text(stmt, 1, deviceName, strlen(deviceName), SQLITE_TRANSIENT);
392 if (ret != SQLITE_OK) {
393 _E("Statement binding the deviceName text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
396 ret = sqlite3_bind_int(stmt, 2, aclState);
397 if (ret != SQLITE_OK) {
398 _E("Statement binding the aclState integer is fail. (%d: %s)", ret, sqlite3_errmsg(database));
401 char _mac[MAC_ADDRESS_LEN + 1];
402 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
403 _mac[1] = convert_mac(_mac[1]);
404 _mac[MAC_ADDRESS_LEN] = '\0';
406 ret = sqlite3_bind_text(stmt, 3, _mac, strlen(_mac), SQLITE_TRANSIENT);
407 if (ret != SQLITE_OK) {
408 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
411 ret = sqlite3_step(stmt);
412 if (ret != SQLITE_DONE) {
413 _E("Statement step is fail. (%d: %s)", ret, sqlite3_errmsg(database));
416 ret = database_finalize(database, stmt);
417 if (ret != SQLITE_OK) {
418 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
423 requestObj->reply(CONV_ERROR_NONE);
427 static void SetACLState(conv::Request *requestObj, const char *macAddress, const char *deviceType, const char *deviceName, ACManagerPolicy aclState)
429 sqlite3 *database = NULL;
430 sqlite3_stmt *stmt = NULL;
432 const char *is_exist_query = "select count(*) from DEVICES_INFO where MAC_ADDRESS=?;";
434 int ret = database_initialize(&database, &stmt, is_exist_query);
435 if (ret != SQLITE_OK) {
436 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
441 char _mac[MAC_ADDRESS_LEN + 1];
442 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
443 _mac[1] = convert_mac(_mac[1]);
444 _mac[MAC_ADDRESS_LEN] = '\0';
446 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
447 if (ret != SQLITE_OK) {
448 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
453 while (sqlite3_step(stmt) == SQLITE_ROW) {
454 count = sqlite3_column_int(stmt, 0);
457 ret = database_finalize(database, stmt);
458 if (ret != SQLITE_OK){
459 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
466 case 0 : RegistACLDevice(requestObj, macAddress, deviceType, deviceName, aclState); break;
467 case 1 : ChangeACLState(requestObj, macAddress, deviceName, aclState); break;
471 static void RemoveACLDevice(conv::Request *requestObj, const char *macAddress)
473 sqlite3 *database = NULL;
474 sqlite3_stmt *stmt = NULL;
475 const char *remove_acl_device_query = "delete from DEVICES_INFO WHERE MAC_ADDRESS=?;";
477 int ret = database_initialize(&database, &stmt, remove_acl_device_query);
478 if (ret != SQLITE_OK) {
479 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
484 char _mac[MAC_ADDRESS_LEN + 1];
485 strncpy(_mac, macAddress, MAC_ADDRESS_LEN);
486 _mac[1] = convert_mac(_mac[1]);
487 _mac[MAC_ADDRESS_LEN] = '\0';
489 ret = sqlite3_bind_text(stmt, 1, _mac, strlen(_mac), SQLITE_TRANSIENT);
490 if (ret != SQLITE_OK) {
491 _E("Statement binding the macAddress text is fail. (%d: %s)", ret, sqlite3_errmsg(database));
494 ret = sqlite3_step(stmt);
495 if (ret != SQLITE_DONE) {
496 _E("Statement step is fail. (%d: %s)", ret, sqlite3_errmsg(database));
499 ret = database_finalize(database, stmt);
500 if (ret != SQLITE_OK) {
501 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
506 requestObj->reply(CONV_ERROR_NONE);
510 static void GetACLDeviceList(conv::Request *requestObj)
512 sqlite3 *database = NULL;
513 sqlite3_stmt *stmt = NULL;
514 const char *get_acl_device_list_query = "select MAC_ADDRESS, DEVICE_TYPE, DEVICE_NAME, ACL_STATE from DEVICES_INFO;";
516 int ret = database_initialize(&database, &stmt, get_acl_device_list_query);
517 if (ret != SQLITE_OK) {
518 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
523 while (sqlite3_step(stmt) == SQLITE_ROW) {
524 char *macAddress = (char *)sqlite3_column_text(stmt, 0);
525 char *deviceType = (char *)sqlite3_column_text(stmt, 1);
526 char *deviceName = (char *)sqlite3_column_text(stmt, 2);
527 ACManagerPolicy aclState = static_cast<ACManagerPolicy> (sqlite3_column_int(stmt, 3));
529 _I("[ACL] MacAddress:%s, DeviceType:%s, DeviceName:%s, State:%d", macAddress, deviceType, deviceName, aclState);
531 conv::Json result_data;
532 result_data.set(NULL, CONV_JSON_DEVICE_ID, macAddress);
533 result_data.set(NULL, CONV_JSON_DEVICE_TYPE, deviceType);
534 result_data.set(NULL, CONV_JSON_DEVICE_NAME, deviceName);
535 result_data.set(NULL, CONV_JSON_ACCESS_CONTROL_STATE, aclState);
536 requestObj->publish(CONV_ERROR_NONE, result_data);
539 ret = database_finalize(database, stmt);
540 if (ret != SQLITE_OK) {
541 requestObj->reply(CONV_ERROR_INVALID_OPERATION);
546 requestObj->reply(CONV_ERROR_NONE);
550 int conv::acl_manager::handleRequest(conv::Request *requestObj) {
551 if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_REGIST)) {
552 std::string mac_address;
553 std::string device_type;
554 std::string device_name;
557 conv::Json output_data = requestObj->getDescription();
558 output_data.get(NULL, CONV_JSON_DEVICE_ID, &mac_address);
559 output_data.get(NULL, CONV_JSON_DEVICE_TYPE, &device_type);
560 output_data.get(NULL, CONV_JSON_DEVICE_NAME, &device_name);
561 output_data.get(NULL, CONV_JSON_ACCESS_CONTROL_STATE, &state);
563 ACManagerPolicy aclState = ACMANAGER_POLICY_U2;
566 case 0 : aclState = ACMANAGER_POLICY_P; break;
567 case 1 : aclState = ACMANAGER_POLICY_D; break;
570 RegistACLDevice(requestObj, (const char*)mac_address.c_str(), (const char*)device_type.c_str(), (const char*)device_name.c_str(), aclState);
572 } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_SET)) {
573 std::string mac_address;
574 std::string device_type;
575 std::string device_name;
578 conv::Json output_data = requestObj->getDescription();
579 output_data.get(NULL, CONV_JSON_DEVICE_ID, &mac_address);
580 output_data.get(NULL, CONV_JSON_DEVICE_TYPE, &device_type);
581 output_data.get(NULL, CONV_JSON_DEVICE_NAME, &device_name);
582 output_data.get(NULL, CONV_JSON_ACCESS_CONTROL_STATE, &state);
584 ACManagerPolicy aclState = static_cast<ACManagerPolicy> (state);
585 SetACLState(requestObj, (const char*)mac_address.c_str(), (const char*)device_type.c_str(), (const char*)device_name.c_str(), aclState);
587 } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_REMOVE)) {
588 std::string mac_address;
589 conv::Json output_data = requestObj->getDescription();
590 output_data.get(NULL, CONV_JSON_DEVICE_ID, &mac_address);
591 RemoveACLDevice(requestObj, (const char*)mac_address.c_str());
593 } else if (!strcmp(requestObj->getSubject(), CONV_SUBJECT_ACCESS_CONTROL_GET)) {
594 GetACLDeviceList(requestObj);
597 return CONV_ERROR_NONE;