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