added maximum input length for sscanf
[platform/core/convergence/service-adaptor.git] / server / src / dbus / dbus-service-adaptor.c
1 /*
2 * Copyright (c) 2011 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 <stdlib.h>
19 #include <string.h>
20 #include <glib.h>
21 #include <gio/gio.h>
22
23 #include "service-adaptor.h"
24 #include "service-adaptor-type.h"
25 #include "service-adaptor-log.h"
26 #include "dbus-service-adaptor.h"
27 #include "dbus-server.h"
28 #include "dbus-server-type.h"
29 #include "dbus-util.h"
30
31 #include "dbus-auth-adaptor.h"
32 #include "dbus-storage-adaptor.h"
33 #include "dbus-contact-adaptor.h"
34 #include "dbus-message-adaptor.h"
35 #include "dbus-shop-adaptor.h"
36
37 #include "util/ping_manager.h"
38
39 #define RET_MSG_LEN     2048
40
41 //LCOV_EXCL_START
42 void service_adaptor_method_call(GDBusConnection *connection,
43                                                 const gchar *sender,
44                                                 const gchar *object_path,
45                                                 const gchar *interface_name,
46                                                 const gchar *method_name,
47                                                 GVariant *parameters,
48                                                 GDBusMethodInvocation *invocation,
49                                                 gpointer user_data)
50 {
51 FUNC_START();
52         service_adaptor_internal_error_code_e ret_code = SERVICE_ADAPTOR_INTERNAL_ERROR_NONE;
53         char ret_msg[RET_MSG_LEN] = {0,};
54
55         if ((0 == g_strcmp0(method_name, PRIVATE_DBUS_CONNECT_SERVICE_ADAPTOR_METHOD)) ||
56                 (0 == g_strcmp0(method_name, DBUS_CONNECT_SERVICE_ADAPTOR_METHOD))) {
57 #if !GLIB_CHECK_VERSION(2, 32, 0)
58                 g_thread_init(NULL);
59 #endif
60 #if !GLIB_CHECK_VERSION(2, 35, 0)
61                 g_type_init();
62 #endif
63                 int waiting_cnt = 10;
64                 service_adaptor_h service_adaptor = service_adaptor_get_handle();
65
66 FUNC_STEP();
67                 while ((NULL == service_adaptor) && (0 < waiting_cnt)) {
68                         service_adaptor = service_adaptor_get_handle();
69                         waiting_cnt--;
70                         service_adaptor_debug("Retry service_adaptor_get_handle()");
71                         sleep(1);
72                 }
73
74 FUNC_STEP();
75                 if (NULL == service_adaptor) {
76                         service_adaptor_error("Cannot get handle of service adaptor");
77                         ret_code = SERVICE_ADAPTOR_INTERNAL_ERROR_INIT;
78                         strncpy(ret_msg, "Cannot get handle of service adaptor", (RET_MSG_LEN - 1));
79
80                         g_dbus_method_invocation_return_value(invocation, g_variant_new("(ts)", (uint64_t) ret_code, ret_msg));
81                         return;
82                 }
83
84 FUNC_STEP();
85                 gint64 timeout = g_get_monotonic_time() + 10 * G_TIME_SPAN_SECOND;
86                 g_mutex_lock(&service_adaptor->service_adaptor_mutex);
87
88 FUNC_STEP();
89                 while (!service_adaptor->started) {
90                         if (!g_cond_wait_until(&service_adaptor->service_adaptor_cond, &service_adaptor->service_adaptor_mutex, timeout)) {
91                                 ret_code = SERVICE_ADAPTOR_INTERNAL_ERROR_INIT;
92                                 strncpy(ret_msg, "Timeout", (RET_MSG_LEN - 1));
93                                 service_adaptor_warning("Service adaptor Initalize timed out");
94
95                                 g_dbus_method_invocation_return_value(invocation, g_variant_new("(ts)", (uint64_t) ret_code, ret_msg));
96                                 g_mutex_unlock(&service_adaptor->service_adaptor_mutex);
97
98                                 return;
99                         }
100                 }
101
102                 GVariant *in_parameters = g_variant_get_child_value(parameters, 0);
103                 char *client_profile = NULL;
104                 g_variant_get(in_parameters, private_service_adaptor_essential_s_type, &client_profile);
105                 service_adaptor_info("[DM] client profile <%s>", client_profile);
106                 char client_name[1024] = {0, };
107                 int client_pid = 0;
108                 int sr = sscanf(client_profile, "%1000s %10d", client_name, &client_pid);
109                 if (sr == 2) {
110                                 service_adaptor_info("[DM] client<%s> pid<%d>", client_name, client_pid);
111                                 #ifndef DETAILED_PEER
112                                 ping_manager_peer_connected(client_pid);
113                                 #else
114                                 peer_info_s info;
115                                 info.pid = client_pid;
116                                 info.name = strdup(client_name);
117                                 ping_manager_peer_connected(&info);
118                                 free(info.name);
119                                 info.name = NULL;
120                                 #endif
121                 }
122
123                 g_mutex_unlock(&service_adaptor->service_adaptor_mutex);
124
125                 service_adaptor_info("Client Connected Successful");
126                 g_dbus_method_invocation_return_value(invocation, g_variant_new("(ts)", (uint64_t) ret_code, ret_msg));
127 FUNC_END();
128         } else if (0 == g_strcmp0(method_name, DBUS_DISCONNECT_SERVICE_ADAPTOR_METHOD)) {
129                 GVariant *in_parameters = g_variant_get_child_value(parameters, 0);
130                 char *client_profile = NULL;
131                 g_variant_get(in_parameters, private_service_adaptor_essential_s_type, &client_profile);
132                 service_adaptor_info("[DM] client profile <%s>", client_profile);
133                 char client_name[1024] = {0, };
134                 int client_pid = 0;
135                 int sr = sscanf(client_profile, "%1000s %10d", client_name, &client_pid);
136                 if (sr == 2) {
137                                 service_adaptor_info("[DM][dis] client<%s> pid<%d>", client_name, client_pid);
138                                 #ifndef DETAILED_PEER
139                                 ping_manager_peer_disconnected(client_pid);
140                                 #else
141                                 peer_info_s info;
142                                 info.pid = client_pid;
143                                 info.name = strdup(client_name);
144                                 ping_manager_peer_disconnected(&info);
145                                 free(info.name);
146                                 info.name = NULL;
147                                 #endif
148                 }
149
150                 service_adaptor_info("Client Disconnected Successful");
151                 g_dbus_method_invocation_return_value(invocation, g_variant_new("(ts)", (uint64_t) ret_code, ret_msg));
152         } else if (0 == g_strcmp0(method_name, PRIVATE_DBUS_EXTERNAL_REQ_METHOD)) {
153                 service_adaptor_debug("[START] External request method");
154                 GVariant *in_parameters = g_variant_get_child_value(parameters, 0);
155                 GVariant *req_struct[private_service_adaptor_external_req_s_type_length];
156
157                 for (size_t j = 0; j < private_service_adaptor_external_req_s_type_length; j++) {
158                         req_struct[j] = g_variant_get_child_value(in_parameters, j);
159                 }
160                 int idx = 0;
161                 char *service_name      = ipc_g_variant_dup_string(req_struct[idx++]);
162                 int service_flag        = g_variant_get_int32(req_struct[idx++]);
163                 char *api_uri           = ipc_g_variant_dup_string(req_struct[idx++]);
164
165                 service_adaptor_debug("service_name : %s / %d", service_name, service_flag);
166                 service_adaptor_debug("api_uri : %s", api_uri);
167                 int raw_data_len = g_variant_n_children(req_struct[idx]);
168                 unsigned char *raw_data = (unsigned char *) calloc((raw_data_len + 1), sizeof(unsigned char));
169
170                 if (NULL != raw_data) {
171                         for (int k = 0; k < raw_data_len; k++) {
172                                 g_variant_get_child(req_struct[idx], k, "(y)", &(raw_data[k]));
173                         }
174                 }
175
176                 for (size_t j = 0; j < private_service_adaptor_external_req_s_type_length; j++) {
177                         g_variant_unref(req_struct[j]);
178                 }
179                 service_adaptor_debug_func("req_data_len (%d)", raw_data_len);
180                 service_adaptor_debug_func("req_data (%s)", raw_data);
181
182                 int ret = 0;
183                 unsigned char *res_data = NULL;
184                 int res_data_len = 0;
185
186                 /* Call API */
187                 switch (service_flag) {
188                 case SERVICE_ADAPTOR_PROTOCOL_SERVICE_TYPE_AUTH:
189                         service_adaptor_debug("Call auth_external_method_call");
190                         auth_external_method_call(service_name, api_uri, raw_data, raw_data_len,
191                                         &res_data, &res_data_len, &ret, ret_msg);
192                         break;
193                 case SERVICE_ADAPTOR_PROTOCOL_SERVICE_TYPE_STORAGE:
194                         break;
195                 case SERVICE_ADAPTOR_PROTOCOL_SERVICE_TYPE_CONTACT:
196                         break;
197                 case SERVICE_ADAPTOR_PROTOCOL_SERVICE_TYPE_MESSAGE:
198                         break;
199                 case SERVICE_ADAPTOR_PROTOCOL_SERVICE_TYPE_SHOP:
200                         break;
201                 case SERVICE_ADAPTOR_PROTOCOL_SERVICE_TYPE_PUSH:
202                         break;
203                 default:
204                         break;
205                 }
206
207                 service_adaptor_debug_func("res_data_len (%d)", res_data_len);
208                 service_adaptor_debug_func("res_data (%s)", res_data);
209                 GVariantBuilder *builder_raw = g_variant_builder_new(G_VARIANT_TYPE(service_adaptor_raw_data_s_type));
210                 if (NULL != res_data) {
211                         for (int r = 0; r < res_data_len; r++) {
212                                 g_variant_builder_add(builder_raw, "(y)", (guchar)res_data[r]);
213                         }
214                 }
215
216                 g_dbus_method_invocation_return_value(invocation,
217                                 g_variant_new(MAKE_RETURN_TYPE(service_adaptor_raw_data_s_type), builder_raw, (uint64_t) ret, ret_msg));
218                 g_variant_builder_unref(builder_raw);
219                 service_adaptor_debug("[End] External request method");
220
221                 free(service_name);
222                 free(api_uri);
223                 free(raw_data);
224                 free(res_data);
225         }
226 }
227
228 service_adaptor_internal_error_code_e dbus_push_data_callback(uint32_t service_id,
229                                                 push_adaptor_notification_data_h app_data,
230                                                 service_adaptor_internal_error_h error_code,
231                                                 void *server_data)
232 {
233 FUNC_START();
234         GError* error = NULL;
235         GDBusConnection *dbus_connection = dbus_get_connection();
236
237         if (NULL != dbus_connection) {
238
239                 GVariant *response = g_variant_new(MAKE_RETURN_TYPE(private_service_adaptor_push_data_s_type), service_id, __safe_add_string(app_data->data), __safe_add_string(app_data->msg), app_data->time_stamp, (uint64_t) error_code->code, __safe_add_string(error_code->msg));
240
241                 g_dbus_connection_emit_signal(dbus_connection,
242                                 NULL,
243                                 SERVICE_ADAPTOR_OBJECT_PATH,
244                                 SERVICE_ADAPTOR_INTERFACE,
245                                 PRIVATE_DBUS_PUSH_DATA_SIGNAL,
246                                 response,
247                                 &error);
248
249                 if (NULL != error) {
250                         service_adaptor_debug("Unable to send msg: %s", error->message);
251                         return SERVICE_ADAPTOR_INTERNAL_ERROR_DBUS;
252                 }
253         }
254
255 FUNC_END();
256         return SERVICE_ADAPTOR_INTERNAL_ERROR_NONE;
257 }
258
259 service_adaptor_internal_error_code_e dbus_service_adaptor_signal_callback(service_adaptor_internal_signal_code_e signal_code,
260                                                 const char *signal_msg)
261 {
262 FUNC_START();
263         GError* error = NULL;
264         GDBusConnection *dbus_connection = dbus_get_connection();
265
266         if (NULL != dbus_connection) {
267                 GVariant *response = g_variant_new("(ts)", (uint64_t) signal_code, (signal_msg ? signal_msg : ""));
268
269                 g_dbus_connection_emit_signal(dbus_connection,
270                                 NULL,
271                                 SERVICE_ADAPTOR_OBJECT_PATH,
272                                 SERVICE_ADAPTOR_INTERFACE,
273                                 PRIVATE_DBUS_SERVICE_ADAPTOR_SIGNAL,
274                                 response,
275                                 &error);
276
277                 if (NULL != error) {
278                         service_adaptor_debug("Unable to send msg: %s", error->message);
279                         return SERVICE_ADAPTOR_INTERNAL_ERROR_DBUS;
280                 }
281         }
282
283 FUNC_END();
284         return SERVICE_ADAPTOR_INTERNAL_ERROR_NONE;
285 }
286 //LCOV_EXCL_STOP
287