Merge branch 'tizen_5.5' into tizen
[platform/core/uifw/capi-ui-sticker.git] / receiver / src / ft.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
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 #include <stdio.h>
18 #include <glib.h>
19 #include <dlog.h>
20 #include <service_app.h>
21 #include <app_common.h>
22 #include <sap.h>
23 #include <sap_file_transfer.h>
24 #include <sticker_provider.h>
25 #include <string.h>
26 #include <string>
27 #include <unistd.h>
28 #include <linux/limits.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <pwd.h>
32 #include <json-glib/json-glib.h>
33 #include <vconf.h>
34
35 #include "ft.h"
36 #include "log.h"
37 #include "sticker_info.h"
38 #include "message.h"
39 #include "sync_alarm.h"
40
41 #define ACCESSORY_SERVICE_PROFILE_ID "/sample/filetransfersender"
42 #define ACCESSORY_SERVICE_CHANNEL_ID 107
43
44 #define STICKER_SYNC_FEATURE_REQ "sticker-sync-feature-req"
45 #define STICKER_SYNC_FEATURE_RSP "sticker-sync-feature-rsp"
46 #define STICKER_SYNC_START_REQ "sticker-sync-start-req"
47 #define STICKER_SYNC_START_RSP "sticker-sync-start-rsp"
48 #define STICKER_SEND_START_REQ "sticker-send-start-req"
49 #define STICKER_SEND_START_RSP "sticker-send-start-rsp"
50 #define STICKER_SEND_FACE_DATA "sticker-send-face-data"
51 #define STICKER_SEND_STOP_REQ  "sticker-send-stop-req"
52 #define STICKER_SEND_STOP_RSP  "sticker-send-stop-rsp"
53
54 #ifndef VCONFKEY_STICKER_SUPPORTED_FEATURE
55 #define VCONFKEY_STICKER_SUPPORTED_FEATURE  "db/sticker/supported_feature"
56
57 enum {
58     VCONFKEY_STICKER_FEATURE_NONE = 0x00,
59     VCONFKEY_STICKER_FEATURE_AREMOJI = 0x01,
60     VCONFKEY_STICKER_FEATURE_BITMOJI = 0x02
61 };
62 #endif
63
64 using namespace std;
65
66 typedef enum {
67     REQUEST_TYPE_SYNC,
68     REQUEST_TYPE_FEATURE_REQ
69 } request_type;
70
71 enum {
72     SYNC_START_RSP_SUCCESS = 1000,
73     SYNC_START_RSP_NO_STICKER = 1001
74 };
75
76 struct sap_info_s {
77     sap_agent_h agent;
78     sap_socket_h socket;
79     sap_peer_agent_h peer_agent;
80     sap_file_transaction_h file_socket;
81 };
82
83 struct request {
84     request_type req_type;
85     string mode;
86     string category;
87     string type;
88 };
89
90 static void _reset_sticker_data();
91
92 struct sticker_info {
93     string file_path;
94     string group;
95     string keyword;
96     string disp_type;
97     string description;
98
99     sticker_info()
100     {
101         _reset_sticker_data();
102     }
103 };
104
105 static struct sap_info_s priv_data = { 0 };
106 static struct sticker_info sticker_data;
107 static struct request pending_request, current_request;
108
109 gboolean file_on_progress = 0;
110 static string incoming_file_name;
111 static int t_id = 0;
112 static int rec_file_cnt = 0;
113 static int total_file_count = 0;
114
115 static gboolean _send_json_data(JsonObject *obj)
116 {
117     JsonGenerator *j_generator = NULL;
118     JsonNode *j_node = NULL;
119     gsize size = 0;
120     gchar *data = NULL;
121     int result = 1;
122
123     j_generator = json_generator_new();
124     if (j_generator == NULL) {
125         LOGE("Unable to json_generator_new");
126         goto cleanup;
127     }
128
129     j_node = json_node_new(JSON_NODE_OBJECT);
130     if (j_node == NULL) {
131         LOGE("Unable to json_node_new");
132         goto cleanup;
133     }
134
135     json_node_set_object(j_node, obj);
136     json_generator_set_root(j_generator, j_node);
137
138     data = json_generator_to_data(j_generator, &size);
139     if (data == NULL) {
140         LOGE("Unable to json_generator_to_data");
141         goto cleanup;
142     }
143
144     if (priv_data.socket) {
145         LOGD("Send JSON data : %s", data);
146         result = sap_socket_send_data(priv_data.socket, ACCESSORY_SERVICE_CHANNEL_ID, strlen(data), (void *)data);
147     }
148
149 cleanup:
150     if (data)
151         g_free(data);
152
153     if (j_node)
154         json_node_free(j_node);
155
156     if (j_generator)
157         g_object_unref(j_generator);
158
159     return result ? FALSE : TRUE;
160 }
161
162 static void notify_sync_progress(unsigned int file_progress)
163 {
164     if (total_file_count == 0)
165         return;
166
167     double total_progress = (((double)rec_file_cnt / (double)total_file_count) + (1.0/(double)total_file_count*file_progress/100))*100;
168
169     LOGI("(%2d / %2d), file progress : %3u%%, total progress : %3u%%", rec_file_cnt, total_file_count, file_progress, (unsigned int)total_progress);
170     char progress_str[32];
171     snprintf(progress_str, sizeof(progress_str), "%u", (unsigned int)total_progress);
172     send_message("sync_progress", progress_str);
173 }
174
175 static void _on_send_completed(sap_file_transaction_h file_transaction,
176                                sap_ft_transfer_e result,
177                                const char *file_path,
178                                void *user_data)
179 {
180     if (priv_data.file_socket) {
181         sap_file_transfer_destroy(file_transaction);
182         priv_data.file_socket = NULL;
183     }
184
185     if (result == SAP_FT_TRANSFER_SUCCESS) {
186         LOGI("Transfer Completed");
187
188         if (chmod(sticker_data.file_path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
189             LOGE("Failed to change permission : %s. error : %s", sticker_data.file_path.c_str(), strerror(errno));
190         }
191         else {
192             LOGI("Succeed to change permission : %s", sticker_data.file_path.c_str());
193             if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
194                 insert_sticker_data(sticker_data.file_path.c_str(), sticker_data.keyword.c_str(), sticker_data.group.c_str(), sticker_data.description.c_str());
195                 destroy_sticker_provider_handle();
196
197                 if (unlink(sticker_data.file_path.c_str()) == -1)
198                     LOGE("Failed to remove sticker file");
199             }
200         }
201
202         rec_file_cnt++;
203     } else {
204         switch (result) {
205             case (SAP_FT_TRANSFER_FAIL_CHANNEL_IO): {
206                 LOGW("Channel IO Error.");
207                 break;
208             }
209
210             case (SAP_FT_TRANSFER_FAIL_FILE_IO): {
211                 LOGW("File IO Error.");
212                 break;
213             }
214
215             case (SAP_FT_TRANSFER_FAIL_CMD_DROPPED):
216             {
217                 LOGW("Transfer dropped.");
218                 break;
219             }
220
221             case (SAP_FT_TRANSFER_FAIL_PEER_UNRESPONSIVE):
222             {
223                 LOGW("Peer Un Responsive.");
224                 break;
225             }
226
227             case (SAP_FT_TRANSFER_FAIL_PEER_CONN_LOST):
228             {
229                 LOGW("Connection Lost.");
230                 break;
231             }
232
233             case (SAP_FT_TRANSFER_FAIL_PEER_CANCELLED):
234             {
235                 LOGW("Peer Cancelled.");
236                 break;
237             }
238
239             case (SAP_FT_TRANSFER_FAIL_SPACE_NOT_AVAILABLE):
240             {
241                 LOGW("No Space.");
242                 break;
243             }
244
245             default:
246                 LOGW("Unknown Error");
247                 break;
248         }
249     }
250
251     file_on_progress = 0;
252 }
253
254 static void _on_sending_file_in_progress(sap_file_transaction_h file_transaction,
255                                          unsigned short int percentage_progress,
256                                          void *user_data)
257 {
258     notify_sync_progress(percentage_progress);
259 }
260
261 static void __set_file_transfer_cb(sap_file_transaction_h file_socket)
262 {
263     LOGI("# set callbacks");
264     sap_file_transfer_set_progress_cb(file_socket, _on_sending_file_in_progress, NULL);
265
266     sap_file_transfer_set_done_cb(file_socket, _on_send_completed, NULL);
267 }
268
269 void accept_file()
270 {
271     int ret;
272     char file_path[PATH_MAX];
273     char *data_path = NULL;
274
275     data_path = app_get_shared_data_path();
276     LOGI("Path : %s", data_path);
277     sprintf(file_path, "%s/%s", data_path, incoming_file_name.c_str());
278     LOGI("Receive filepath : %s", file_path);
279     sticker_data.file_path = string(file_path);
280     free(data_path);
281
282     ret = sap_file_transfer_receive(priv_data.file_socket, file_path);
283     switch(ret) {
284         case SAP_RESULT_PERMISSION_DENIED:
285             LOGW("permission denied");
286             break;
287         case SAP_RESULT_FAILURE:
288             LOGW("Fail");
289             break;
290         case SAP_RESULT_SUCCESS:
291             LOGI("Success");
292             break;
293     }
294
295     file_on_progress = 1;
296 }
297
298 void request_sticker_data(const char *mode, const char *category, const char *type)
299 {
300     JsonObject *j_object = json_object_new();
301     if (j_object == NULL) {
302         LOGE("json object create error");
303         return;
304     }
305
306     json_object_set_string_member(j_object, "msgId", STICKER_SYNC_START_REQ);
307     json_object_set_int_member(j_object, "tID", ++t_id);
308     json_object_set_string_member(j_object, "mode", mode);
309     json_object_set_string_member(j_object, "category", category);
310     json_object_set_string_member(j_object, "type", type);
311
312     if (_send_json_data(j_object) == FALSE) {
313         pending_request.req_type = REQUEST_TYPE_SYNC;
314         pending_request.mode = string(mode ? mode : "manual");
315         pending_request.category = string(category? category : "arsticker");
316         pending_request.type = string(type ? type : "input");
317
318         LOGI("Push sync request");
319     }
320     else {
321         current_request.req_type = REQUEST_TYPE_SYNC;
322         current_request.mode = string(mode ? mode : "manual");
323         current_request.category = string(category? category : "arsticker");
324         current_request.type = string(type ? type : "input");
325     }
326
327     json_object_unref(j_object);
328 }
329
330 void request_sticker_feature()
331 {
332     JsonObject *j_object = json_object_new();
333     if (j_object == NULL) {
334         LOGE("json object create error");
335         return;
336     }
337
338     json_object_set_string_member(j_object, "msgId", STICKER_SYNC_FEATURE_REQ);
339     json_object_set_int_member(j_object, "tID", ++t_id);
340
341     if (_send_json_data(j_object) == FALSE) {
342         pending_request.req_type = REQUEST_TYPE_FEATURE_REQ;
343         LOGE("Failed to send STICKER_SYNC_FEATURE_REQ");
344     }
345
346     json_object_unref(j_object);
347 }
348
349 void reject_file()
350 {
351     int ret = sap_file_transfer_reject(priv_data.file_socket);
352     LOGI("ret : %d", ret);
353
354     file_on_progress = 0;
355 }
356
357 static void _on_receive_file_cb(sap_peer_agent_h peer_agent_h,
358                                 sap_file_transaction_h socket,
359                                 const char *file_path,
360                                 void *user_data)
361 {
362     file_on_progress = 1;
363     priv_data.file_socket = socket;
364     LOGI("# incoming file request.");
365     __set_file_transfer_cb(priv_data.file_socket);
366
367     incoming_file_name = file_path;
368     std::size_t found = incoming_file_name.find_last_of("/");
369     incoming_file_name = incoming_file_name.substr(found+1);
370
371     LOGI("# file path : %s, incoming file name : %s", file_path, incoming_file_name.c_str());
372
373     accept_file();
374 }
375
376 void conn_terminated(sap_peer_agent_h peer_agent,
377                      sap_socket_h socket,
378                      sap_service_connection_terminated_reason_e result,
379                      void *user_data)
380 {
381     sap_info_s *priv = NULL;
382     priv = (sap_info_s *)user_data;
383
384     switch (result)
385     {
386     case SAP_CONNECTION_TERMINATED_REASON_PEER_DISCONNECTED:
387         LOGW("Peer Disconnected");
388         break;
389     case SAP_CONNECTION_TERMINATED_REASON_DEVICE_DETACHED:
390         LOGW("Disconnected Device Detached");
391         break;
392     case SAP_CONNECTION_TERMINATED_REASON_UNKNOWN:
393         LOGW("Disconnected Unknown Reason");
394         break;
395     default:
396         LOGW("connection terminated. reason : %d", result);
397         break;
398     }
399
400     sap_socket_destroy(priv->socket);
401     priv->socket = NULL;
402
403     service_app_exit();
404 }
405
406 static void _reset_sticker_data()
407 {
408     sticker_data.file_path.clear();
409     sticker_data.group.clear();
410     sticker_data.keyword.clear();
411     sticker_data.disp_type.clear();
412     sticker_data.description.clear();
413 }
414
415 void
416 on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned int payload_length, void *buffer,
417                  void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
418 {
419     unsigned int buf_len = strlen((char *)buffer);
420     LOGI("received data: %s, len: %d, buffer len : %d", (char *)buffer, payload_length, buf_len);
421
422     JsonParser *parser = json_parser_new();
423     GError *err_msg = NULL;
424     JsonNode *root = NULL;
425     JsonObject *root_obj = NULL;
426     string msg_id;
427     const char *json_msgid = NULL;
428
429     json_parser_load_from_data(parser, (char *)buffer, payload_length, &err_msg);
430     if (err_msg) {
431         LOGE("failed to load json file. error message: %s", err_msg->message);
432         goto cleanup;
433     }
434
435     root = json_parser_get_root(parser);
436     if (root == NULL) {
437         LOGE("failed to get root");
438         goto cleanup;
439     }
440
441     root_obj = json_node_get_object(root);
442     if (root_obj == NULL) {
443         LOGE("failed to get object");
444         goto cleanup;
445     }
446
447     json_msgid = json_object_get_string_member(root_obj, "msgId");
448     msg_id = string(json_msgid ? json_msgid : "");
449     if (msg_id == STICKER_SYNC_FEATURE_RSP) {
450         LOGD("msg : %s", msg_id.c_str());
451         const char *json_aremoji = json_object_get_string_member(root_obj, "arEmoji");
452         const char *json_bitmoji = json_object_get_string_member(root_obj, "bitmoji");
453         string support_aremoji = string(json_aremoji ? json_aremoji : "");
454         string support_bitmoji = string(json_bitmoji ? json_bitmoji : "");
455         int supported_feature = VCONFKEY_STICKER_FEATURE_NONE;
456
457         if (support_aremoji == "support")
458             supported_feature |= VCONFKEY_STICKER_FEATURE_AREMOJI;
459
460         if (support_bitmoji == "support")
461             supported_feature |= VCONFKEY_STICKER_FEATURE_BITMOJI;
462
463         if (vconf_set_int(VCONFKEY_STICKER_SUPPORTED_FEATURE, supported_feature) == 0)
464             LOGD("Succeed to set supported feature");
465         else
466             LOGW("Fail to set supported feature");
467
468         service_app_exit();
469     } else if (msg_id == STICKER_SYNC_START_RSP) {
470         LOGD("msg : %s", msg_id.c_str());
471         const char *json_result = json_object_get_string_member(root_obj, "result");
472         string result = string(json_result ? json_result : "");
473         int result_code = json_object_get_int_member(root_obj, "resultCode");
474         LOGD("result : %s, resultCode : %d", result.c_str(), result_code);
475
476         string response_to_app;
477         switch (result_code) {
478         case SYNC_START_RSP_SUCCESS:
479             response_to_app = "success";
480             break;
481         case SYNC_START_RSP_NO_STICKER:
482             response_to_app = "no_sticker";
483             break;
484         default:
485             response_to_app = "unknown_error";
486             break;
487         }
488
489         send_message("sync_start_response", response_to_app.c_str());
490
491         if (result_code != SYNC_START_RSP_SUCCESS)
492             service_app_exit();
493     } else if (msg_id == STICKER_SEND_START_REQ) {
494         LOGD("msg : %s", msg_id.c_str());
495         total_file_count = 0;
496         rec_file_cnt = 0;
497         t_id = json_object_get_int_member(root_obj, "tID");
498         JsonArray *file_list = json_object_get_array_member(root_obj, "list");
499         if (file_list) {
500             int arr_len = json_array_get_length(file_list);
501             for (int i = 0; i < arr_len; i++) {
502                 JsonObject *file_obj = json_array_get_object_element(file_list, i);
503                 int file_len = json_object_get_int_member(file_obj, "size");
504                 const char *json_filename = json_object_get_string_member(file_obj, "fileName");
505                 string file_name = string(json_filename ? json_filename : "");
506
507                 if (file_len > 0) {
508                     LOGD("Add file : %s, len : %d", file_name.c_str(), file_len);
509                     total_file_count++;
510                 } else {
511                     LOGD("Delete file : %s, len : %d", file_name.c_str(), file_len);
512                     if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
513                         delete_sticker_data(file_name.c_str());
514                         destroy_sticker_provider_handle();
515                     }
516                 }
517             }
518         }
519
520         JsonObject *j_object = json_object_new();
521         if (j_object == NULL) {
522             LOGE("Unable to json_object_new");
523             goto cleanup;
524         }
525
526         json_object_set_string_member(j_object, "msgId", STICKER_SEND_START_RSP);
527         json_object_set_int_member(j_object, "tID", t_id);
528         json_object_set_string_member(j_object, "result", "success");
529
530         if (_send_json_data(j_object) == FALSE)
531             LOGE("Failed to send message");
532
533         json_object_unref(j_object);
534     } else if (msg_id == STICKER_SEND_FACE_DATA) {
535         LOGD("msg : %s", msg_id.c_str());
536         _reset_sticker_data();
537
538         const char *type_data = json_object_get_string_member(root_obj, "type");
539         if (type_data)
540             sticker_data.disp_type = string(type_data);
541
542         const char *category = json_object_get_string_member(root_obj, "category");
543         if (category) {
544             sticker_data.group = string(category);
545             sticker_data.keyword = string(category);
546         }
547     } else if (msg_id == STICKER_SEND_STOP_REQ) {
548         LOGD("msg : %s", msg_id.c_str());
549         const char *json_reason = json_object_get_string_member(root_obj, "reason");
550         string reason = string(json_reason ? json_reason : "");
551         int file_len = json_object_get_int_member(root_obj, "count");
552
553         JsonObject *j_object = json_object_new();
554         if (j_object == NULL) {
555             LOGE("Unable to json_object_new");
556             goto cleanup;
557         }
558
559         json_object_set_string_member(j_object, "msgId", STICKER_SEND_STOP_RSP);
560         json_object_set_int_member(j_object, "tID", t_id);
561
562         if (reason == "complete" && rec_file_cnt != file_len)
563             json_object_set_string_member(j_object, "result", "failure");
564         else {
565             int complete_flags = 0;
566             if (vconf_get_int(VCONFKEY_STICKER_SYNC_COMPLETE, &complete_flags) == 0) {
567                 if (sticker_data.group == string("arsticker"))
568                     complete_flags |= 0x1;
569                 else if (sticker_data.group == string("bitmoji"))
570                     complete_flags |= 0x2;
571
572                 LOGD("sync complete flag : %x", complete_flags);
573
574                 if (vconf_set_int(VCONFKEY_STICKER_SYNC_COMPLETE, complete_flags) == 0)
575                     LOGD("Succeed to set sync complete");
576                 else
577                     LOGW("Fail to set sync complete");
578             }
579             else {
580                 LOGW("Failed to get sticker sync flags");
581             }
582
583             json_object_set_string_member(j_object, "result", "success");
584
585             if (current_request.mode == string("manual")) {
586                 if (!sync_alarm_exist())
587                     sync_alarm_register(APP_CONTROL_OPERATION_SYNC_ALARM, SYNC_ALARM_DELAY, SYNC_ALARM_INTERVAL);
588             }
589         }
590
591         if (_send_json_data(j_object) == FALSE)
592             LOGE("Failed to send message");
593
594         send_message("sync_stop_result", reason.c_str());
595
596         json_object_unref(j_object);
597
598         current_request.mode.clear();
599         current_request.category.clear();
600         current_request.type.clear();
601
602         service_app_exit();
603     } else
604         LOGW("unknown msg id : %s", msg_id.c_str());
605
606 cleanup:
607     if (err_msg)
608         g_error_free(err_msg);
609
610     if (parser)
611         g_object_unref(parser);
612 }
613
614 static void on_conn_req(sap_peer_agent_h peer_agent,
615                         sap_socket_h socket,
616                         sap_service_connection_result_e result,
617                         void *user_data)
618 {
619     switch (result)
620     {
621     case SAP_CONNECTION_SUCCESS:
622         LOGI("Connection success");
623         priv_data.socket = socket;
624         sap_peer_agent_accept_service_connection(peer_agent);
625         sap_peer_agent_set_service_connection_terminated_cb(peer_agent, conn_terminated, &priv_data);
626         sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
627         break;
628     case SAP_CONNECTION_ALREADY_EXIST:
629         priv_data.socket = socket;
630         LOGI("Connection Already Exist");
631         break;
632     case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
633         LOGW("Connection failure device unreachable");
634         break;
635     case SAP_CONNECTION_FAILURE_INVALID_PEERAGENT:
636         LOGW("Connection failure invalid peer agent");
637         break;
638     case SAP_CONNECTION_FAILURE_NETWORK:
639         LOGW("Connection failure network");
640         break;
641     case SAP_CONNECTION_FAILURE_PEERAGENT_NO_RESPONSE:
642         LOGW("Connection failure peer agent no response");
643         break;
644     case SAP_CONNECTION_FAILURE_PEERAGENT_REJECTED:
645         LOGW("Connection failure peer agent rejected");
646         break;
647     case SAP_CONNECTION_FAILURE_UNKNOWN:
648         LOGW("Connection failure unknown");
649         break;
650     default:
651         LOGW("Connection failure. error code : %d", result);
652         break;
653     }
654 }
655
656 static void
657 _on_service_connection_created(sap_peer_agent_h peer_agent,
658                                sap_socket_h socket,
659                                sap_service_connection_result_e result,
660                                void *user_data)
661 {
662     sap_info_s *priv = (sap_info_s *)user_data;
663
664     switch (result)
665     {
666     case SAP_CONNECTION_SUCCESS:
667         sap_peer_agent_set_service_connection_terminated_cb(priv->peer_agent,
668                                                             conn_terminated,
669                                                             priv);
670
671         sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
672         priv->socket = socket;
673         LOGI("Connection Established");
674
675         LOGD("pending_request : %d", pending_request.req_type);
676
677         if (pending_request.req_type == REQUEST_TYPE_FEATURE_REQ) {
678             LOGD("[Request feature exchange]");
679             request_sticker_feature();
680         }
681         else if (pending_request.req_type == REQUEST_TYPE_SYNC) {
682             if (!pending_request.mode.empty()) {
683                 LOGD("[Request to sync sticker] mode: %s, category: %s, type : %s", pending_request.mode.c_str(),
684                                                                                     pending_request.category.c_str(),
685                                                                                     pending_request.type.c_str());
686
687                 request_sticker_data(pending_request.mode.c_str(), pending_request.category.c_str(), pending_request.type.c_str());
688
689                 pending_request.mode.clear();
690                 pending_request.category.clear();
691                 pending_request.type.clear();
692             }
693         }
694
695         break;
696
697     case SAP_CONNECTION_ALREADY_EXIST:
698         priv->socket = socket;
699         LOGI("Connection Already Exist");
700         break;
701
702     case SAP_CONNECTION_FAILURE_DEVICE_UNREACHABLE:
703         LOGW("Connection Failure device unreachable");
704         break;
705
706     case SAP_CONNECTION_FAILURE_INVALID_PEERAGENT:
707         LOGW("Connection Failure invalid peer agent");
708         break;
709
710     case SAP_CONNECTION_FAILURE_NETWORK:
711         LOGW("Connection Failure network");
712         break;
713
714     case SAP_CONNECTION_FAILURE_PEERAGENT_NO_RESPONSE:
715         LOGW("Connection Failure peer agent no response");
716         break;
717
718     case SAP_CONNECTION_FAILURE_PEERAGENT_REJECTED:
719         LOGW("Connection Failure peer agent rejected");
720         break;
721
722     case SAP_CONNECTION_FAILURE_UNKNOWN:
723         LOGW("Connection Failure peer agent unknown");
724         break;
725
726     case SAP_CONNECTION_IN_PROGRESS:
727         LOGW("Connection in progress");
728         break;
729
730     case SAP_CONNECTION_PEER_AGENT_NOT_SUPPORTED:
731         LOGW("Connection peer agent not supported");
732         break;
733     }
734 }
735
736 static gboolean
737 _create_service_connection(gpointer user_data)
738 {
739     sap_info_s *priv = (sap_info_s *)user_data;
740     int result = sap_agent_request_service_connection(priv->agent,
741                                                       priv->peer_agent,
742                                                       _on_service_connection_created,
743                                                       priv);
744
745     LOGD("request connection result : %d", result);
746
747     return FALSE;
748 }
749
750 static void
751 _on_peer_agent_updated(sap_peer_agent_h peer_agent,
752                        sap_peer_agent_status_e peer_status,
753                        sap_peer_agent_found_result_e result,
754                        void *user_data)
755 {
756     sap_info_s *priv = (sap_info_s *)user_data;
757
758     switch (result)
759     {
760     case SAP_PEER_AGENT_FOUND_RESULT_DEVICE_NOT_CONNECTED:
761         LOGW("SAP_PEER_AGENT_FOUND_RESULT_DEVICE_NOT_CONNECTED");
762         break;
763
764     case SAP_PEER_AGENT_FOUND_RESULT_FOUND:
765         if (peer_status == SAP_PEER_AGENT_STATUS_AVAILABLE)
766         {
767             LOGD("SAP_PEER_AGENT_FOUND_RESULT_FOUND");
768             priv->peer_agent = peer_agent;
769             g_idle_add(_create_service_connection, priv);
770         }
771         else
772         {
773             sap_peer_agent_destroy(peer_agent);
774         }
775         break;
776
777     case SAP_PEER_AGENT_FOUND_RESULT_SERVICE_NOT_FOUND:
778         LOGW("SAP_PEER_AGENT_FOUND_RESULT_SERVICE_NOT_FOUND");
779         break;
780
781     case SAP_PEER_AGENT_FOUND_RESULT_TIMEDOUT:
782         LOGW("SAP_PEER_AGENT_FOUND_RESULT_TIMEDOUT");
783         break;
784
785     case SAP_PEER_AGENT_FOUND_RESULT_INTERNAL_ERROR:
786         LOGW("SAP_PEER_AGENT_FOUND_RESULT_INTERNAL_ERROR");
787         break;
788
789     default:
790         break;
791     }
792 }
793
794 static gboolean
795 _find_peer_agent(gpointer user_data)
796 {
797     sap_info_s *priv = (sap_info_s *)user_data;
798     sap_agent_find_peer_agent(priv->agent, _on_peer_agent_updated, priv);
799
800     return FALSE;
801 }
802
803 static void on_agent_initialized(sap_agent_h agent,
804                                  sap_agent_initialized_result_e result,
805                                  void *user_data)
806 {
807     switch (result) {
808         case SAP_AGENT_INITIALIZED_RESULT_SUCCESS:
809             LOGD("agent is initialized");
810
811             priv_data.agent = agent;
812
813             sap_file_transfer_set_incoming_file_cb(agent, _on_receive_file_cb, NULL);
814             sap_agent_set_service_connection_requested_cb(agent, on_conn_req, NULL);
815
816             break;
817         case SAP_AGENT_INITIALIZED_RESULT_DUPLICATED:
818             LOGE("duplicate registration");
819             break;
820         case SAP_AGENT_INITIALIZED_RESULT_INVALID_ARGUMENTS:
821             LOGE("invalid arguments");
822             break;
823         case SAP_AGENT_INITIALIZED_RESULT_INTERNAL_ERROR:
824             LOGE("internal sap error");
825             break;
826         default:
827             LOGE("unknown status (%d)", result);
828             break;
829     }
830 }
831
832 static void on_agent_deinitialized(sap_agent_h agent,
833                                    sap_agent_deinitialized_result_e result,
834                                    void *user_data)
835 {
836     LOGD("result of deinitialize : %d", result);
837 }
838
839 static void _on_device_status_changed(sap_device_status_e status,
840                                       sap_transport_type_e transport_type,
841                                       void *user_data)
842 {
843     LOGD("%s, status :%d", __func__, status);
844
845     switch (transport_type) {
846         case SAP_TRANSPORT_TYPE_BT:
847             LOGD("transport_type (%d): bt", transport_type);
848             break;
849         case SAP_TRANSPORT_TYPE_BLE:
850             LOGD("transport_type (%d): ble", transport_type);
851             break;
852         case SAP_TRANSPORT_TYPE_TCP:
853             LOGD("transport_type (%d): tcp/ip", transport_type);
854             break;
855         case SAP_TRANSPORT_TYPE_USB:
856             LOGD("transport_type (%d): usb", transport_type);
857             break;
858         case SAP_TRANSPORT_TYPE_MOBILE:
859             LOGD("transport_type (%d): mobile", transport_type);
860             break;
861         default:
862             LOGE("unknown transport_type (%d)", transport_type);
863             break;
864     }
865
866     switch (status) {
867         case SAP_DEVICE_STATUS_DETACHED:
868             LOGD("device is not connected.");
869             break;
870         case SAP_DEVICE_STATUS_ATTACHED:
871             LOGD("Attached calling find peer now");
872             g_idle_add(_find_peer_agent, &priv_data);
873             break;
874         default:
875             LOGE("unknown status (%d)", status);
876             break;
877     }
878 }
879
880 gboolean agent_initialize()
881 {
882     int result = 0;
883
884     do {
885         result = sap_agent_initialize(priv_data.agent, ACCESSORY_SERVICE_PROFILE_ID, SAP_AGENT_ROLE_CONSUMER,
886                 on_agent_initialized, NULL);
887
888         LOGD("SAP >>> getRegisteredServiceAgent() >>> %d", result);
889     } while (result != SAP_RESULT_SUCCESS);
890
891     return TRUE;
892 }
893
894 gboolean initialize_sap(void)
895 {
896     sap_agent_h agent = NULL;
897
898     sap_agent_create(&agent);
899
900     priv_data.agent = agent;
901
902     agent_initialize();
903
904     sap_set_device_status_changed_cb(_on_device_status_changed, NULL);
905
906     return TRUE;
907 }
908
909 void deinitialize_sap(void)
910 {
911     if (priv_data.agent) {
912         int ret = sap_agent_deinitialize(priv_data.agent, on_agent_deinitialized, NULL);
913         switch (ret) {
914             case SAP_RESULT_FAILURE:
915                 LOGW("Failed to deinitialize");
916                 break;
917             case SAP_RESULT_SUCCESS:
918                 LOGD("Succeed to deinitialize");
919                 break;
920             case SAP_RESULT_PERMISSION_DENIED:
921                 LOGW("permission denied: deinitialize ");
922                 break;
923             default:
924                 LOGD("deinitialize : %d", ret);
925                 break;
926         }
927
928         sap_agent_destroy(priv_data.agent);
929         priv_data.agent = NULL;
930     }
931 }