release tizen_2.0 beta
[framework/telephony/tel-plugin-socket_communicator.git] / plugin / src / socket_ps.c
1 /*
2  * tel-plugin-socket-communicator
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <glib-object.h>
26
27 #include <tcore.h>
28 #include <server.h>
29 #include <plugin.h>
30 #include <hal.h>
31 #include <communicator.h>
32 #include <core_object.h>
33 #include <queue.h>
34 #include <user_request.h>
35 #include <util.h>
36 #include <co_ps.h>
37
38 #include "sipc.h"
39 #include "tapi_common.h"
40 #include "module_req.h"
41
42 static void _request_fail(UserRequest *ur, int cmd, int resp_len, void *resp)
43 {
44         tcore_user_request_send_response(ur, cmd, resp_len, resp);
45         tcore_user_request_unref(ur);
46 }
47 static char *_get_ip_string(const unsigned char str[4])
48 {
49         union tcore_ip4_type ip;
50
51         ip.i = 0;
52         ip.s[0] = str[0];
53         ip.s[1] = str[1];
54         ip.s[2] = str[2];
55         ip.s[3] = str[3];
56
57         return tcore_util_get_string_by_ip4type(ip);
58 }
59
60 gboolean scomm_service_request_ps(unsigned int ch_id, Communicator *c, TcorePlugin *plugin,
61                 tapi_service_command_e cmd, gchar *data, void **outparam)
62 {
63         int ret = 0;
64         struct _sipc_marshal_object *out_obj;
65         struct _sipc_marshal_object *in_obj;
66         gboolean result = TRUE;
67         UserRequest *ur = NULL;
68         struct tcore_user_info ui = { 0, 0, 0, NULL, 0, 0, NULL };
69
70         in_obj = sipc_util_marshal_object_deserializer(data);
71         if (!in_obj) {
72                 dbg("in_obj is NULL");
73                 result = FALSE;
74                 goto RETURN;
75         }
76
77         ur = tcore_user_request_new(c, tcore_plugin_get_description(plugin)->name);
78         if (!ur) {
79                 dbg("ur is NULL");
80                 result = FALSE;
81                 goto RETURN;
82         }
83
84         ui.channel_id = ch_id;
85         ui.client_cmd = cmd;
86         tcore_user_request_set_user_info(ur, &ui);
87
88         switch (cmd) {
89                 case TAPI_SERVICE_PS_SET_DUN_PIN_CONTROL: {
90                         struct treq_ps_set_dun_pin_control data_pincontrol;
91                         struct tresp_ps_set_dun_pin_control resp;
92                         gchar *str_signal = NULL;
93                         gboolean status;
94                         enum telephony_ps_dun_pincontrol_signal in_signal = DUN_PINCONTROL_SIGNAL_DCD;
95
96                         str_signal = sipc_util_marshal_object_get_string(in_obj, "signal");
97                         status = sipc_util_marshal_object_get_boolean(in_obj, "status");
98
99                         if (!str_signal) {
100                                 /* fail */
101                                 resp.result = TCORE_RETURN_EINVAL;
102                                 _request_fail(ur, TRESP_PS_SET_DUN_PIN_CONTROL, sizeof(struct tresp_ps_set_dun_pin_control), &resp);
103                                 result = FALSE;
104                                 break;
105                         }
106                         else {
107                                 dbg("signal = [%s]", str_signal);
108                         }
109
110                         if (!g_strcmp0(str_signal, "dcd")) {
111                                 in_signal = DUN_PINCONTROL_SIGNAL_DCD;
112                         }
113                         else if (!g_strcmp0(str_signal, "dtr")) {
114                                 in_signal = DUN_PINCONTROL_SIGNAL_DTR;
115                         }
116                         else if (!g_strcmp0(str_signal, "dsr")) {
117                                 in_signal = DUN_PINCONTROL_SIGNAL_DSR;
118                         }
119                         else if (!g_strcmp0(str_signal, "rts")) {
120                                 in_signal = DUN_PINCONTROL_SIGNAL_RTS;
121                         }
122                         else if (!g_strcmp0(str_signal, "cts")) {
123                                 in_signal = DUN_PINCONTROL_SIGNAL_CTS;
124                         }
125                         else if (!g_strcmp0(str_signal, "ri")) {
126                                 in_signal = DUN_PINCONTROL_SIGNAL_RI;
127                         }
128                         else {
129                                 /* fail */
130                                 g_free(str_signal);
131                                 resp.result = TCORE_RETURN_EINVAL;
132                                 _request_fail(ur, TRESP_PS_SET_DUN_PIN_CONTROL, sizeof(struct tresp_ps_set_dun_pin_control), &resp);
133                                 result = FALSE;
134                                 break;
135                         }
136
137                         g_free(str_signal);
138
139                         dbg("signal = %d, status = %d", in_signal, status);
140
141                         data_pincontrol.signal = in_signal;
142                         data_pincontrol.status = status;
143
144                         tcore_user_request_set_data(ur, sizeof(struct treq_ps_set_dun_pin_control), &data_pincontrol);
145                         tcore_user_request_set_command(ur, TREQ_PS_SET_DUN_PIN_CONTROL);
146                 }
147                         break;
148         }
149
150 RETURN:
151         sipc_util_marshal_object_destory(in_obj);
152         out_obj = sipc_util_marshal_object_create();
153         sipc_util_marshal_object_add_data(out_obj, "result", &result, SIPC_MARSHAL_DATA_BOOLEAN_TYPE);
154
155         dbg("result = %d", result);
156
157         *outparam = sipc_util_marshal_object_serializer(out_obj);
158         sipc_util_marshal_object_destory(out_obj);
159
160         if (result == FALSE) {
161                 return FALSE;
162         }
163
164         ret = tcore_communicator_dispatch_request(c, ur);
165         if (ret != TCORE_RETURN_SUCCESS) {
166                 return FALSE;
167         }
168
169         return TRUE;
170 }
171
172 gboolean scomm_service_response_ps(Communicator *comm, UserRequest *ur, enum tcore_response_command command,
173                 unsigned int data_len, const void *data)
174 {
175         const struct tresp_ps_set_dun_pin_control *resp_dun_pin_control = data;
176         int ret = 0;
177         gchar *out_d = NULL, *serial_d = NULL;
178         struct custom_data *ctx = NULL;
179         const struct tcore_user_info *ui;
180         struct _tapi_header hdr;
181         struct _sipc_marshal_object* out_obj = NULL;
182         struct _sipc_marshal_object* in_obj = NULL;
183
184         ctx = tcore_communicator_ref_user_data(comm);
185         if (!ctx) {
186                 dbg("user_data is NULL");
187                 return FALSE;
188         }
189
190         ui = tcore_user_request_ref_user_info(ur);
191
192         dbg("response command = [0x%x], data_len = %d", command, data_len);
193         dbg("channel_id = %d, client_cmd = %d", ui->channel_id, ui->client_cmd);
194
195         memset(&hdr, 0, sizeof(struct _tapi_header));
196         hdr.cmd = (tapi_service_command_e) ui->client_cmd;
197
198         out_obj = sipc_util_marshal_object_create();
199
200         switch (command) {
201                 case TRESP_PS_SET_DUN_PIN_CONTROL:
202                         dbg("TRESP_PS_SET_DUN_PIN_CONTROL");
203                         sipc_util_marshal_object_add_data(out_obj, "result", (void*) &resp_dun_pin_control->result,
204                                         SIPC_MARSHAL_DATA_INT_TYPE);
205                         break;
206         }
207
208         if (out_obj) {
209                 serial_d = sipc_util_marshal_object_serializer(out_obj);
210                 hdr.data_len = strlen(serial_d);
211                 sipc_util_marshal_object_destory(out_obj);
212         }
213
214         out_d = g_new0(char, sizeof(struct _tapi_header) + hdr.data_len);
215         memcpy(out_d, &hdr, sizeof(struct _tapi_header));
216
217         if (serial_d) {
218                 memcpy(out_d + sizeof(struct _tapi_header), serial_d, hdr.data_len);
219                 dbg("serial_d = [%s]", serial_d);
220                 g_free(serial_d);
221         }
222
223         ret = sipc_server_send(ctx->sk_server, ui->channel_id, out_d, sizeof(struct _tapi_header) + hdr.data_len,
224                         SIPC_SEND_DATA_ASYNC);
225         g_free(out_d);
226
227         if (ret < 0) {
228                 dbg("ret = %d", ret);
229                 return FALSE;
230         }
231
232         return TRUE;
233 }
234
235 gboolean scomm_service_notification_ps(Communicator *comm, CoreObject *source, enum tcore_notification_command command,
236                 unsigned int data_len, const void *data)
237 {
238         const struct tnoti_ps_dun_pin_control *noti_pin_info = data;
239         const struct tnoti_ps_call_status *noti_call_status = data;
240         const struct tnoti_ps_pdp_ipconfiguration *noti_pdp_ipconfiguration = data;
241         const struct tnoti_ps_protocol_status *noti_protocol_status = data;
242
243         int ret = 0;
244         struct custom_data *ctx = NULL;
245         struct _tapi_header hdr;
246         struct _sipc_marshal_object* out_obj = NULL;
247         gchar *out_d = NULL, *serial_d = NULL;
248         char *ipstr;
249
250         memset(&hdr, 0, sizeof(struct _tapi_header));
251
252         ctx = tcore_communicator_ref_user_data(comm);
253         if (!ctx) {
254                 dbg("user_data is NULL");
255                 return FALSE;
256         }
257
258         dbg("notification !!! (command = 0x%x, data_len = %d)", command, data_len);
259
260         switch (command) {
261                 case TNOTI_PS_DUN_PIN_CONTROL: {
262                         gchar *str_signal = NULL;
263                         gint status;
264
265                         switch (noti_pin_info->signal) {
266                                 case DUN_PINCONTROL_SIGNAL_DCD:
267                                         str_signal = strdup("dcd");
268                                         break;
269
270                                 case DUN_PINCONTROL_SIGNAL_DTR:
271                                         str_signal = strdup("dtr");
272                                         break;
273
274                                 case DUN_PINCONTROL_SIGNAL_DSR:
275                                         str_signal = strdup("dsr");
276                                         break;
277
278                                 case DUN_PINCONTROL_SIGNAL_RTS:
279                                         str_signal = strdup("rts");
280                                         break;
281
282                                 case DUN_PINCONTROL_SIGNAL_CTS:
283                                         str_signal = strdup("cts");
284                                         break;
285
286                                 case DUN_PINCONTROL_SIGNAL_RI:
287                                         str_signal = strdup("ri");
288                                         break;
289                         }
290                         status = noti_pin_info->status;
291
292                         hdr.cmd = TAPI_NOTI_PS_DUN_PIN_CONTROL;
293
294                         dbg("signal = [%s], status = %d", str_signal, status);
295
296                         out_obj = sipc_util_marshal_object_create();
297                         sipc_util_marshal_object_add_data(out_obj, "signal", str_signal, SIPC_MARSHAL_DATA_STRING_TYPE);
298                         sipc_util_marshal_object_add_data(out_obj, "status", &status, SIPC_MARSHAL_DATA_BOOLEAN_TYPE);
299                 }
300                         break;
301
302                 case TNOTI_PS_EXTERNAL_CALL:
303                         hdr.cmd = TAPI_NOTI_PS_EXTERNAL_CALL;
304                         /* no data */
305                         break;
306
307                 case TNOTI_PS_CALL_STATUS:
308                         hdr.cmd = TAPI_NOTI_PS_CALL_STATUS;
309                         out_obj = sipc_util_marshal_object_create();
310                         sipc_util_marshal_object_add_data(out_obj, "context_id", &noti_call_status->context_id,
311                                         SIPC_MARSHAL_DATA_INT_TYPE);
312                         if (noti_call_status->state == 1) {
313                                 sipc_util_marshal_object_add_data(out_obj, "state", "activated", SIPC_MARSHAL_DATA_STRING_TYPE);
314                         }
315                         else {
316                                 sipc_util_marshal_object_add_data(out_obj, "state", "deactivated", SIPC_MARSHAL_DATA_STRING_TYPE);
317                         }
318                         break;
319
320                 case TNOTI_PS_PDP_IPCONFIGURATION:
321                         hdr.cmd = TAPI_NOTI_PS_PDP_IPCONFIGURATION;
322                         out_obj = sipc_util_marshal_object_create();
323                         sipc_util_marshal_object_add_data(out_obj, "context_id", &noti_pdp_ipconfiguration->context_id,
324                                         SIPC_MARSHAL_DATA_INT_TYPE);
325                         sipc_util_marshal_object_add_data(out_obj, "secondary_context_id",
326                                         &noti_pdp_ipconfiguration->secondary_context_id, SIPC_MARSHAL_DATA_INT_TYPE);
327                         ipstr = _get_ip_string(noti_pdp_ipconfiguration->ip_address);
328                         sipc_util_marshal_object_add_data(out_obj, "ip_address", ipstr, SIPC_MARSHAL_DATA_STRING_TYPE);
329                         free(ipstr);
330                         ipstr = _get_ip_string(noti_pdp_ipconfiguration->primary_dns);
331                         sipc_util_marshal_object_add_data(out_obj, "primary_dns", ipstr, SIPC_MARSHAL_DATA_STRING_TYPE);
332                         free(ipstr);
333                         ipstr = _get_ip_string(noti_pdp_ipconfiguration->secondary_dns);
334                         sipc_util_marshal_object_add_data(out_obj, "secondary_dns", ipstr, SIPC_MARSHAL_DATA_STRING_TYPE);
335                         free(ipstr);
336                         ipstr = _get_ip_string(noti_pdp_ipconfiguration->gateway);
337                         sipc_util_marshal_object_add_data(out_obj, "gateway", ipstr, SIPC_MARSHAL_DATA_STRING_TYPE);
338                         free(ipstr);
339                         ipstr = _get_ip_string(noti_pdp_ipconfiguration->subnet_mask);
340                         sipc_util_marshal_object_add_data(out_obj, "subnet_mask", ipstr, SIPC_MARSHAL_DATA_STRING_TYPE);
341                         free(ipstr);
342                         sipc_util_marshal_object_add_data(out_obj, "devname", &noti_pdp_ipconfiguration->devname,
343                                         SIPC_MARSHAL_DATA_STRING_TYPE);
344                         break;
345
346                 case TNOTI_PS_PROTOCOL_STATUS:
347                         hdr.cmd = TAPI_NOTI_PS_PROTOCOL_STATUS;
348                         out_obj = sipc_util_marshal_object_create();
349                         switch (noti_protocol_status->status) {
350                                 case 1:
351                                         sipc_util_marshal_object_add_data(out_obj, "status", "hsdpa", SIPC_MARSHAL_DATA_STRING_TYPE);
352                                         break;
353
354                                 case 2:
355                                         sipc_util_marshal_object_add_data(out_obj, "status", "hspa+", SIPC_MARSHAL_DATA_STRING_TYPE);
356                                         break;
357
358                                 case 3:
359                                         sipc_util_marshal_object_add_data(out_obj, "status", "hsupa", SIPC_MARSHAL_DATA_STRING_TYPE);
360                                         break;
361
362                                 case 0:
363                                 default:
364                                         sipc_util_marshal_object_add_data(out_obj, "status", "none", SIPC_MARSHAL_DATA_STRING_TYPE);
365                                         break;
366                         }
367                         break;
368
369                 default:
370                         dbg("unknown notification");
371                         return FALSE;
372                         break;
373         }
374
375         if (out_obj) {
376                 serial_d = sipc_util_marshal_object_serializer(out_obj);
377                 hdr.data_len = strlen(serial_d);
378                 sipc_util_marshal_object_destory(out_obj);
379         }
380
381         out_d = g_new0(char, sizeof(struct _tapi_header)+hdr.data_len);
382         memcpy(out_d, &hdr, sizeof(struct _tapi_header));
383         if (serial_d) {
384                 memcpy(out_d + sizeof(struct _tapi_header), serial_d, hdr.data_len);
385                 g_free(serial_d);
386         }
387
388         dbg("len = %d, out_d = [%s]", sizeof(struct _tapi_header) + hdr.data_len, out_d);
389
390         ret = sipc_server_broadcast(ctx->sk_server, out_d, sizeof(struct _tapi_header) + hdr.data_len);
391         dbg("ret = %d", ret);
392         g_free(out_d);
393
394         return TRUE;
395 }