2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 #include <service_app.h>
21 #include <app_common.h>
23 #include <sap_file_transfer.h>
24 #include <sticker_provider.h>
28 #include <linux/limits.h>
29 #include <sys/types.h>
32 #include <json-glib/json-glib.h>
36 #include "sticker_info.h"
38 #define ACCESSORY_SERVICE_PROFILE_ID "/sample/filetransfersender"
39 #define ACCESSORY_SERVICE_CHANNEL_ID 107
41 #define STICKER_SYNC_START_REQ "sticker-sync-start-req"
42 #define STICKER_SYNC_START_RSP "sticker-sync-start-rsp"
43 #define STICKER_SEND_START_REQ "sticker-send-start-req"
44 #define STICKER_SEND_START_RSP "sticker-send-start-rsp"
45 #define STICKER_SEND_FACE_DATA "sticker-send-face-data"
46 #define STICKER_SEND_STOP_REQ "sticker-send-stop-req"
47 #define STICKER_SEND_STOP_RSP "sticker-send-stop-rsp"
54 sap_file_transaction_h file_socket;
57 static void _reset_sticker_data();
68 _reset_sticker_data();
72 static struct priv priv_data = { 0 };
73 static struct sticker_info sticker_data;
75 gboolean file_on_progress = 0;
76 static string incoming_file_name;
78 static int rec_file_cnt = 0;
80 static gboolean _send_json_data(JsonObject *obj)
82 JsonGenerator *j_generator = NULL;
83 JsonNode *j_node = NULL;
88 j_generator = json_generator_new();
89 if (j_generator == NULL) {
90 LOGE("Unable to json_generator_new");
94 j_node = json_node_new(JSON_NODE_OBJECT);
96 LOGE("Unable to json_node_new");
100 json_node_set_object(j_node, obj);
101 json_generator_set_root(j_generator, j_node);
103 data = json_generator_to_data(j_generator, &size);
105 LOGE("Unable to json_generator_to_data");
109 if (priv_data.socket) {
110 LOGD("Send JSON data : %s", data);
111 result = sap_socket_send_data(priv_data.socket, ACCESSORY_SERVICE_CHANNEL_ID, strlen(data), (void *)data);
119 json_node_free(j_node);
122 g_object_unref(j_generator);
124 return result ? FALSE : TRUE;
127 static void _on_send_completed(sap_file_transaction_h file_transaction,
128 sap_ft_transfer_e result,
129 const char *file_path,
132 if (priv_data.file_socket) {
133 sap_file_transfer_destroy(file_transaction);
134 priv_data.file_socket = NULL;
137 if (result == SAP_FT_TRANSFER_SUCCESS) {
138 LOGI("Transfer Completed");
140 if (chmod(sticker_data.file_path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
141 LOGE("Failed to change permission : %s. error : %s", sticker_data.file_path.c_str(), strerror(errno));
144 LOGI("Succeed to change permission : %s", sticker_data.file_path.c_str());
145 if (create_sticker_provider_handle() == STICKER_ERROR_NONE) {
146 insert_sticker_data(sticker_data.file_path.c_str(), sticker_data.keyword.c_str(), sticker_data.group.c_str(), sticker_data.description.c_str());
147 destroy_sticker_provider_handle();
149 if (unlink(sticker_data.file_path.c_str()) == -1)
150 LOGE("Failed to remove sticker file");
157 case (SAP_FT_TRANSFER_FAIL_CHANNEL_IO): {
158 LOGW("Channel IO Error.");
162 case (SAP_FT_TRANSFER_FAIL_FILE_IO): {
163 LOGW("File IO Error.");
167 case (SAP_FT_TRANSFER_FAIL_CMD_DROPPED):
169 LOGW("Transfer dropped.");
173 case (SAP_FT_TRANSFER_FAIL_PEER_UNRESPONSIVE):
175 LOGW("Peer Un Responsive.");
179 case (SAP_FT_TRANSFER_FAIL_PEER_CONN_LOST):
181 LOGW("Connection Lost.");
185 case (SAP_FT_TRANSFER_FAIL_PEER_CANCELLED):
187 LOGW("Peer Cancelled.");
191 case (SAP_FT_TRANSFER_FAIL_SPACE_NOT_AVAILABLE):
198 LOGW("Unknown Error");
203 file_on_progress = 0;
206 static void _on_sending_file_in_progress(sap_file_transaction_h file_transaction,
207 unsigned short int percentage_progress,
210 LOGI("# progress %d", percentage_progress);
213 static void __set_file_transfer_cb(sap_file_transaction_h file_socket)
215 LOGI("# set callbacks");
216 sap_file_transfer_set_progress_cb(file_socket, _on_sending_file_in_progress, NULL);
218 sap_file_transfer_set_done_cb(file_socket, _on_send_completed, NULL);
224 char file_path[PATH_MAX];
225 char *data_path = NULL;
227 data_path = app_get_shared_data_path();
228 LOGI("Path : %s", data_path);
229 sprintf(file_path, "%s/%s", data_path, incoming_file_name.c_str());
230 LOGI("Receive filepath : %s", file_path);
231 sticker_data.file_path = string(file_path);
234 ret = sap_file_transfer_receive(priv_data.file_socket, file_path);
236 case SAP_RESULT_PERMISSION_DENIED:
237 LOGW("permission denied");
239 case SAP_RESULT_FAILURE:
242 case SAP_RESULT_SUCCESS:
247 file_on_progress = 1;
250 void sap_file_transfer_get_receive_filepath(char **filepath)
252 *filepath = strdup(sticker_data.file_path.c_str());
255 void request_sticker_data(const char *mode, const char *category, const char *type)
257 JsonObject *j_object = json_object_new();
258 if (j_object == NULL) {
259 LOGE("json object create error");
263 json_object_set_string_member(j_object, "msgId", STICKER_SYNC_START_REQ);
264 json_object_set_int_member(j_object, "tID", ++t_id);
265 json_object_set_string_member(j_object, "mode", mode);
266 json_object_set_string_member(j_object, "category", category);
267 json_object_set_string_member(j_object, "type", type);
269 if (_send_json_data(j_object) == FALSE)
270 LOGE("Failed to request sticker data");
272 json_object_unref(j_object);
277 int ret = sap_file_transfer_reject(priv_data.file_socket);
278 LOGI("ret : %d", ret);
280 file_on_progress = 0;
283 static void _on_receive_file_cb(sap_peer_agent_h peer_agent_h,
284 sap_file_transaction_h socket,
285 const char *file_path,
288 file_on_progress = 1;
289 priv_data.file_socket = socket;
290 LOGI("# incoming file request.");
291 __set_file_transfer_cb(priv_data.file_socket);
293 incoming_file_name = file_path;
294 std::size_t found = incoming_file_name.find_last_of("/");
295 incoming_file_name = incoming_file_name.substr(found+1);
297 LOGI("# file path : %s, incoming file name : %s", file_path, incoming_file_name.c_str());
302 void conn_terminated(sap_peer_agent_h peer_agent,
304 sap_service_connection_terminated_reason_e result,
309 case SAP_CONNECTION_TERMINATED_REASON_PEER_DISCONNECTED:
310 LOGW("Peer Disconnected");
312 case SAP_CONNECTION_TERMINATED_REASON_DEVICE_DETACHED:
313 LOGW("Disconnected Device Detached");
315 case SAP_CONNECTION_TERMINATED_REASON_UNKNOWN:
316 LOGW("Disconnected Unknown Reason");
319 LOGW("connection terminated. reason : %d", result);
326 static void _reset_sticker_data()
328 sticker_data.file_path.clear();
329 sticker_data.group.clear();
330 sticker_data.keyword.clear();
331 sticker_data.disp_type.clear();
332 sticker_data.description.clear();
336 on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned int payload_length, void *buffer,
337 void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
339 LOGI("received data: %s, len:%d", (char *)buffer, payload_length);
341 JsonParser *parser = json_parser_new();
342 GError *err_msg = NULL;
343 JsonNode *root = NULL;
344 JsonObject *root_obj = NULL;
346 const char *json_msgid = NULL;
348 json_parser_load_from_data(parser, (char *)buffer, -1, &err_msg);
350 LOGE("failed to load json file. error message: %s", err_msg->message);
354 root = json_parser_get_root(parser);
356 LOGE("failed to get root");
360 root_obj = json_node_get_object(root);
361 if (root_obj == NULL) {
362 LOGE("failed to get object");
366 json_msgid = json_object_get_string_member(root_obj, "msgId");
367 msg_id = string(json_msgid ? json_msgid : "");
368 if (msg_id == STICKER_SYNC_START_RSP) {
369 LOGD("msg : %s", msg_id.c_str());
370 const char *json_result = json_object_get_string_member(root_obj, "result");
371 string result = string(json_result ? json_result : "");
372 int result_code = json_object_get_int_member(root_obj, "resultCode");
373 LOGD("result : %s, resultCode : %d", result.c_str(), result_code);
374 } else if (msg_id == STICKER_SEND_START_REQ) {
375 LOGD("msg : %s", msg_id.c_str());
377 t_id = json_object_get_int_member(root_obj, "tID");
378 JsonArray *file_list = json_object_get_array_member(root_obj, "list");
380 int arr_len = json_array_get_length(file_list);
381 for (int i = 0; i < arr_len; i++) {
382 JsonObject *file_obj = json_array_get_object_element(file_list, i);
383 int file_len = json_object_get_int_member(file_obj, "size");
384 const char *json_filename = json_object_get_string_member(file_obj, "fileName");
385 string file_name = string(json_filename ? json_filename : "");
388 LOGD("fileName : %s, len : %d", file_name.c_str(), file_len);
391 LOGD("fileName : %s, len : %d", file_name.c_str(), file_len);
396 JsonObject *j_object = json_object_new();
397 if (j_object == NULL) {
398 LOGE("Unable to json_object_new");
402 json_object_set_string_member(j_object, "msgId", STICKER_SEND_START_RSP);
403 json_object_set_int_member(j_object, "tID", t_id);
404 json_object_set_string_member(j_object, "result", "success");
406 if (_send_json_data(j_object) == FALSE)
407 LOGE("Failed to send message");
409 json_object_unref(j_object);
410 } else if (msg_id == STICKER_SEND_FACE_DATA) {
411 LOGD("msg : %s", msg_id.c_str());
412 _reset_sticker_data();
414 const char *type_data = json_object_get_string_member(root_obj, "type");
416 sticker_data.disp_type = string(type_data);
418 const char *category = json_object_get_string_member(root_obj, "category");
420 sticker_data.group = string(category);
421 sticker_data.keyword = string(category);
423 } else if (msg_id == STICKER_SEND_STOP_REQ) {
424 LOGD("msg : %s", msg_id.c_str());
425 const char *json_reason = json_object_get_string_member(root_obj, "reason");
426 string reason = string(json_reason ? json_reason : "");
427 int file_len = json_object_get_int_member(root_obj, "count");
429 JsonObject *j_object = json_object_new();
430 if (j_object == NULL) {
431 LOGE("Unable to json_object_new");
435 json_object_set_string_member(j_object, "msgId", STICKER_SEND_STOP_RSP);
436 json_object_set_int_member(j_object, "tID", t_id);
438 if (reason == "complete" && rec_file_cnt != file_len)
439 json_object_set_string_member(j_object, "result", "failure");
441 json_object_set_string_member(j_object, "result", "success");
443 if (_send_json_data(j_object) == FALSE)
444 LOGE("Failed to send message");
446 json_object_unref(j_object);
448 LOGW("unknown msg id : %s", msg_id.c_str());
452 g_error_free(err_msg);
455 g_object_unref(parser);
458 static void on_conn_req(sap_peer_agent_h peer_agent,
460 sap_service_connection_result_e result,
463 if (result == SAP_CONNECTION_SUCCESS) {
464 priv_data.socket = socket;
465 sap_peer_agent_accept_service_connection(peer_agent);
466 sap_peer_agent_set_service_connection_terminated_cb(peer_agent, conn_terminated, NULL);
467 sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
471 static void on_agent_initialized(sap_agent_h agent,
472 sap_agent_initialized_result_e result,
476 case SAP_AGENT_INITIALIZED_RESULT_SUCCESS:
477 LOGD("agent is initialized");
479 priv_data.agent = agent;
481 sap_file_transfer_set_incoming_file_cb(agent, _on_receive_file_cb, NULL);
482 sap_agent_set_service_connection_requested_cb(agent, on_conn_req, NULL);
485 case SAP_AGENT_INITIALIZED_RESULT_DUPLICATED:
486 LOGE("duplicate registration");
488 case SAP_AGENT_INITIALIZED_RESULT_INVALID_ARGUMENTS:
489 LOGE("invalid arguments");
491 case SAP_AGENT_INITIALIZED_RESULT_INTERNAL_ERROR:
492 LOGE("internal sap error");
495 LOGE("unknown status (%d)", result);
500 static void on_agent_deinitialized(sap_agent_h agent,
501 sap_agent_deinitialized_result_e result,
504 LOGD("result of deinitialize : %d", result);
507 static void _on_device_status_changed(sap_device_status_e status,
508 sap_transport_type_e transport_type,
511 LOGD("%s, status :%d", __func__, status);
513 switch (transport_type) {
514 case SAP_TRANSPORT_TYPE_BT:
515 LOGD("transport_type (%d): bt", transport_type);
517 case SAP_TRANSPORT_TYPE_BLE:
518 LOGD("transport_type (%d): ble", transport_type);
520 case SAP_TRANSPORT_TYPE_TCP:
521 LOGD("transport_type (%d): tcp/ip", transport_type);
523 case SAP_TRANSPORT_TYPE_USB:
524 LOGD("transport_type (%d): usb", transport_type);
526 case SAP_TRANSPORT_TYPE_MOBILE:
527 LOGD("transport_type (%d): mobile", transport_type);
530 LOGE("unknown transport_type (%d)", transport_type);
535 case SAP_DEVICE_STATUS_DETACHED:
536 LOGD("device is not connected.");
538 case SAP_DEVICE_STATUS_ATTACHED:
539 LOGD("Attached calling find peer now");
542 LOGE("unknown status (%d)", status);
547 gboolean agent_initialize()
552 result = sap_agent_initialize(priv_data.agent, ACCESSORY_SERVICE_PROFILE_ID, SAP_AGENT_ROLE_CONSUMER,
553 on_agent_initialized, NULL);
555 LOGD("SAP >>> getRegisteredServiceAgent() >>> %d", result);
556 } while (result != SAP_RESULT_SUCCESS);
561 gboolean initialize_sap(void)
563 sap_agent_h agent = NULL;
565 sap_agent_create(&agent);
567 priv_data.agent = agent;
571 sap_set_device_status_changed_cb(_on_device_status_changed, NULL);
576 void deinitialize_sap(void)
578 if (priv_data.agent) {
579 int ret = sap_agent_deinitialize(priv_data.agent, on_agent_deinitialized, NULL);
581 case SAP_RESULT_FAILURE:
582 LOGW("Failed to deinitialize");
584 case SAP_RESULT_SUCCESS:
585 LOGD("Succeed to deinitialize");
587 case SAP_RESULT_PERMISSION_DENIED:
588 LOGW("permission denied: deinitialize ");
591 LOGD("deinitialize : %d", ret);
595 sap_agent_destroy(priv_data.agent);
596 priv_data.agent = NULL;