2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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.
28 #include <curl/curl.h>
30 #include <openssl/evp.h>
31 #include <openssl/bio.h>
32 #include <openssl/buffer.h>
36 #include <wav_player.h>
41 #include "net_nfc_typedef.h"
42 #include "net_nfc_typedef_internal.h"
43 #include "net_nfc_debug_internal.h"
44 #include "net_nfc_util_defines.h"
45 #include "net_nfc_util_internal.h"
46 #include "net_nfc_util_ndef_message.h"
47 #include "net_nfc_util_ndef_record.h"
48 #include "net_nfc_server_context.h"
49 #include "net_nfc_server_se.h"
50 #include "net_nfc_server_util.h"
52 #define NET_NFC_MANAGER_SOUND_PATH_TASK_START "/usr/share/nfc-manager-daemon/sounds/Operation_sdk.wav"
53 #define NET_NFC_MANAGER_SOUND_PATH_TASK_END "/usr/share/nfc-manager-daemon/sounds/Operation_sdk.wav"
54 #define NET_NFC_MANAGER_SOUND_PATH_TASK_ERROR "/usr/share/nfc-manager-daemon/sounds/Operation_sdk.wav"
56 #define OSP_K_COND "__OSP_COND_NAME__"
57 #define OSP_K_COND_TYPE "nfc"
58 #define OSP_K_LAUNCH_TYPE "__OSP_LAUNCH_TYPE__"
60 static const char osp_launch_type_condition[] = "condition";
62 static bool _net_nfc_app_util_change_file_owner_permission(FILE *file)
65 size_t buffer_len = 0;
66 struct passwd pwd = { 0, };
67 struct passwd *pw_inhouse = NULL;
68 struct group grp = { 0, };
69 struct group *gr_inhouse = NULL;
74 /* change permission */
75 fchmod(fileno(file), 0777);
79 buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX);
85 _net_nfc_util_alloc_mem(buffer, buffer_len);
89 getpwnam_r("inhouse", &pwd, buffer, buffer_len, &pw_inhouse);
90 _net_nfc_util_free_mem(buffer);
93 buffer_len = sysconf(_SC_GETGR_R_SIZE_MAX);
99 _net_nfc_util_alloc_mem(buffer, buffer_len);
103 getgrnam_r("inhouse", &grp, buffer, buffer_len, &gr_inhouse);
104 _net_nfc_util_free_mem(buffer);
106 if ((pw_inhouse != NULL) && (gr_inhouse != NULL))
108 if (fchown(fileno(file), pw_inhouse->pw_uid, gr_inhouse->gr_gid) < 0)
110 DEBUG_ERR_MSG("failed to change owner");
117 static net_nfc_error_e net_nfc_app_util_store_ndef_message(data_s *data)
119 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
120 char file_name[1024] = { 0, };
126 return NET_NFC_NULL_PARAMETER;
129 /* check and make directory */
130 snprintf(file_name, sizeof(file_name), "%s/%s", NET_NFC_MANAGER_DATA_PATH,
131 NET_NFC_MANAGER_DATA_PATH_MESSAGE);
133 if (stat(file_name, &st) == -1)
138 SECURE_LOGD("path doesn't exist, do mkdir : %s", file_name);
140 snprintf(command, sizeof(command), "mkdir -p -m 755 %s", file_name);
142 ret = system(command);
144 if (stat(file_name, &st) == -1)
146 DEBUG_ERR_MSG("mkdir failed(%d)", ret);
147 return NET_NFC_UNKNOWN_ERROR;
152 snprintf(file_name, sizeof(file_name), "%s/%s/%s", NET_NFC_MANAGER_DATA_PATH,
153 NET_NFC_MANAGER_DATA_PATH_MESSAGE, NET_NFC_MANAGER_NDEF_FILE_NAME);
154 SECURE_LOGD("file path : %s", file_name);
158 if ((fp = fopen(file_name, "w")) != NULL)
162 if ((length = fwrite(data->buffer, 1, data->length, fp)) > 0)
164 DEBUG_SERVER_MSG("[%d] bytes is written", length);
166 _net_nfc_app_util_change_file_owner_permission(fp);
175 DEBUG_ERR_MSG("write is failed = [%d]", data->length);
176 result = NET_NFC_UNKNOWN_ERROR;
185 static bool _net_nfc_app_util_get_operation_from_record(ndef_record_s *record, char *operation, size_t length)
188 char *op_text = NULL;
190 if (record == NULL || operation == NULL || length == 0)
197 case NET_NFC_RECORD_WELL_KNOWN_TYPE :
198 op_text = "http://tizen.org/appcontrol/operation/nfc/wellknown";
201 case NET_NFC_RECORD_MIME_TYPE :
202 op_text = "http://tizen.org/appcontrol/operation/nfc/mime";
205 case NET_NFC_RECORD_URI : /* Absolute URI */
206 op_text = "http://tizen.org/appcontrol/operation/nfc/uri";
209 case NET_NFC_RECORD_EXTERNAL_RTD : /* external type */
210 op_text = "http://tizen.org/appcontrol/operation/nfc/external";
213 case NET_NFC_RECORD_EMPTY : /* empty_tag */
214 op_text = "http://tizen.org/appcontrol/operation/nfc/empty";
217 case NET_NFC_RECORD_UNKNOWN : /* unknown msg. discard it */
218 case NET_NFC_RECORD_UNCHAGNED : /* RFU msg. discard it */
225 snprintf(operation, length, "%s", op_text);
232 static void _to_lower_utf_8(char *str)
236 if (*str >= 'A' && *str <= 'Z')
243 static void _to_lower(int type, char *str)
245 _to_lower_utf_8(str);
248 static bool _net_nfc_app_util_get_mime_from_record(ndef_record_s *record, char *mime, size_t length)
252 if (record == NULL || mime == NULL || length == 0)
259 case NET_NFC_RECORD_WELL_KNOWN_TYPE :
261 if (record->type_s.buffer == NULL || record->type_s.length == 0 ||
262 record->payload_s.buffer == NULL || record->payload_s.length == 0)
264 DEBUG_ERR_MSG("Broken NDEF Message [NET_NFC_RECORD_WELL_KNOWN_TYPE]");
268 if (record->type_s.length == 1 && record->type_s.buffer[0] == 'U')
270 snprintf(mime, length, "U/0x%02x", record->payload_s.buffer[0]);
274 memcpy(mime, record->type_s.buffer, record->type_s.length);
275 mime[record->type_s.length] = '\0';
277 strncat(mime, "/*", 2);
278 mime[record->type_s.length + 2] = '\0';
281 //DEBUG_SERVER_MSG("mime [%s]", mime);
287 case NET_NFC_RECORD_MIME_TYPE :
293 if (record->type_s.buffer == NULL || record->type_s.length == 0)
295 DEBUG_ERR_MSG("Broken NDEF Message [NET_NFC_RECORD_MIME_TYPE]");
300 _net_nfc_util_alloc_mem(buffer, record->type_s.length + 1);
303 DEBUG_ERR_MSG("_net_nfc_manager_util_alloc_mem return NULL");
306 memcpy(buffer, record->type_s.buffer, record->type_s.length);
308 //DEBUG_SERVER_MSG("NET_NFC_RECORD_MIME_TYPE type [%s]", buffer);
310 token = strchr(buffer, ';');
313 //DEBUG_SERVER_MSG("token = strchr(buffer, ';') != NULL, len [%d]", token - buffer);
314 len = MIN(token - buffer, length - 1);
318 len = MIN(strlen(buffer), length - 1);
321 //DEBUG_SERVER_MSG("len [%d]", len);
323 strncpy(mime, buffer, len);
328 //DEBUG_SERVER_MSG("mime [%s]", mime);
330 _net_nfc_util_free_mem(buffer);
336 case NET_NFC_RECORD_URI : /* Absolute URI */
337 case NET_NFC_RECORD_EXTERNAL_RTD : /* external type */
338 case NET_NFC_RECORD_EMPTY : /* empty_tag */
342 case NET_NFC_RECORD_UNKNOWN : /* unknown msg. discard it */
343 case NET_NFC_RECORD_UNCHAGNED : /* RFU msg. discard it */
352 static bool _net_nfc_app_util_get_uri_from_record(ndef_record_s *record, char *data, size_t length)
356 if (record == NULL || data == NULL || length == 0)
363 case NET_NFC_RECORD_WELL_KNOWN_TYPE :
364 case NET_NFC_RECORD_URI : /* Absolute URI */
368 if (net_nfc_util_create_uri_string_from_uri_record(record, &uri) == NET_NFC_OK &&
371 //DEBUG_SERVER_MSG("uri record : %s", uri);
372 snprintf(data, length, "%s", uri);
374 _net_nfc_util_free_mem(uri);
380 case NET_NFC_RECORD_EXTERNAL_RTD : /* external type */
382 data_s *type = &record->type_s;
384 if (type->length > 0)
388 int len = strlen(NET_NFC_UTIL_EXTERNAL_TYPE_SCHEME);
390 _net_nfc_util_alloc_mem(buffer, type->length + len + 1);
393 memcpy(buffer, NET_NFC_UTIL_EXTERNAL_TYPE_SCHEME, len);
394 memcpy(buffer + len, type->buffer, type->length);
396 /* to lower case!! */
399 DEBUG_SERVER_MSG("uri record : %s", buffer);
400 snprintf(data, length, "%s", buffer);
402 _net_nfc_util_free_mem(buffer);
405 int len = MIN(type->length, length - 1);
406 memcpy(data, type->buffer, len);
409 /* to lower case!! */
412 //DEBUG_SERVER_MSG("uri record : %s", data);
419 case NET_NFC_RECORD_MIME_TYPE :
420 case NET_NFC_RECORD_EMPTY : /* empy msg. discard it */
424 case NET_NFC_RECORD_UNKNOWN : /* unknown msg. discard it */
425 case NET_NFC_RECORD_UNCHAGNED : /* RFU msg. discard it */
434 static bool _net_nfc_app_util_get_data_from_record(ndef_record_s *record, char *data, size_t length)
438 if (record == NULL || data == NULL || length == 0)
445 case NET_NFC_RECORD_WELL_KNOWN_TYPE :
447 if (record->type_s.buffer == NULL || record->type_s.length == 0
448 || record->payload_s.buffer == NULL || record->payload_s.length == 0)
450 DEBUG_ERR_MSG("Broken NDEF Message [NET_NFC_RECORD_WELL_KNOWN_TYPE]");
454 if (record->type_s.length == 1 && record->type_s.buffer[0] == 'T')
456 uint8_t *buffer_temp = record->payload_s.buffer;
457 uint32_t buffer_length = record->payload_s.length;
459 int index = (buffer_temp[0] & 0x3F) + 1;
460 int text_length = buffer_length - index;
462 memcpy(data, &(buffer_temp[index]), MIN(text_length, length));
465 //DEBUG_SERVER_MSG("data [%s]", data);
471 case NET_NFC_RECORD_MIME_TYPE :
472 case NET_NFC_RECORD_URI : /* Absolute URI */
473 case NET_NFC_RECORD_EXTERNAL_RTD : /* external type */
474 case NET_NFC_RECORD_EMPTY : /* empy msg. discard it */
478 case NET_NFC_RECORD_UNKNOWN : /* unknown msg. discard it */
479 case NET_NFC_RECORD_UNCHAGNED : /* RFU msg. discard it */
487 net_nfc_error_e net_nfc_app_util_process_ndef(data_s *data)
489 net_nfc_error_e result = NET_NFC_UNKNOWN_ERROR;
490 ndef_message_s *msg = NULL;
491 char operation[2048] = { 0, };
492 char mime[2048] = { 0, };
493 char text[2048] = { 0, };
495 char uri[2048] = { 0, };
499 if (data == NULL || data->buffer == NULL || data->length == 0)
501 DEBUG_ERR_MSG("net_nfc_app_util_process_ndef NET_NFC_NULL_PARAMETER");
502 return NET_NFC_NULL_PARAMETER;
506 if ((result = net_nfc_app_util_store_ndef_message(data)) != NET_NFC_OK)
508 DEBUG_ERR_MSG("net_nfc_app_util_store_ndef_message failed [%d]", result);
512 /* check state of launch popup */
513 if(net_nfc_app_util_check_launch_state() == TRUE)
515 DEBUG_SERVER_MSG("skip launch popup!!!");
520 if (net_nfc_util_create_ndef_message(&msg) != NET_NFC_OK)
522 DEBUG_ERR_MSG("memory alloc fail..");
523 return NET_NFC_ALLOC_FAIL;
526 /* parse ndef message and fill appsvc data */
527 if ((result = net_nfc_util_convert_rawdata_to_ndef_message(data, msg)) != NET_NFC_OK)
529 DEBUG_ERR_MSG("net_nfc_app_util_store_ndef_message failed [%d]", result);
533 if (_net_nfc_app_util_get_operation_from_record(msg->records, operation, sizeof(operation)) == FALSE)
535 DEBUG_ERR_MSG("_net_nfc_app_util_get_operation_from_record failed [%d]", result);
536 result = NET_NFC_UNKNOWN_ERROR;
540 if (_net_nfc_app_util_get_mime_from_record(msg->records, mime, sizeof(mime)) == FALSE)
542 DEBUG_ERR_MSG("_net_nfc_app_util_get_mime_from_record failed [%d]", result);
543 result = NET_NFC_UNKNOWN_ERROR;
547 if (_net_nfc_app_util_get_uri_from_record(msg->records, uri, sizeof(uri)) == FALSE)
549 DEBUG_ERR_MSG("_net_nfc_app_util_get_uri_from_record failed [%d]", result);
550 result = NET_NFC_UNKNOWN_ERROR;
555 if (_net_nfc_app_util_get_data_from_record(msg->records, text, sizeof(text)) == FALSE)
557 DEBUG_ERR_MSG("_net_nfc_app_util_get_data_from_record failed [%d]", result);
558 result = NET_NFC_UNKNOWN_ERROR;
562 ret = net_nfc_app_util_appsvc_launch(operation, uri, mime, text);
564 if (ret == APPSVC_RET_ENOMATCH)
566 /* TODO : check again */
567 ret = net_nfc_app_util_appsvc_launch(operation, uri, mime, text);
571 DEBUG_SERVER_MSG("net_nfc_app_util_appsvc_launch return %d", ret);
576 net_nfc_util_free_ndef_message(msg);
581 static bool net_nfc_app_util_is_dir(const char* path_name)
583 struct stat statbuf = { 0 };
585 if (stat(path_name, &statbuf) == -1)
590 if (S_ISDIR(statbuf.st_mode) != 0)
600 void net_nfc_app_util_clean_storage(char* src_path)
602 struct dirent* ent = NULL;
605 char path[1024] = { 0 };
607 if ((dir = opendir(src_path)) == NULL)
612 while ((ent = readdir(dir)) != NULL)
614 if (strncmp(ent->d_name, ".", 1) == 0 || strncmp(ent->d_name, "..", 2) == 0)
620 snprintf(path, 1024, "%s/%s", src_path, ent->d_name);
622 if (net_nfc_app_util_is_dir(path) != false)
624 net_nfc_app_util_clean_storage(path);
639 void net_nfc_app_util_aul_launch_app(char* package_name, bundle* kb)
642 if((result = aul_launch_app(package_name, kb)) < 0)
647 DEBUG_SERVER_MSG("aul launch error : AUL_R_EINVAL");
650 DEBUG_SERVER_MSG("aul launch error : AUL_R_ECOM");
653 DEBUG_SERVER_MSG("aul launch error : AUL_R_ERROR");
656 DEBUG_SERVER_MSG("aul launch error : unknown ERROR");
662 DEBUG_SERVER_MSG("success to launch [%s]", package_name);
666 int net_nfc_app_util_appsvc_launch(const char *operation, const char *uri, const char *mime, const char *data)
672 bd = bundle_create();
676 if (operation != NULL && strlen(operation) > 0)
678 DEBUG_SERVER_MSG("operation : %s", operation);
679 appsvc_set_operation(bd, operation);
682 if (uri != NULL && strlen(uri) > 0)
684 DEBUG_SERVER_MSG("uri : %s", uri);
685 appsvc_set_uri(bd, uri);
688 if (mime != NULL && strlen(mime) > 0)
690 DEBUG_SERVER_MSG("mime : %s", mime);
691 appsvc_set_mime(bd, mime);
694 if (data != NULL && strlen(data) > 0)
696 DEBUG_SERVER_MSG("data : %s", data);
697 appsvc_add_data(bd, "data", data);
700 bundle_add(bd, OSP_K_COND, OSP_K_COND_TYPE);
701 bundle_add(bd, OSP_K_LAUNCH_TYPE, osp_launch_type_condition);
703 result = appsvc_run_service(bd, 0, NULL, NULL);
710 void _binary_to_string(uint8_t *buffer, uint32_t len, char *out_buf, uint32_t max_len)
714 if (buffer == NULL || len == 0 || out_buf == NULL || max_len == 0)
717 while (len > 0 && current < max_len)
719 current += snprintf(out_buf + current, max_len - current, "%02X", *(buffer++));
724 void _string_to_binary(const char *input, uint8_t *output, uint32_t *length)
729 if (input == NULL || *length == 0 || output == NULL)
732 DEBUG_SERVER_MSG("_string_to_binary ");
734 /* strlen("nfc://secure/aid/") = 17 */
738 while (*input && (current < *length))
740 temp = (*input++) - '0';
747 output[current / 2] += temp;
751 output[current / 2] = temp << 4;
757 *length = current / 2;
760 int net_nfc_app_util_launch_se_transaction_app(uint8_t *aid, uint32_t aid_len, uint8_t *param, uint32_t param_len)
765 bd = bundle_create();
767 appsvc_set_operation(bd, "http://tizen.org/appcontrol/operation/nfc/transaction");
769 /* convert aid to aid string */
770 if (aid != NULL && aid_len > 0)
772 char temp_string[1024] = { 0, };
773 char aid_string[1024] = { 0, };
775 _binary_to_string(aid, aid_len, temp_string, sizeof(temp_string));
776 snprintf(aid_string, sizeof(aid_string), "nfc://secure/aid/%s", temp_string);
777 DEBUG_SERVER_MSG("aid_string : %s", aid_string);
778 appsvc_set_uri(bd, aid_string);
781 if (param != NULL && param_len > 0)
783 char param_string[1024] = { 0, };
785 _binary_to_string(param, param_len, param_string, sizeof(param_string));
786 DEBUG_SERVER_MSG("param_string : %s", param_string);
787 appsvc_add_data(bd, "data", param_string);
790 appsvc_run_service(bd, 0, NULL, NULL);
796 int net_nfc_app_util_encode_base64(uint8_t *buffer, uint32_t buf_len, char *result, uint32_t max_result)
802 if (buffer == NULL || buf_len == 0 || result == NULL || max_result == 0)
806 b64 = BIO_new(BIO_f_base64());
807 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
808 bmem = BIO_new(BIO_s_mem());
809 b64 = BIO_push(b64, bmem);
811 BIO_write(b64, buffer, buf_len);
813 BIO_get_mem_ptr(b64, &bptr);
815 memset(result, 0, max_result);
816 memcpy(result, bptr->data, MIN(bptr->length, max_result - 1));
825 int net_nfc_app_util_decode_base64(const char *buffer, uint32_t buf_len, uint8_t *result, uint32_t *res_len)
830 if (buffer == NULL || buf_len == 0 || result == NULL || res_len == NULL || *res_len == 0)
833 _net_nfc_util_alloc_mem(temp, buf_len);
839 b64 = BIO_new(BIO_f_base64());
840 BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
841 bmem = BIO_new_mem_buf((void *)buffer, buf_len);
842 bmem = BIO_push(b64, bmem);
844 temp_len = BIO_read(bmem, temp, buf_len);
848 memset(result, 0, *res_len);
849 memcpy(result, temp, MIN(temp_len, *res_len));
851 *res_len = MIN(temp_len, *res_len);
853 _net_nfc_util_free_mem(temp);
859 DEBUG_ERR_MSG("alloc failed");
865 static pid_t _net_nfc_app_util_get_focus_app_pid()
867 Ecore_X_Window focus;
872 focus = ecore_x_window_focus_get();
873 if (ecore_x_netwm_pid_get(focus, &pid))
879 bool net_nfc_app_util_check_launch_state()
882 net_nfc_launch_popup_state_e popup_state;
885 focus_app_pid = _net_nfc_app_util_get_focus_app_pid();
887 popup_state = net_nfc_server_gdbus_get_client_popup_state(focus_app_pid);
889 if(popup_state == NET_NFC_NO_LAUNCH_APP_SELECT)
895 static void _play_sound_callback(int id, void *data)
897 DEBUG_MSG("_play_sound_callback");
899 if (WAV_PLAYER_ERROR_NONE != wav_player_stop(id))
901 DEBUG_MSG("wav_player_stop failed");
905 void net_nfc_manager_util_play_sound(net_nfc_sound_type_e sound_type)
908 int bVibrationOn = 0;
910 if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_STATUS_BOOL, &bSoundOn) != 0)
912 DEBUG_MSG("vconf_get_bool failed for Sound");
916 if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &bVibrationOn) != 0)
918 DEBUG_MSG("vconf_get_bool failed for Vibration");
922 if ((sound_type > NET_NFC_TASK_ERROR) || (sound_type < NET_NFC_TASK_START))
924 DEBUG_MSG("Invalid Sound Type");
932 DEBUG_MSG("Play Vibration");
934 if (SVI_SUCCESS == svi_init(&svi_handle))
936 if (SVI_SUCCESS == svi_play_vib(svi_handle, SVI_VIB_TOUCH_SIP))
938 DEBUG_MSG("svi_play_vib success");
941 svi_fini(svi_handle);
947 char *sound_path = NULL;
949 DEBUG_MSG("Play Sound");
953 case NET_NFC_TASK_START :
954 sound_path = strdup(NET_NFC_MANAGER_SOUND_PATH_TASK_START);
956 case NET_NFC_TASK_END :
957 sound_path = strdup(NET_NFC_MANAGER_SOUND_PATH_TASK_END);
959 case NET_NFC_TASK_ERROR :
960 sound_path = strdup(NET_NFC_MANAGER_SOUND_PATH_TASK_ERROR);
964 if (sound_path != NULL)
966 if (WAV_PLAYER_ERROR_NONE == wav_player_start(sound_path, SOUND_TYPE_MEDIA, _play_sound_callback, NULL, NULL))
968 DEBUG_MSG("wav_player_start success");
971 _net_nfc_util_free_mem(sound_path);
975 DEBUG_ERR_MSG("Invalid Sound Path");