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