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