tizen 2.3.1 release
[framework/telephony/tel-plugin-dbus_tapi.git] / src / sap.c
1 /*
2  * tel-plugin-dbus-tapi
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
26 #include <tcore.h>
27 #include <server.h>
28 #include <plugin.h>
29 #include <hal.h>
30 #include <communicator.h>
31 #include <core_object.h>
32 #include <queue.h>
33 #include <user_request.h>
34 #include <util.h>
35 #include <co_sap.h>
36 #include <co_sim.h>
37
38 #include "generated-code.h"
39 #include "common.h"
40
41 static gboolean on_sap_connect(TelephonySap *sap, GDBusMethodInvocation *invocation,
42                 gint arg_req_max_size, gpointer user_data)
43 {
44         struct custom_data *ctx = user_data;
45         UserRequest *ur = NULL;
46         TReturn ret;
47         struct treq_sap_req_connect req_conn;
48
49         if (!check_access_control (invocation, AC_SAP, "x"))
50                 return TRUE;
51
52         ur = MAKE_UR(ctx, sap, invocation);
53         memset(&req_conn, 0, sizeof(struct treq_sap_req_connect));
54
55         req_conn.max_msg_size = (unsigned short)arg_req_max_size;
56
57         tcore_user_request_set_data(ur, sizeof(struct treq_sap_req_connect), &req_conn);
58         tcore_user_request_set_command(ur, TREQ_SAP_REQ_CONNECT);
59         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
60         if(ret != TCORE_RETURN_SUCCESS) {
61                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
62                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
63                 tcore_user_request_unref(ur);
64         }
65
66         return TRUE;
67 }
68
69 static gboolean on_sap_disconnect(TelephonySap *sap, GDBusMethodInvocation *invocation, gpointer user_data)
70 {
71         struct custom_data *ctx = user_data;
72         UserRequest *ur = NULL;
73         TReturn ret;
74
75         if (!check_access_control (invocation, AC_SAP, "x"))
76                 return TRUE;
77
78         ur = MAKE_UR(ctx, sap, invocation);
79
80         tcore_user_request_set_command(ur, TREQ_SAP_REQ_DISCONNECT);
81         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
82         if(ret != TCORE_RETURN_SUCCESS) {
83                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
84                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
85                 tcore_user_request_unref(ur);
86         }
87
88         return TRUE;
89 }
90
91 static gboolean on_sap_get_status(TelephonySap *sap, GDBusMethodInvocation *invocation, gpointer user_data)
92 {
93         struct custom_data *ctx = user_data;
94         UserRequest *ur = NULL;
95         TReturn ret;
96
97         if (!check_access_control (invocation, AC_SAP, "r"))
98                 return TRUE;
99
100         ur = MAKE_UR(ctx, sap, invocation);
101
102         tcore_user_request_set_command(ur, TREQ_SAP_REQ_STATUS);
103         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
104         if(ret != TCORE_RETURN_SUCCESS) {
105                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
106                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
107                 tcore_user_request_unref(ur);
108         }
109
110         return TRUE;
111 }
112
113 static gboolean on_sap_get_atr(TelephonySap *sap, GDBusMethodInvocation *invocation, gpointer user_data)
114 {
115         struct custom_data *ctx = user_data;
116         UserRequest *ur = NULL;
117         TReturn ret;
118
119         if (!check_access_control (invocation, AC_SAP, "r"))
120                 return TRUE;
121
122         ur = MAKE_UR(ctx, sap, invocation);
123
124         tcore_user_request_set_command(ur, TREQ_SAP_REQ_ATR);
125         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
126         if(ret != TCORE_RETURN_SUCCESS) {
127                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
128                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
129                 tcore_user_request_unref(ur);
130         }
131
132         return TRUE;
133 }
134
135 static gboolean on_sap_transfer_apdu(TelephonySap *sap, GDBusMethodInvocation *invocation,
136                 GVariant *arg_req_apdu, gpointer user_data)
137 {
138         struct custom_data *ctx = user_data;
139         UserRequest *ur = NULL;
140         struct treq_sap_transfer_apdu t_apdu;
141         TReturn ret;
142         GVariantIter *iter = NULL;
143         GVariant *inner_gv = NULL;
144         guchar rt_i;
145         int i =0;
146
147         dbg("Func Entrance");
148
149         if (!check_access_control (invocation, AC_SAP, "x"))
150                 return TRUE;
151
152         memset(&t_apdu, 0, sizeof(struct treq_sap_transfer_apdu));
153
154         inner_gv = g_variant_get_variant(arg_req_apdu);
155
156         g_variant_get(inner_gv, "ay", &iter);
157         while ( g_variant_iter_loop (iter, "y", &rt_i)) {
158                 t_apdu.apdu_data[i] = rt_i;
159                 i++;
160         }
161         t_apdu.apdu_length = (unsigned int)i;
162         g_variant_iter_free(iter);
163         g_variant_unref(inner_gv);
164         g_variant_unref(arg_req_apdu);
165
166         for(i=0; i < (int)t_apdu.apdu_length; i++)
167                 dbg("apdu[%d][0x%02x]",i, t_apdu.apdu_data[i]);
168
169         ur = MAKE_UR(ctx, sap, invocation);
170         tcore_user_request_set_data(ur, sizeof(struct treq_sap_transfer_apdu), &t_apdu);
171         tcore_user_request_set_command(ur, TREQ_SAP_TRANSFER_APDU);
172         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
173         if(ret != TCORE_RETURN_SUCCESS) {
174                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
175                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
176                 tcore_user_request_unref(ur);
177         }
178
179         return TRUE;
180 }
181
182 static gboolean on_sap_set_protocol(TelephonySap *sap, GDBusMethodInvocation *invocation,
183                 gint arg_protocol, gpointer user_data)
184 {
185         struct custom_data *ctx = user_data;
186         UserRequest *ur = NULL;
187         TReturn ret;
188         struct treq_sap_set_protocol set_protocol;
189
190         if (!check_access_control (invocation, AC_SAP, "w"))
191                 return TRUE;
192
193         ur = MAKE_UR(ctx, sap, invocation);
194         memset(&set_protocol, 0, sizeof(struct treq_sap_set_protocol));
195
196         set_protocol.protocol = arg_protocol;
197
198         tcore_user_request_set_data(ur, sizeof(struct treq_sap_set_protocol), &set_protocol);
199         tcore_user_request_set_command(ur, TREQ_SAP_SET_PROTOCOL);
200         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
201         if(ret != TCORE_RETURN_SUCCESS) {
202                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
203                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
204                 tcore_user_request_unref(ur);
205         }
206
207         return TRUE;
208 }
209
210 static gboolean on_sap_set_power(TelephonySap *sap, GDBusMethodInvocation *invocation,
211                 gint arg_mode, gpointer user_data)
212 {
213         struct custom_data *ctx = user_data;
214         UserRequest *ur = NULL;
215         TReturn ret;
216         struct treq_sap_set_power set_power;
217
218         if (!check_access_control (invocation, AC_SAP, "w"))
219                 return TRUE;
220
221         ur = MAKE_UR(ctx, sap, invocation);
222         memset(&set_power, 0, sizeof(struct treq_sap_set_power));
223
224         set_power.mode = arg_mode;
225
226         tcore_user_request_set_data(ur, sizeof(struct treq_sap_set_power), &set_power);
227         tcore_user_request_set_command(ur, TREQ_SAP_SET_POWER);
228         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
229         if(ret != TCORE_RETURN_SUCCESS) {
230                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
231                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
232                 tcore_user_request_unref(ur);
233         }
234
235         return TRUE;
236 }
237
238 static gboolean on_sap_get_card_reader_status(TelephonySap *sap, GDBusMethodInvocation *invocation, gpointer user_data)
239 {
240         struct custom_data *ctx = user_data;
241         UserRequest *ur = NULL;
242         TReturn ret;
243
244         if (!check_access_control (invocation, AC_SAP, "r"))
245                 return TRUE;
246
247         ur = MAKE_UR(ctx, sap, invocation);
248
249         tcore_user_request_set_command(ur, TREQ_SAP_REQ_CARDREADERSTATUS);
250         ret = tcore_communicator_dispatch_request(ctx->comm, ur);
251         if(ret != TCORE_RETURN_SUCCESS) {
252                 FAIL_RESPONSE (invocation, DEFAULT_MSG_REQ_FAILED);
253                 dbg("[ error ] tcore_communicator_dispatch_request() : (0x%x)", ret);
254                 tcore_user_request_unref(ur);
255         }
256
257         return TRUE;
258 }
259
260 gboolean dbus_plugin_setup_sap_interface(TelephonyObjectSkeleton *object, struct custom_data *ctx)
261 {
262         TelephonySap *sap;
263
264         sap = telephony_sap_skeleton_new();
265         telephony_object_skeleton_set_sap(object, sap);
266         g_object_unref(sap);
267
268         dbg("sap = %p", sap);
269
270         g_signal_connect (sap,
271                         "handle-connect",
272                         G_CALLBACK (on_sap_connect),
273                         ctx);
274
275         g_signal_connect (sap,
276                         "handle-disconnect",
277                         G_CALLBACK (on_sap_disconnect),
278                         ctx);
279
280         g_signal_connect (sap,
281                         "handle-get-status",
282                         G_CALLBACK (on_sap_get_status),
283                         ctx);
284
285         g_signal_connect (sap,
286                         "handle-get-atr",
287                         G_CALLBACK (on_sap_get_atr),
288                         ctx);
289
290         g_signal_connect (sap,
291                         "handle-transfer-apdu",
292                         G_CALLBACK (on_sap_transfer_apdu),
293                         ctx);
294
295         g_signal_connect (sap,
296                         "handle-set-protocol",
297                         G_CALLBACK (on_sap_set_protocol),
298                         ctx);
299
300         g_signal_connect (sap,
301                         "handle-set-power",
302                         G_CALLBACK (on_sap_set_power),
303                         ctx);
304
305         g_signal_connect (sap,
306                         "handle-get-card-reader-status",
307                         G_CALLBACK (on_sap_get_card_reader_status),
308                         ctx);
309
310         return TRUE;
311 }
312
313 gboolean dbus_plugin_sap_response(struct custom_data *ctx, UserRequest *ur,
314                 struct dbus_request_info *dbus_info, enum tcore_response_command command,
315                 unsigned int data_len, const void *data)
316 {
317         const struct tresp_sap_req_connect *sap_conn = data;
318         const struct tresp_sap_req_disconnect *sap_disconn = data;
319         const struct tresp_sap_req_status *sap_status = data;
320         const struct tresp_sap_req_atr *sap_atr = data;
321         const struct tresp_sap_transfer_apdu *sap_apdu = data;
322         const struct tresp_sap_set_protocol *sap_protocol = data;
323         const struct tresp_sap_set_power *sap_power = data;
324         const struct tresp_sap_req_cardreaderstatus *sap_reader = data;
325
326         dbg("application Command = [0x%x], data_len = %d",command, data_len);
327
328         switch (command) {
329                 case TRESP_SAP_REQ_CONNECT:
330                         dbg("dbus comm - TRESP_SAP_REQ_CONNECT");
331                         telephony_sap_complete_connect(dbus_info->interface_object, dbus_info->invocation,
332                                         sap_conn->status, sap_conn->max_msg_size);
333                         break;
334
335                 case TRESP_SAP_REQ_DISCONNECT:
336                         dbg("dbus comm - TRESP_SAP_REQ_DISCONNECT");
337                         telephony_sap_complete_disconnect(dbus_info->interface_object, dbus_info->invocation,
338                                         sap_disconn->result);
339                         break;
340
341                 case TRESP_SAP_REQ_STATUS:
342                         dbg("dbus comm - TRESP_SAP_REQ_STATUS");
343                         telephony_sap_complete_get_status(dbus_info->interface_object, dbus_info->invocation,
344                                         sap_status->status);
345                         break;
346
347                 case TRESP_SAP_REQ_ATR: {
348                         GVariantBuilder builder;
349                         GVariant * atr_gv = NULL;
350                         GVariant *inner_gv = NULL;
351                         int i =0;
352
353                         dbg("dbus comm - TRESP_SAP_REQ_ATR");
354                         g_variant_builder_init(&builder, G_VARIANT_TYPE ("ay"));
355                         for(i = 0; i < (int)sap_atr->atr_length; i++) {
356                                 dbg("sap_atr->atr[%d][0x%02x]", i,sap_atr->atr[i]);
357                                 g_variant_builder_add (&builder, "y", sap_atr->atr[i]);
358                         }
359                         inner_gv = g_variant_builder_end(&builder);
360                         atr_gv = g_variant_new("v", inner_gv);
361
362                         telephony_sap_complete_get_atr(dbus_info->interface_object, dbus_info->invocation,
363                                         sap_atr->result, atr_gv);
364                 }
365                         break;
366
367                 case TRESP_SAP_TRANSFER_APDU: {
368                         GVariantBuilder builder;
369                         GVariant * apdu_gv = NULL;
370                         GVariant *inner_gv = NULL;
371                         int i =0;
372
373                         dbg("dbus comm - TRESP_SAP_TRANSFER_APDU");
374                         g_variant_builder_init(&builder, G_VARIANT_TYPE ("ay"));
375                         for(i = 0; i < (int)sap_apdu->resp_apdu_length; i++) {
376                                 dbg("sap_apdu->resp_adpdu[%d][0x%02x]", i,sap_apdu->resp_adpdu[i]);
377                                 g_variant_builder_add (&builder, "y", sap_apdu->resp_adpdu[i]);
378                         }
379                         inner_gv = g_variant_builder_end(&builder);
380                         apdu_gv = g_variant_new("v", inner_gv);
381
382                         telephony_sap_complete_transfer_apdu(dbus_info->interface_object, dbus_info->invocation,
383                                         sap_apdu->result, apdu_gv);
384                 }
385                         break;
386
387                 case TRESP_SAP_SET_PROTOCOL:
388                         dbg("dbus comm - TRESP_SAP_SET_PROTOCOL");
389                         telephony_sap_complete_set_protocol(dbus_info->interface_object, dbus_info->invocation,
390                                         sap_protocol->result);
391                         break;
392
393                 case TRESP_SAP_SET_POWER:
394                         dbg("dbus comm - TRESP_SAP_SET_POWER");
395                         telephony_sap_complete_set_power(dbus_info->interface_object, dbus_info->invocation,
396                                         sap_power->result);
397                         break;
398
399                 case TRESP_SAP_REQ_CARDREADERSTATUS:
400                         dbg("dbus comm - TRESP_SAP_REQ_CARDREADERSTATUS");
401                         telephony_sap_complete_get_card_reader_status(dbus_info->interface_object, dbus_info->invocation,
402                                         sap_reader->result, sap_reader->reader_status);
403                         break;
404
405                 default:
406                         dbg("not handled command[%d]", command);
407                 break;
408         }
409
410         return TRUE;
411 }
412
413 gboolean dbus_plugin_sap_notification(struct custom_data *ctx, CoreObject *source,
414                 TelephonyObjectSkeleton *object, enum tcore_notification_command command,
415                 unsigned int data_len, const void *data)
416 {
417         TelephonySap *sap;
418         const struct tnoti_sap_status_changed *n_sap_status = data;
419         const struct tnoti_sap_disconnect *n_sap_disconn = data;
420
421         if (!object) {
422                 dbg("object is NULL");
423                 return FALSE;
424         }
425
426         sap = telephony_object_peek_sap(TELEPHONY_OBJECT(object));
427
428         switch (command) {
429                 case TNOTI_SAP_STATUS:
430                         dbg("notified sap_status[%d]", n_sap_status->status);
431                         telephony_sap_emit_status(sap, n_sap_status->status);
432                         break;
433                 case TNOTI_SAP_DISCONNECT:
434                         dbg("notified sap_disconnect type[%d]", n_sap_disconn->type);
435                         telephony_sap_emit_disconnect(sap, n_sap_disconn->type);
436                         break;
437                 default:
438                         dbg("not handled command[%d]", command);
439                 break;
440         }
441
442         return TRUE;
443 }