Initialize Tizen 2.3
[apps/home/ug-nfc-efl.git] / ug-nfc-share-efl / src / ug-nfc-share-tag.c
1 /*
2   * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3   *
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
7
8   *     http://floralicense.org/license/
9   *
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.
15   */
16
17
18 #include "ug-nfc-share-tag.h"
19 #include "ug-nfc-share-popup.h"
20
21 #include <stdio.h>
22 #include <Elementary.h>
23 #include <Ecore.h>
24 #include <bundle.h>
25 #include <Ecore_X.h>
26 #include <vconf.h>
27 #include <sys/types.h>
28 #include <sys/wait.h>
29
30 /* external library header */
31 #include <mime_type.h>
32 #include <notification.h>
33
34 #define NFC_POPUP_TIMEOUT               3.0
35
36 static ug_nfc_share_tag_type ug_nfc_share_tagType;
37
38
39 int _bt_ipc_send_obex_message(char *address, const uint8_t *files, uint32_t length);
40
41 /*-----------------------------------------------------------------------------------------------*/
42
43 static void _show_status_text(void *data, char *text)
44 {
45         ugdata_t *ug_data = (ugdata_t *)data;
46
47         UG_NFC_SHARE_BEGIN();
48
49         ret_if(ug_data == NULL);
50         ret_if(text == NULL);
51
52         notification_status_message_post(text);
53
54         ug_destroy_me(ug_data->nfc_share_ug);
55
56         UG_NFC_SHARE_END();
57 }
58
59 ug_nfc_share_tag_type ug_nfc_share_get_tag_type(void)
60 {
61         return ug_nfc_share_tagType;
62 }
63
64 void ug_nfc_share_set_tag_type(ug_nfc_share_tag_type tag_type)
65 {
66         if (tag_type < 0 || tag_type >= UG_NFC_SHARE_TAG_MAX)
67                 return;
68
69         ug_nfc_share_tagType = tag_type;
70 }
71
72 nfc_ndef_message_h ug_nfc_share_get_current_ndef(void *data)
73 {
74         ugdata_t *ug_data = (ugdata_t *)data;
75
76         UG_NFC_SHARE_BEGIN();
77
78         retv_if(ug_data == NULL, NULL);
79
80         UG_NFC_SHARE_END();
81
82         return ug_data->current_ndef;
83 }
84
85 ug_nfc_share_result_e ug_nfc_share_set_current_ndef(void *data, nfc_ndef_message_h ndef_msg)
86 {
87         UG_NFC_SHARE_BEGIN();
88
89         ugdata_t *ug_data = (ugdata_t *)data;
90         if (ug_data == NULL)
91         {
92                 UG_NFC_SHARE_DEBUG_ERR("ug_data is null");
93                 return UG_NFC_SHARE_ERROR;
94         }
95
96         if (ug_data->current_ndef != NULL)
97         {
98                 if (nfc_ndef_message_destroy(ug_data->current_ndef) != NFC_ERROR_NONE)
99                 {
100                         UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_message_destroy failed");
101                 }
102         }
103
104         ug_data->current_ndef = ndef_msg;
105
106         UG_NFC_SHARE_END();
107
108         return UG_NFC_SHARE_OK;
109
110 }
111
112 static ug_nfc_share_result_e ug_nfc_share_make_mime_type_data_from_file_path(const char *path, uint8_t *type_data, uint32_t *type_size)
113 {
114         ug_nfc_share_result_e result = UG_NFC_SHARE_ERROR;
115         char *extension = NULL;
116
117         UG_NFC_SHARE_BEGIN();
118
119         retv_if(path == NULL, result);
120         retv_if(type_data == NULL, result);
121         retv_if(type_size == NULL, result);
122
123         UG_NFC_SHARE_DEBUG("typedata = %p, typesize = %d", type_data, *type_size);
124
125         memset(type_data, 0, *type_size);
126         *type_size = 0;
127
128         extension = strrchr(path, '.');
129         UG_NFC_SHARE_DEBUG("extension = %s", GET_SAFE_STRING(extension));
130
131         if (extension != NULL)
132         {
133                 char *mime_str = NULL;
134
135                 if (mime_type_get_mime_type(extension+1, &mime_str) == MIME_TYPE_ERROR_NONE)
136                 {
137                         UG_NFC_SHARE_DEBUG("mime_str[%s]", mime_str);
138
139                         *type_size = strlen(mime_str);
140                         memcpy(type_data, mime_str, *type_size);
141                         result = UG_NFC_SHARE_OK;
142                 }
143                 else
144                 {
145                         UG_NFC_SHARE_DEBUG_ERR("ERROR :: mime_type_get_mime_type failed");
146                         result = UG_NFC_SHARE_ERROR;
147                 }
148         }
149
150         UG_NFC_SHARE_DEBUG("mime type : %s", GET_SAFE_STRING((char *)type_data));
151
152         UG_NFC_SHARE_END();
153
154         return result;
155 }
156
157 ug_nfc_share_result_e ug_nfc_share_make_ndef_message_from_file(nfc_ndef_message_h *msg, const char *path)
158 {
159         int result = UG_NFC_SHARE_ERROR;
160         struct stat st;
161         uint8_t type_buffer[50] = { 0, };
162         int type_size = sizeof(type_buffer);
163         nfc_ndef_record_h record = NULL;
164         FILE *file = NULL;
165         char *file_name = NULL;
166         uint8_t *file_data = NULL;
167         long int file_len = 0;
168
169
170         UG_NFC_SHARE_BEGIN();
171
172         retv_if(msg == NULL, result);
173         retv_if(path == NULL, result);
174         /*Cause of Svace warning */
175         /*Name : TOCTTOU_SEQUENCE
176          Mitigation :
177          1.use fstat inplace of stat
178          2.or using check-Use-Check Pattern
179          */
180         retv_if((stat(path, &st) == -1 && errno == ENOENT), result);
181
182         /* read file and make payload*/
183         file = fopen(path, "r");
184         if (file != NULL)
185         {
186                 long int read_count = 0, read_total = 0;
187
188                 fseek(file, 0, SEEK_END);
189                 file_len = ftell(file);
190                 fseek(file, 0, SEEK_SET);
191
192                 UG_NFC_SHARE_MEM_MALLOC(file_data, file_len, uint8_t);
193                 if (file_data == NULL)
194                 {
195                         UG_NFC_SHARE_DEBUG_ERR("ERROR :: UG_NFC_SHARE_MEM_MALLOC failed");
196
197                         fclose(file);
198
199                         return result;
200                 }
201
202                 do
203                 {
204                         read_count = fread(file_data + read_total, 1, file_len - read_total, file);
205                         read_total += read_count;
206                 }
207                 while (read_count != 0 && read_total < file_len);
208
209                 fclose(file);
210
211                 UG_NFC_SHARE_DEBUG("fread(%s) success, size %ld", path, file_len);
212         }
213         else
214         {
215                 UG_NFC_SHARE_DEBUG_ERR("fopen(%s) error");
216
217                 return result;
218         }
219
220         /* get type data */
221         result = ug_nfc_share_make_mime_type_data_from_file_path(path, type_buffer, (uint32_t *)&type_size);
222         if (result != UG_NFC_SHARE_OK)
223         {
224                 UG_NFC_SHARE_DEBUG_ERR("ERROR :: _make_mime_type_data_from_file_path failed [%d]", result);
225
226                 return result;
227         }
228
229         /* get file name for id */
230         file_name = strrchr(path, '/');
231         if (file_name == NULL)
232         {
233                 file_name = (char *)path;
234         }
235         else
236         {
237                 file_name++;
238         }
239
240         UG_NFC_SHARE_DEBUG("file name : %s", file_name);
241
242         /* create record */
243         result = nfc_ndef_record_create(&record, NFC_RECORD_TNF_MIME_MEDIA, type_buffer, type_size, (uint8_t *)file_name, strlen(file_name), file_data, file_len);
244         if (result != NFC_ERROR_NONE)
245         {
246                 UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_record_create failed (%d)", result);
247
248                 return result;
249         }
250
251         /* make file NDEF message */
252         result = nfc_ndef_message_create(msg);
253         if (result != NFC_ERROR_NONE)
254         {
255                 UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_message_create failed [%d]", result);
256
257                 nfc_ndef_record_destroy(record);
258
259                 return result;
260         }
261
262         /* append record to ndef message */
263         result = nfc_ndef_message_append_record(*msg, record);
264         if (result != NFC_ERROR_NONE)
265         {
266                 UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_message_append_record failed (%d)", result);
267
268                 return result;
269         }
270
271         UG_NFC_SHARE_DEBUG("ug_nfc_share_make_ndef_message_from_file success");
272
273         UG_NFC_SHARE_END();
274
275         return result;
276 }
277
278 /* nfc_handover */
279 ug_nfc_share_result_e ug_nfc_share_make_ndef_message_from_multi_file(nfc_ndef_message_h *msg, const char *path[], int record_count)
280 {
281         int result = UG_NFC_SHARE_ERROR;
282         struct stat st;
283         uint8_t type_buffer[50] = { 0, };
284         int type_size = sizeof(type_buffer);
285         nfc_ndef_record_h record = NULL;
286         FILE *file = NULL;
287         char *file_name = NULL;
288         uint8_t *file_data = NULL;
289         long int file_len = 0;
290         int index;
291
292
293         UG_NFC_SHARE_BEGIN();
294
295         retv_if(msg == NULL, result);
296         retv_if(path == NULL, result);
297         /*Cause of Svace warning */
298         /*Name : TOCTTOU_SEQUENCE
299          Mitigation :
300          1.use fstat inplace of stat
301          2.or using check-Use-Check Pattern
302          */
303
304         for (index = 0; index < record_count; index++)
305         {
306                 retv_if((stat(path[index], &st) == -1 && errno == ENOENT), result);
307
308                 /* read file and make payload*/
309                 file = fopen(path[index], "r");
310
311                 if (file != NULL)
312                 {
313                         long int read_count = 0, read_total = 0;
314
315                         fseek(file, 0, SEEK_END);
316                         file_len = ftell(file);
317                         fseek(file, 0, SEEK_SET);
318
319                         UG_NFC_SHARE_MEM_MALLOC(file_data, file_len, uint8_t);
320                         if (file_data == NULL)
321                         {
322                                 UG_NFC_SHARE_DEBUG_ERR("ERROR :: UG_NFC_SHARE_MEM_MALLOC failed");
323
324                                 fclose(file);
325
326                                 return result;
327                         }
328
329                         do
330                         {
331                                 read_count = fread(file_data + read_total, 1, file_len - read_total, file);
332                                 read_total += read_count;
333                         }
334                         while (read_count != 0 && read_total < file_len);
335
336                         fclose(file);
337
338                         UG_NFC_SHARE_DEBUG("fread(%s) success, size %ld", path[index], file_len);
339                 }
340                 else
341                 {
342                         UG_NFC_SHARE_DEBUG_ERR("fopen(%s) error");
343
344                         return result;
345                 }
346
347                 /* get type data */
348                 result = ug_nfc_share_make_mime_type_data_from_file_path(path[index], type_buffer, (uint32_t *)&type_size);
349                 if (result != UG_NFC_SHARE_OK)
350                 {
351                         UG_NFC_SHARE_DEBUG_ERR("ERROR :: _make_mime_type_data_from_file_path failed [%d]", result);
352
353                         return result;
354                 }
355
356                 /* get file name for id */
357                 file_name = strrchr(path[index], '/');
358                 if (file_name == NULL)
359                 {
360                         file_name = (char *)path[index];
361                 }
362                 else
363                 {
364                         file_name++;
365                 }
366
367                 UG_NFC_SHARE_DEBUG("file name : %s", file_name);
368
369                 /* create record */
370                 result = nfc_ndef_record_create(&record, NFC_RECORD_TNF_MIME_MEDIA, type_buffer, type_size, (uint8_t *)file_name, strlen(file_name), file_data, file_len);
371                 if (result != NFC_ERROR_NONE)
372                 {
373                         UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_record_create failed (%d)", result);
374
375                         return result;
376                 }
377
378                 /* make file NDEF message */
379                 result = nfc_ndef_message_create(msg);
380                 if (result != NFC_ERROR_NONE)
381                 {
382                         UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_message_create failed [%d]", result);
383
384                         nfc_ndef_record_destroy(record);
385
386                         return result;
387                 }
388
389                 /* append record to ndef message */
390                 result = nfc_ndef_message_append_record(*msg, record);
391                 if (result != NFC_ERROR_NONE)
392                 {
393                         UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_message_append_record failed (%d)", result);
394
395                         return result;
396                 }
397
398                 UG_NFC_SHARE_DEBUG("ug_nfc_share_make_ndef_message_from_file success");
399
400                 UG_NFC_SHARE_END();
401         }
402         return result;
403 }
404
405 void _ug_nfc_share_get_bt_addr_from_string(uint8_t *addr, char *addr_string)
406 {
407         char *temp = NULL;
408
409         if (addr == NULL || addr_string == NULL)
410         {
411                 return;
412         }
413
414         UG_NFC_SHARE_DEBUG("string : %s", addr_string);
415
416         UG_NFC_SHARE_MEM_STRDUP(temp, addr_string);
417         if (temp != NULL)
418         {
419                 char *token = NULL;
420                 long value;
421                 int count = 0;
422
423                 token = strtok(temp, ":");
424
425                 do
426                 {
427                         value = strtol(token, NULL, 16);
428
429                         addr[count++] = (uint8_t)value;
430                 }
431                 while ((token = strtok(NULL, ":")) != NULL);
432         }
433         UG_NFC_SHARE_MEM_FREE(temp);
434 }
435
436 static void _p2p_connection_handover_completed_cb(nfc_error_e result, nfc_ac_type_e carrior, void *ac_data, int ac_data_size, void *user_data)
437 {
438         UG_NFC_SHARE_BEGIN();
439
440         ugdata_t* ug_data = (ugdata_t*)user_data;
441
442         /* To prevent write event during showing popup, unset response callback */
443         ug_nfc_unset_nfc_callback();
444
445         /* nfc deactivate */
446         if(nfc_manager_deinitialize () != NFC_ERROR_NONE)
447         {
448                 UG_NFC_SHARE_DEBUG_ERR("nfc_manager_deinitialize failed");
449         }
450
451         if(result == NFC_ERROR_NONE)
452         {
453                 char *data = NULL;
454
455                 UG_NFC_SHARE_DEBUG("p2p_connection_handover is completed");
456
457                 data = (char *)bundle_get_val(ug_data->bd, "request_data");
458
459                 UG_NFC_SHARE_DEBUG("uri[%d] = %s", strlen(data), data);
460
461                 if (_bt_ipc_send_obex_message((char *)ac_data, (uint8_t *)data, strlen(data) + 1) == 0)
462                 {
463                         _show_status_text(ug_data, IDS_SHARED);
464                 }
465                 else
466                 {
467                         UG_NFC_SHARE_DEBUG_ERR("_bt_ipc_send_obex_message failed");
468
469                         _show_status_text(ug_data, IDS_UNABLE_TO_SHARE);
470                 }
471         }
472         else
473         {
474                 UG_NFC_SHARE_DEBUG_ERR("p2p_connection_handover failed");
475
476                 _show_status_text(ug_data, IDS_UNABLE_TO_SHARE);
477         }
478
479         UG_NFC_SHARE_END();
480 }
481
482 static void _p2p_send_completed_cb(nfc_error_e result, void *user_data)
483 {
484         UG_NFC_SHARE_BEGIN();
485
486         ugdata_t* ug_data = (ugdata_t*)user_data;
487
488         /* To prevent write event during showing popup, unset response callback */
489         ug_nfc_unset_nfc_callback();
490
491         /* nfc deactivate */
492         if(nfc_manager_deinitialize () != NFC_ERROR_NONE)
493         {
494                 UG_NFC_SHARE_DEBUG_ERR("nfc_manager_deinitialize failed");
495         }
496
497         if(result == NFC_ERROR_NONE)
498         {
499                 UG_NFC_SHARE_DEBUG("_p2p_send_completed_cb is completed");
500
501                 _show_status_text(ug_data, IDS_SHARED);
502         }
503         else
504         {
505                 UG_NFC_SHARE_DEBUG_ERR("_p2p_send_completed_cb failed");
506
507                 _show_status_text(ug_data, IDS_UNABLE_TO_SHARE);
508         }
509
510         UG_NFC_SHARE_END();
511 }
512
513 static void _p2p_target_discovered_cb(nfc_discovered_type_e type, nfc_p2p_target_h target, void *user_data)
514 {
515         UG_NFC_SHARE_BEGIN();
516
517         ugdata_t* ug_data = (ugdata_t*)user_data;
518
519         if(type == NFC_DISCOVERED_TYPE_ATTACHED)
520         {
521                 int result = NFC_ERROR_NONE;
522
523                 UG_NFC_SHARE_DEBUG("NFC_DISCOVERED_TYPE_ATTACHED");
524
525                 if (ug_nfc_share_get_tag_type() == UG_NFC_SHARE_TAG_HANDOVER)
526                 {
527                         UG_NFC_SHARE_DEBUG("UG_NFC_SHARE_TAG_HANDOVER");
528
529                         /* The code below will be changed after capi is completed */
530                         if ((result = nfc_p2p_connection_handover(target, NFC_AC_TYPE_UNKNOWN, _p2p_connection_handover_completed_cb, ug_data)) != NFC_ERROR_NONE)
531                         {
532                                 UG_NFC_SHARE_DEBUG_ERR("nfc_p2p_connection_handover failed [%d]", result);
533                         }
534
535                         return;
536                 }
537                 else
538                 {
539                         nfc_ndef_message_h msg = NULL;
540
541                         msg = ug_nfc_share_get_current_ndef(ug_data);
542                         if(msg == NULL)
543                         {
544                                 UG_NFC_SHARE_DEBUG_ERR("nfc_ndef_message_h is NULL!!");
545                                 return;
546                         }
547
548                         result = nfc_p2p_send(target, msg, _p2p_send_completed_cb, ug_data);
549                         if(result != NFC_ERROR_NONE)
550                         {
551                                 UG_NFC_SHARE_DEBUG_ERR("nfc_p2p_send failed[%d]", result);
552                                 return;
553                         }
554                 }
555         }
556         else
557         {
558                 UG_NFC_SHARE_DEBUG("NFC_DISCOVERED_TYPE_DETACHED");
559         }
560
561         UG_NFC_SHARE_END();
562 }
563
564 void ug_nfc_set_nfc_callback(void *user_data)
565 {
566         UG_NFC_SHARE_BEGIN();
567
568         nfc_manager_set_p2p_target_discovered_cb(_p2p_target_discovered_cb, user_data);
569
570         UG_NFC_SHARE_END();
571 }
572
573 void ug_nfc_unset_nfc_callback(void)
574 {
575         UG_NFC_SHARE_BEGIN();
576
577         nfc_manager_unset_p2p_target_discovered_cb();
578
579         UG_NFC_SHARE_END();
580 }
581
582 int _bt_ipc_send_obex_message(char *address, const uint8_t *files, uint32_t length)
583 {
584         int result = 0;
585         uint32_t i, count = 1;
586         E_DBus_Connection *conn = NULL;
587
588         UG_NFC_SHARE_BEGIN();
589
590         if (address == NULL || files == NULL)
591         {
592                 UG_NFC_SHARE_DEBUG_ERR("invalid param [%p] [%p]", address, files);
593                 return 0;
594         }
595
596         /* count files */
597         for (i = 0; i < length; i++)
598         {
599                 if (files[i] == '?')
600                 {
601                         count++;
602                 }
603         }
604
605         if (e_dbus_init() > 0)
606         {
607                 if ((conn = e_dbus_bus_get(DBUS_BUS_SYSTEM)) != NULL)
608                 {
609                         DBusMessage *msg = NULL;
610
611                         if (e_dbus_request_name(conn, "User.Bluetooth.UG", 0, NULL, NULL) != NULL)
612                         {
613                                 if ((msg = dbus_message_new_signal("/org/projectx/connect_device", "User.Bluetooth.UG", "Send")) != NULL)
614                                 {
615                                         int reserved = 0;
616                                         char *type = "nfc";
617                                         char *name = address;
618                                         uint8_t temp[6] = { 0, };
619                                         uint8_t *addr = temp;
620
621                                         _ug_nfc_share_get_bt_addr_from_string(temp, address);
622
623                                         UG_NFC_SHARE_DEBUG("msg [%p], reserved [%d], address [%02X:%02X:%02X:%02X:%02X:%02X], count [%d], files [%s]", msg, reserved, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], count, files);
624
625                                         if (dbus_message_append_args(msg,
626                                                                                                 DBUS_TYPE_INT32, &reserved,
627                                                                                                 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, 6,
628                                                                                                 DBUS_TYPE_INT32, &count,
629                                                                                                 DBUS_TYPE_STRING, &files,
630                                                                                                 DBUS_TYPE_STRING, &type,
631                                                                                                 DBUS_TYPE_STRING, &name,
632                                                                                                 DBUS_TYPE_INVALID))
633                                         {
634                                                 e_dbus_message_send(conn, msg, NULL, -1, NULL);
635
636                                                 UG_NFC_SHARE_DEBUG("Send success");
637                                         }
638                                         else
639                                         {
640                                                 UG_NFC_SHARE_DEBUG_ERR("Connect sending failed");
641
642                                                 result = -1;
643                                         }
644
645                                         dbus_message_unref(msg);
646                                 }
647                                 else
648                                 {
649                                         UG_NFC_SHARE_DEBUG_ERR("dbus_message_new_signal failed");
650
651                                         result = -1;
652                                 }
653                         }
654                         else
655                         {
656                                 UG_NFC_SHARE_DEBUG_ERR("e_dbus_request_name failed");
657
658                                 result = -1;
659                         }
660                 }
661                 else
662                 {
663                         UG_NFC_SHARE_DEBUG_ERR("e_dbus_bus_get failed");
664
665                         result = -1;
666                 }
667
668                 e_dbus_shutdown();
669         }
670         else
671         {
672                 UG_NFC_SHARE_DEBUG_ERR("e_dbus_init failed");
673
674                 result = -1;
675         }
676
677         UG_NFC_SHARE_END();
678
679         return result;
680 }