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