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