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