Fixed the crash issue when the file is received
[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 <app_common.h>
21 #include <sap.h>
22 #include <sap_file_transfer.h>
23 #include <sticker_provider.h>
24 #include <string.h>
25 #include <string>
26 #include <unistd.h>
27 #include <linux/limits.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <pwd.h>
31
32 #define ACCESSORY_SERVICE_PROFILE_ID "/sample/filetransfersender"
33
34 #include "sticker_info.h"
35
36 using namespace std;
37
38 struct priv {
39         sap_agent_h agent;
40         sap_file_transaction_h socket;
41 };
42
43 static struct priv priv_data = { 0 };
44
45 gboolean file_on_progress = 0;
46 static string incoming_file_name;
47 static string recv_filepath;
48
49 static void _on_send_completed(sap_file_transaction_h file_transaction,
50                                sap_ft_transfer_e result,
51                                const char *file_path,
52                                void *user_data)
53 {
54         char error_message[100];
55
56         dlog_print(DLOG_INFO, TAG, "# transfer completed");
57
58         if (priv_data.socket) {
59                 sap_file_transfer_destroy(file_transaction);
60                 priv_data.socket = NULL;
61         }
62
63         if (result == SAP_FT_TRANSFER_SUCCESS) {
64                 sprintf(error_message, "Transfer Completed");
65                 dlog_print(DLOG_INFO, TAG, "Transfer Completed");
66
67                 if (chmod(recv_filepath.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
68                         dlog_print(DLOG_ERROR, TAG, "Failed to change permission : %s. error : %s", recv_filepath.c_str(), strerror(errno));
69                 }
70                 else {
71                         dlog_print(DLOG_INFO, TAG, "Succeed to change permission : %s", recv_filepath.c_str());
72                         create_sticker_provider_handle();
73                         insert_sticker_data(recv_filepath.c_str(), "keyword", "group", "test icon");
74                         destroy_sticker_provider_handle();
75                 }
76         } else {
77                 switch (result) {
78                 case (SAP_FT_TRANSFER_FAIL_CHANNEL_IO): {
79                         sprintf(error_message, "Channel IO Error.");
80                         dlog_print(DLOG_WARN, TAG, "Channel IO Error.");
81                         break;
82                 }
83
84                 case (SAP_FT_TRANSFER_FAIL_FILE_IO): {
85                         sprintf(error_message, "File IO Error.");
86                         dlog_print(DLOG_WARN, TAG, "File IO Error.");
87                         break;
88                 }
89
90                 case (SAP_FT_TRANSFER_FAIL_CMD_DROPPED): {
91                         sprintf(error_message, "Transfer dropped.");
92                         dlog_print(DLOG_WARN, TAG, "Transfer dropped.");
93                         break;
94                 }
95
96                 case (SAP_FT_TRANSFER_FAIL_PEER_UNRESPONSIVE): {
97                         sprintf(error_message, "Peer Un Responsive.");
98                         dlog_print(DLOG_WARN, TAG, "Peer Un Responsive.");
99                         break;
100                 }
101
102                 case (SAP_FT_TRANSFER_FAIL_PEER_CONN_LOST): {
103                         sprintf(error_message, "Connection Lost.");
104                         dlog_print(DLOG_WARN, TAG, "Connection Lost.");
105                         break;
106                 }
107
108                 case (SAP_FT_TRANSFER_FAIL_PEER_CANCELLED): {
109                         sprintf(error_message, "Peer Cancelled.");
110                         dlog_print(DLOG_WARN, TAG, "Peer Cancelled.");
111                         break;
112                 }
113
114                 case (SAP_FT_TRANSFER_FAIL_SPACE_NOT_AVAILABLE): {
115                         sprintf(error_message, "No Space.");
116                         dlog_print(DLOG_WARN, TAG, "No Space.");
117                         break;
118                 }
119
120                 default:
121                         sprintf(error_message, "Unknown Error");
122                         dlog_print(DLOG_WARN, TAG, "Unknown Error");
123                 }
124         }
125
126         file_on_progress = 0;
127 }
128
129 static void _on_sending_file_in_progress(sap_file_transaction_h file_transaction,
130                                          unsigned short int percentage_progress,
131                                          void *user_data)
132 {
133         dlog_print(DLOG_INFO, TAG, "# progress %d", percentage_progress);
134 }
135
136 static void __set_file_transfer_cb(sap_file_transaction_h file_socket)
137 {
138         dlog_print(DLOG_INFO, TAG, "# set callbacks");
139         sap_file_transfer_set_progress_cb(file_socket, _on_sending_file_in_progress, NULL);
140
141         sap_file_transfer_set_done_cb(file_socket, _on_send_completed, NULL);
142 }
143
144 void accept_file()
145 {
146         int ret;
147         char file_path[PATH_MAX];
148         char *data_path = NULL;
149
150         data_path = app_get_shared_data_path();
151         dlog_print(DLOG_INFO, TAG, "Path : %s", data_path);
152         sprintf(file_path, "%s/%s", data_path, incoming_file_name.c_str());
153         dlog_print(DLOG_INFO, TAG, "Receive filepath : %s", file_path);
154         recv_filepath = string(file_path);
155         free(data_path);
156
157         ret = sap_file_transfer_receive(priv_data.socket, file_path);
158         switch(ret) {
159         case SAP_RESULT_PERMISSION_DENIED:
160                 dlog_print(DLOG_WARN, TAG, "permission denied");
161                 break;
162         case SAP_RESULT_FAILURE:
163                 dlog_print(DLOG_WARN, TAG, "Fail");
164                 break;
165         case SAP_RESULT_SUCCESS:
166                 dlog_print(DLOG_INFO, TAG, "Success");
167                 break;
168         }
169
170         file_on_progress = 1;
171 }
172
173 void sap_file_transfer_get_receive_filepath(char **filepath)
174 {
175         *filepath = strdup(recv_filepath.c_str());
176 }
177
178 void reject_file()
179 {
180         int ret = sap_file_transfer_reject(priv_data.socket);
181         dlog_print(DLOG_INFO, TAG, "ret : %d", ret);
182
183         file_on_progress = 0;
184 }
185
186 static void _on_receive_file_cb(sap_peer_agent_h peer_agent_h,
187                           sap_file_transaction_h socket,
188                           const char *file_path,
189                           void *user_data)
190 {
191         file_on_progress = 1;
192         priv_data.socket = socket;
193         dlog_print(DLOG_INFO, TAG, "# incoming file request.");
194         __set_file_transfer_cb(priv_data.socket);
195
196         incoming_file_name = file_path;
197         std::size_t found = incoming_file_name.find_last_of("/");
198         incoming_file_name = incoming_file_name.substr(found+1);
199
200         dlog_print(DLOG_INFO, TAG, "# file path : %s, incoming file name : %s", file_path, incoming_file_name.c_str());
201
202         accept_file();
203 }
204
205 void conn_terminated(sap_peer_agent_h peer_agent,
206                      sap_socket_h socket,
207                      sap_service_connection_terminated_reason_e result,
208                      void *user_data)
209 {
210         dlog_print(DLOG_INFO, TAG, "connection terminated");
211 }
212
213 void
214 on_message_received(sap_peer_agent_h peer_agent, unsigned int payload_length, void *buffer,
215                 void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
216 {
217         char *peer_app;
218         sap_peer_agent_get_app_name(peer_agent, &peer_app);
219         dlog_print(DLOG_INFO, TAG, "received data: %s, len:%d from %s", (char *)buffer, payload_length, peer_app);
220         g_free(peer_app);
221 }
222
223 void
224 on_data_received(sap_socket_h socket, unsigned short int channel_id, unsigned int payload_length, void *buffer,
225                 void *user_data) /* message exchange on_receive callback (sap_agent_data_received_cb) */
226 {
227         dlog_print(DLOG_INFO, TAG, "received data: %s, len:%d", (char *)buffer, payload_length);
228 }
229
230 static void on_conn_req(sap_peer_agent_h peer_agent,
231                         sap_socket_h socket,
232                         sap_service_connection_result_e result,
233                         void *user_data)
234 {
235         sap_peer_agent_accept_service_connection(peer_agent);
236         sap_peer_agent_set_service_connection_terminated_cb(peer_agent, conn_terminated, NULL);
237
238         sap_socket_set_data_received_cb(socket, on_data_received, peer_agent);
239 }
240
241 static void on_agent_initialized(sap_agent_h agent,
242                                  sap_agent_initialized_result_e result,
243                                  void *user_data)
244 {
245         switch (result) {
246         case SAP_AGENT_INITIALIZED_RESULT_SUCCESS:
247
248                 dlog_print(DLOG_DEBUG, TAG, "agent is initialized");
249
250                 priv_data.agent = agent;
251
252                 sap_file_transfer_set_incoming_file_cb(agent, _on_receive_file_cb, NULL);
253                 sap_agent_set_service_connection_requested_cb(agent, on_conn_req, NULL);
254
255                 break;
256
257         case SAP_AGENT_INITIALIZED_RESULT_DUPLICATED:
258                 dlog_print(DLOG_ERROR, TAG, "duplicate registration");
259
260                 break;
261
262         case SAP_AGENT_INITIALIZED_RESULT_INVALID_ARGUMENTS:
263                 dlog_print(DLOG_ERROR, TAG, "invalid arguments");
264
265                 break;
266
267         case SAP_AGENT_INITIALIZED_RESULT_INTERNAL_ERROR:
268                 dlog_print(DLOG_ERROR, TAG, "internal sap error");
269
270                 break;
271
272         default:
273                 dlog_print(DLOG_ERROR, TAG, "unknown status (%d)", result);
274
275                 break;
276         }
277 }
278
279 static void _on_device_status_changed(sap_device_status_e status,
280                                       sap_transport_type_e transport_type,
281                                       void *user_data)
282 {
283         dlog_print(DLOG_DEBUG, TAG, "%s, status :%d", __func__, status);
284
285         switch (transport_type) {
286         case SAP_TRANSPORT_TYPE_BT:
287                 dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): bt", transport_type);
288                 break;
289
290         case SAP_TRANSPORT_TYPE_BLE:
291                 dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): ble", transport_type);
292                 break;
293
294         case SAP_TRANSPORT_TYPE_TCP:
295                 dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): tcp/ip", transport_type);
296                 break;
297
298         case SAP_TRANSPORT_TYPE_USB:
299                 dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): usb", transport_type);
300                 break;
301
302         case SAP_TRANSPORT_TYPE_MOBILE:
303                 dlog_print(DLOG_DEBUG, TAG, "transport_type (%d): mobile", transport_type);
304                 break;
305
306         default:
307                 dlog_print(DLOG_ERROR, TAG, "unknown transport_type (%d)", transport_type);
308                 break;
309         }
310
311         switch (status) {
312         case SAP_DEVICE_STATUS_DETACHED:
313                 dlog_print(DLOG_DEBUG, TAG, "device is not connected.");
314                 break;
315
316         case SAP_DEVICE_STATUS_ATTACHED:
317                 dlog_print(DLOG_DEBUG, TAG, "Attached calling find peer now");
318                 break;
319
320         default:
321                 dlog_print(DLOG_ERROR, TAG, "unknown status (%d)", status);
322                 break;
323         }
324 }
325
326 gboolean agent_initialize()
327 {
328         int result = 0;
329
330         do {
331                 result = sap_agent_initialize(priv_data.agent, ACCESSORY_SERVICE_PROFILE_ID, SAP_AGENT_ROLE_CONSUMER,
332                                               on_agent_initialized, NULL);
333
334                 dlog_print(DLOG_DEBUG, TAG, "SAP >>> getRegisteredServiceAgent() >>> %d", result);
335         } while (result != SAP_RESULT_SUCCESS);
336
337         return TRUE;
338 }
339
340 gboolean initialize_sap(void)
341 {
342         sap_agent_h agent = NULL;
343
344         sap_agent_create(&agent);
345
346         priv_data.agent = agent;
347
348         agent_initialize();
349
350         sap_set_device_status_changed_cb(_on_device_status_changed, NULL);
351
352         return TRUE;
353 }