Sync from SPIN branch
[platform/core/telephony/tel-plugin-dbus_tapi.git] / src / dtapi_sms.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
25 #include <glib.h>
26
27 #include <tcore.h>
28 #include <server.h>
29 #include <plugin.h>
30 #include <co_sms.h>
31
32 #include "generated-code.h"
33 #include "dtapi_common.h"
34
35 static gboolean on_sms_send_msg(TelephonySms *sms,
36         GDBusMethodInvocation *invocation,
37         gint format, GVariant *sca,
38         gint tpdu_length, GVariant *tpdu_data,
39         gint more_msg, gpointer user_data)
40 {
41         struct treq_sms_send_msg req;
42         struct custom_data *ctx = user_data;
43         enum tcore_request_command command;
44         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
45
46         int i = 0;
47         GVariantIter *iter = NULL;
48         GVariant *inner_gv = NULL;
49
50         if (!check_access_control(p_cynara, invocation, AC_SMS, "x"))
51                 return TRUE;
52
53         memset(&req, 0x0, sizeof(struct treq_sms_send_msg));
54
55         if (SMS_NETTYPE_3GPP == format) {
56                 command =  TREQ_SMS_SEND_UMTS_MSG;
57         } else if (SMS_NETTYPE_3GPP2 == format) {
58                 command = TREQ_SMS_SEND_CDMA_MSG;
59         } else {
60                 err("Invalid Format Received:[%d]", format);
61
62                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
63
64                 return TRUE;
65         }
66
67         inner_gv = g_variant_get_variant(sca);
68         g_variant_get(inner_gv, "ay", &iter);
69         while (g_variant_iter_loop(iter, "y", &req.msgDataPackage.sca[i])) {
70                 i++;
71                 if (i >= SMS_SMSP_ADDRESS_LEN)
72                         break;
73         }
74         g_variant_iter_free(iter);
75         g_variant_unref(inner_gv);
76
77         req.msgDataPackage.msgLength = tpdu_length;
78
79         i = 0;
80         inner_gv = g_variant_get_variant(tpdu_data);
81         g_variant_get(inner_gv, "ay", &iter);
82         while (g_variant_iter_loop(iter, "y", &req.msgDataPackage.tpduData[i])) {
83                 i++;
84                 if (i >= SMS_SMDATA_SIZE_MAX + 1)
85                         break;
86         }
87         g_variant_iter_free(iter);
88         g_variant_unref(inner_gv);
89
90         req.msgDataPackage.format = format;
91         req.more = more_msg;
92
93         /* Dispatch request */
94         dtapi_dispatch_request(ctx, sms, invocation,
95                 command,
96                 &req, sizeof(struct treq_sms_send_msg));
97
98         return  TRUE;
99 }
100
101 static gboolean on_sms_read_msg(TelephonySms *sms,
102         GDBusMethodInvocation *invocation, gint msg_index, gpointer user_data)
103 {
104         struct treq_sms_read_msg req;
105         struct custom_data *ctx = user_data;
106         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
107
108         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
109                 return TRUE;
110
111         req.index = msg_index;
112
113         /* Dispatch request */
114         dtapi_dispatch_request(ctx, sms, invocation,
115                 TREQ_SMS_READ_MSG,
116                 &req, sizeof(struct treq_sms_read_msg));
117
118         return TRUE;
119 }
120
121 static gboolean on_sms_save_msg(TelephonySms *sms,
122         GDBusMethodInvocation *invocation,
123         gint format, gint msg_status, GVariant *sca,
124         gint tpdu_length, GVariant *tpdu_data, gpointer user_data)
125 {
126         struct treq_sms_save_msg req;
127         struct custom_data *ctx = user_data;
128         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
129
130         int i = 0;
131         GVariantIter *iter = NULL;
132         GVariant *inner_gv = NULL;
133
134         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
135                 return TRUE;
136
137         if (SMS_NETTYPE_3GPP == format) {
138                 req.msgDataPackage.format = SMS_NETTYPE_3GPP;
139         } else if (SMS_NETTYPE_3GPP2 == format) {
140                 req.msgDataPackage.format = SMS_NETTYPE_3GPP2;
141         } else {
142                 err("Invalid Format Received:[%d]", format);
143
144                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
145
146                 return TRUE;
147         }
148
149         req.simIndex = 0xffff;
150         req.msgStatus = msg_status;
151
152         inner_gv = g_variant_get_variant(sca);
153         g_variant_get(inner_gv, "ay", &iter);
154         while (g_variant_iter_loop(iter, "y", &req.msgDataPackage.sca[i])) {
155                 i++;
156                 if (i >= SMS_SMSP_ADDRESS_LEN)
157                         break;
158         }
159         g_variant_iter_free(iter);
160         g_variant_unref(inner_gv);
161
162         i = 0;
163         inner_gv = g_variant_get_variant(tpdu_data);
164         g_variant_get(inner_gv, "ay", &iter);
165         while (g_variant_iter_loop(iter, "y", &req.msgDataPackage.tpduData[i])) {
166                 i++;
167                 if (i >= SMS_SMDATA_SIZE_MAX + 1)
168                         break;
169         }
170         g_variant_iter_free(iter);
171         g_variant_unref(inner_gv);
172
173         req.msgDataPackage.msgLength = tpdu_length;
174
175         /* Dispatch request */
176         dtapi_dispatch_request(ctx, sms, invocation,
177                 TREQ_SMS_SAVE_MSG,
178                 &req, sizeof(struct treq_sms_save_msg));
179
180         return TRUE;
181 }
182
183 static gboolean on_sms_delete_msg(TelephonySms *sms,
184         GDBusMethodInvocation *invocation, gint msg_index, gpointer user_data)
185 {
186         struct treq_sms_delete_msg req;
187         struct custom_data *ctx = user_data;
188         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
189
190         if (!check_access_control(p_cynara, invocation, AC_SMS, "x"))
191                 return TRUE;
192
193         req.index = msg_index;
194
195         /* Dispatch request */
196         dtapi_dispatch_request(ctx, sms, invocation,
197                 TREQ_SMS_DELETE_MSG,
198                 &req, sizeof(struct treq_sms_delete_msg));
199
200         return TRUE;
201 }
202
203 static gboolean on_sms_get_msg_count(TelephonySms *sms,
204         GDBusMethodInvocation *invocation, gpointer user_data)
205 {
206         struct custom_data *ctx = user_data;
207         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
208
209         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
210                 return TRUE;
211
212         /* Dispatch request */
213         dtapi_dispatch_request(ctx, sms, invocation,
214                 TREQ_SMS_GET_COUNT,
215                 NULL, 0);
216
217         return TRUE;
218 }
219
220 static gboolean on_sms_get_sca(TelephonySms *sms,
221         GDBusMethodInvocation *invocation, gint msg_index, gpointer user_data)
222 {
223         struct treq_sms_get_sca req;
224         struct custom_data *ctx = user_data;
225         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
226
227         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
228                 return TRUE;
229
230         req.index = msg_index;
231
232         /* Dispatch request */
233         dtapi_dispatch_request(ctx, sms, invocation,
234                 TREQ_SMS_GET_SCA,
235                 &req, sizeof(struct treq_sms_get_sca));
236
237         return TRUE;
238 }
239
240 static gboolean on_sms_set_sca(TelephonySms *sms,
241         GDBusMethodInvocation *invocation,
242         gint msg_index,
243         gint sca_ton, gint sca_npi, gint sca_length, GVariant *sca,
244         gpointer user_data)
245 {
246         struct custom_data *ctx = user_data;
247         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
248
249         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
250                 return TRUE;
251
252         if ((sca_length <= 0)
253                         || (sca_length > (SMS_MAX_SMS_SERVICE_CENTER_ADDR + 1))) {
254                 err("[tcore_SMS] TAPI_API_INVALID_INPUT !!!");
255
256                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
257         } else if (msg_index != 0) {
258                 err("[tcore_SMS] Index except 0 is supported");
259
260                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
261         } else {
262                 struct treq_sms_set_sca req;
263
264                 int i = 0;
265                 GVariantIter *iter = NULL;
266                 GVariant *inner_gv = NULL;
267
268                 memset(&req, 0, sizeof(struct treq_sms_set_sca));
269
270                 req.index = msg_index;
271                 req.scaInfo.dialNumLen = sca_length;
272                 req.scaInfo.typeOfNum = sca_ton;
273                 req.scaInfo.numPlanId = sca_npi;
274
275                 inner_gv = g_variant_get_variant(sca);
276                 g_variant_get(inner_gv, "ay", &iter);
277                 while (g_variant_iter_loop(iter, "y", &req.scaInfo.diallingNum[i])) {
278                         i++;
279                         if (i >= SMS_SMSP_ADDRESS_LEN + 1)
280                                 break;
281                 }
282
283                 g_variant_iter_free(iter);
284                 g_variant_unref(inner_gv);
285
286                 /* Dispatch request */
287                 dtapi_dispatch_request(ctx, sms, invocation,
288                         TREQ_SMS_SET_SCA,
289                         &req, sizeof(struct treq_sms_set_sca));
290         }
291
292         return TRUE;
293 }
294
295 static gboolean on_sms_get_cb_config(TelephonySms *sms,
296         GDBusMethodInvocation *invocation, gpointer user_data)
297 {
298         struct custom_data *ctx = user_data;
299         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
300
301         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
302                 return TRUE;
303
304         /* Dispatch request */
305         dtapi_dispatch_request(ctx, sms, invocation,
306                 TREQ_SMS_GET_CB_CONFIG,
307                 NULL, 0);
308
309         return TRUE;
310 }
311
312 static gboolean on_sms_set_cb_config(TelephonySms *sms,
313         GDBusMethodInvocation *invocation,
314         gint network_type, gboolean enable_cb,
315         gint msg_id_max_cnt, gint msg_id_range_cnt,
316         GVariant *arg_mdgId, gpointer user_data)
317 {
318         struct treq_sms_set_cb_config req;
319         struct custom_data *ctx = user_data;
320         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
321
322         GVariant *value = NULL;
323         GVariant *inner_gv = NULL;
324         GVariantIter *iter = NULL;
325         GVariantIter *iter_row = NULL;
326         const gchar *key = NULL;
327         int i = 0;
328
329         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
330                 return TRUE;
331
332         req.net3gppType = network_type;
333         req.cbEnabled = enable_cb;
334         req.msgIdMaxCount = msg_id_max_cnt;
335         req.msgIdRangeCount = msg_id_range_cnt;
336
337         inner_gv = g_variant_get_variant(arg_mdgId);
338         g_variant_get(inner_gv, "aa{sv}", &iter);
339         while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
340                 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
341                         if (!g_strcmp0(key, "FromMsgId"))
342                                 req.msgIDs[i].net3gpp.fromMsgId = g_variant_get_uint16(value);
343                         else if (!g_strcmp0(key, "ToMsgId"))
344                                 req.msgIDs[i].net3gpp.toMsgId = g_variant_get_uint16(value);
345                         else if (!g_strcmp0(key, "CBCategory"))
346                                 req.msgIDs[i].net3gpp2.cbCategory = g_variant_get_uint16(value);
347                         else if (!g_strcmp0(key, "CBLanguage"))
348                                 req.msgIDs[i].net3gpp2.cbLanguage = g_variant_get_uint16(value);
349                         else if (!g_strcmp0(key, "Selected"))
350                                 req.msgIDs[i].net3gpp2.selected = g_variant_get_byte(value);
351                 }
352                 g_variant_iter_free(iter_row);
353
354                 i++;
355                 if (i >= SMS_GSM_SMS_CBMI_LIST_SIZE_MAX)
356                         break;
357         }
358         g_variant_iter_free(iter);
359         g_variant_unref(inner_gv);
360
361         /* Dispatch request */
362         dtapi_dispatch_request(ctx, sms, invocation,
363                 TREQ_SMS_SET_CB_CONFIG,
364                 &req, sizeof(struct treq_sms_set_cb_config));
365
366         return TRUE;
367 }
368
369 static gboolean on_sms_set_mem_status(TelephonySms *sms,
370         GDBusMethodInvocation *invocation,
371         gint memory_status, gpointer user_data)
372 {
373         struct treq_sms_set_mem_status req;
374         struct custom_data *ctx = user_data;
375         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
376
377         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
378                 return TRUE;
379
380         req.memory_status = memory_status;
381
382         /* Dispatch request */
383         dtapi_dispatch_request(ctx, sms, invocation,
384                 TREQ_SMS_SET_MEM_STATUS,
385                 &req, sizeof(struct treq_sms_set_mem_status));
386
387         return TRUE;
388 }
389
390 static gboolean on_sms_get_pref_bearer(TelephonySms *sms,
391         GDBusMethodInvocation *invocation, gpointer user_data)
392 {
393         struct custom_data *ctx = user_data;
394         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
395
396         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
397                 return TRUE;
398
399         /* Dispatch request */
400         dtapi_dispatch_request(ctx, sms, invocation,
401                 TREQ_SMS_GET_PREF_BEARER,
402                 NULL, 0);
403
404         return TRUE;
405 }
406
407 static gboolean on_sms_set_pref_bearer(TelephonySms *sms,
408         GDBusMethodInvocation *invocation,
409         gint bearer_type, gpointer user_data)
410 {
411         struct treq_sms_set_pref_bearer req;
412         struct custom_data *ctx = user_data;
413         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
414
415         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
416                 return TRUE;
417
418         req.svc = bearer_type;
419
420         /* Dispatch request */
421         dtapi_dispatch_request(ctx, sms, invocation,
422                 TREQ_SMS_SET_PREF_BEARER,
423                 &req, sizeof(struct treq_sms_set_pref_bearer));
424
425         return TRUE;
426 }
427
428 static gboolean on_sms_set_delivery_report(TelephonySms *sms,
429         GDBusMethodInvocation *invocation,
430         gint format, const gchar *sca,
431         gint tpdu_length, const gchar *tpdu_data,
432         gint rp_cause, gpointer user_data)
433 {
434         struct treq_sms_set_delivery_report req;
435         struct custom_data *ctx = user_data;
436         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
437
438         guchar *decoded_sca = NULL;
439         guchar *decoded_tpdu = NULL;
440
441         gsize decoded_sca_len = 0;
442         gsize decoded_tpdu_len = 0;
443
444         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
445                 return TRUE;
446
447         memset(&req, 0, sizeof(struct treq_sms_set_delivery_report));
448
449         if (SMS_NETTYPE_3GPP == format) {
450                 req.dataInfo.format = SMS_NETTYPE_3GPP;
451         } else if (SMS_NETTYPE_3GPP2 == format) {
452                 req.dataInfo.format = SMS_NETTYPE_3GPP2;
453         } else {
454                 err("Invalid Format Received:[%d]", format);
455
456                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
457
458                 return TRUE;
459         }
460
461         decoded_sca = g_base64_decode(sca, &decoded_sca_len);
462         if (NULL == decoded_sca) {
463                 warn("g_base64_decode: Failed to decode sca");
464
465                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
466
467                 return TRUE;
468         } else if (decoded_sca_len > SMS_SMSP_ADDRESS_LEN) {
469                 err("Invalid Sca length");
470
471                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
472
473                 goto EXIT;
474         }
475         memcpy(req.dataInfo.sca, decoded_sca, decoded_sca_len);
476
477         decoded_tpdu = g_base64_decode(tpdu_data, &decoded_tpdu_len);
478         if (NULL == decoded_tpdu) {
479                 warn("g_base64_decode: Failed to decode tpdu");
480                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
481                 goto EXIT;
482         } else if (decoded_tpdu_len > SMS_SMDATA_SIZE_MAX+1) {
483                 err("Invalid tpdu length");
484
485                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
486
487                 goto EXIT;
488         }
489         memcpy(req.dataInfo.tpduData, decoded_tpdu, decoded_tpdu_len);
490
491         info("[%s] Decoded SCA len: [%d] TPDU len: [%d]", GET_CP_NAME(invocation),
492                 decoded_sca_len, decoded_tpdu_len);
493
494         req.dataInfo.msgLength = tpdu_length;
495         req.rspType = rp_cause;
496
497         /* Dispatch request */
498         dtapi_dispatch_request(ctx, sms, invocation,
499                 TREQ_SMS_SET_DELIVERY_REPORT,
500                 &req, sizeof(struct treq_sms_set_delivery_report));
501
502 EXIT:
503         g_free(decoded_sca);
504         g_free(decoded_tpdu);
505
506         return TRUE;
507 }
508
509 static gboolean on_sms_set_msg_status(TelephonySms *sms,
510         GDBusMethodInvocation *invocation,
511         gint msg_index, gint msg_status, gpointer user_data)
512 {
513         struct treq_sms_set_msg_status req;
514         struct custom_data *ctx = user_data;
515         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
516
517         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
518                 return TRUE;
519
520         req.index = msg_index;
521         req.msgStatus = msg_status;
522
523         /* Dispatch request */
524         dtapi_dispatch_request(ctx, sms, invocation,
525                 TREQ_SMS_SET_MSG_STATUS,
526                 &req, sizeof(struct treq_sms_set_msg_status));
527
528         return TRUE;
529 }
530
531 static gboolean on_sms_get_sms_params(TelephonySms *sms,
532         GDBusMethodInvocation *invocation,
533         gint msg_index, gpointer user_data)
534 {
535         struct treq_sms_get_params req;
536         struct custom_data *ctx = user_data;
537         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
538
539         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
540                 return TRUE;
541
542         req.index = msg_index;
543
544         /* Dispatch request */
545         dtapi_dispatch_request(ctx, sms, invocation,
546                 TREQ_SMS_GET_PARAMS,
547                 &req, sizeof(struct treq_sms_get_params));
548
549         return TRUE;
550 }
551
552 static gboolean on_sms_set_sms_params(TelephonySms *sms,
553         GDBusMethodInvocation *invocation,
554         gint record_index, gint record_len,
555         gint alpha_id_len, GVariant *alpha_id,
556         gint param_indicator,
557         gint dial_num_len, gint dial_num_ton, gint dial_num_npi, GVariant *dial_num,
558         gint sca_len, gint sca_ton, gint sca_npi, GVariant *sca,
559         gint protocol_id, gint dcs, gint validity_period,
560         gpointer user_data)
561 {
562         struct treq_sms_set_params req;
563         struct custom_data *ctx = user_data;
564         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
565
566         int i = 0;
567         GVariantIter *iter = NULL;
568         GVariant *inner_gv = NULL;
569
570         if (!check_access_control(p_cynara, invocation, AC_SMS, "w"))
571                 return TRUE;
572
573         memset(&req, 0x0, sizeof(struct treq_sms_set_params));
574
575         req.params.recordIndex = record_index;
576         req.params.recordLen = record_len;
577         req.params.alphaIdLen = alpha_id_len;
578
579         inner_gv = g_variant_get_variant(alpha_id);
580         g_variant_get(inner_gv, "ay", &iter);
581         while (g_variant_iter_loop(iter, "y", &req.params.szAlphaId[i])) {
582                 i++;
583                 if (i >= SMS_SMSP_ALPHA_ID_LEN_MAX + 1)
584                         break;
585         }
586         g_variant_iter_free(iter);
587         g_variant_unref(inner_gv);
588
589         req.params.paramIndicator = param_indicator;
590         req.params.tpDestAddr.dialNumLen = dial_num_len;
591         req.params.tpDestAddr.typeOfNum = dial_num_ton;
592         req.params.tpDestAddr.numPlanId = dial_num_npi;
593
594         i = 0;
595         inner_gv = g_variant_get_variant(dial_num);
596         g_variant_get(inner_gv, "ay", &iter);
597         while (g_variant_iter_loop(iter, "y", &req.params.tpDestAddr.diallingNum[i])) {
598                 i++;
599                 if (i >= SMS_SMSP_ADDRESS_LEN + 1)
600                         break;
601         }
602         g_variant_iter_free(iter);
603         g_variant_unref(inner_gv);
604
605         req.params.tpSvcCntrAddr.dialNumLen = sca_len;
606         req.params.tpSvcCntrAddr.typeOfNum = sca_ton;
607         req.params.tpSvcCntrAddr.numPlanId = sca_npi;
608
609         i = 0;
610         inner_gv = g_variant_get_variant(sca);
611         g_variant_get(inner_gv, "ay", &iter);
612         while (g_variant_iter_loop(iter, "y", &req.params.tpSvcCntrAddr.diallingNum[i])) {
613                 i++;
614                 if (i >= SMS_SMSP_ADDRESS_LEN + 1)
615                         break;
616         }
617         g_variant_iter_free(iter);
618         g_variant_unref(inner_gv);
619
620         req.params.tpProtocolId = protocol_id;
621         req.params.tpDataCodingScheme = dcs;
622         req.params.tpValidityPeriod = validity_period;
623
624         /* Dispatch request */
625         dtapi_dispatch_request(ctx, sms, invocation,
626                 TREQ_SMS_SET_PARAMS,
627                 &req, sizeof(struct treq_sms_set_params));
628
629         return TRUE;
630 }
631
632 static gboolean on_sms_get_sms_param_cnt(TelephonySms *sms,
633         GDBusMethodInvocation *invocation, gpointer user_data)
634 {
635         struct custom_data *ctx = user_data;
636         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
637
638         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
639                 return TRUE;
640
641         /* Dispatch request */
642         dtapi_dispatch_request(ctx, sms, invocation,
643                 TREQ_SMS_GET_PARAMCNT,
644                 NULL, 0);
645
646         return TRUE;
647 }
648
649 static gboolean on_sms_get_sms_ready_status(TelephonySms *sms,
650         GDBusMethodInvocation *invocation, gpointer user_data)
651 {
652         struct custom_data *ctx = user_data;
653         CoreObject *co_sms = NULL;
654         TcorePlugin *plugin = NULL;
655         gboolean ready_status = FALSE;
656         cynara *p_cynara = (ctx) ? ctx->p_cynara : NULL;
657
658         if (!check_access_control(p_cynara, invocation, AC_SMS, "r"))
659                 return TRUE;
660
661         plugin = tcore_server_find_plugin(ctx->server, GET_CP_NAME(invocation));
662         co_sms = tcore_plugin_ref_core_object(plugin, CORE_OBJECT_TYPE_SMS);
663         if (!co_sms) {
664                 err("co_sms is NULL");
665
666                 FAIL_RESPONSE(invocation, DEFAULT_MSG_REQ_FAILED);
667
668                 return TRUE;
669         }
670
671         ready_status = tcore_sms_get_ready_status(co_sms);
672         dbg("[%s] ready_status = %d", GET_CP_NAME(invocation), ready_status);
673
674         telephony_sms_complete_get_sms_ready_status(sms, invocation, ready_status);
675
676         return TRUE;
677 }
678
679 gboolean dbus_plugin_setup_sms_interface(TelephonyObjectSkeleton *object,
680         struct custom_data *ctx)
681 {
682         TelephonySms *sms;
683
684         sms = telephony_sms_skeleton_new();
685         telephony_object_skeleton_set_sms(object, sms);
686         g_object_unref(sms);
687
688         dbg("sms = %p", sms);
689
690         /*
691          * Register signal handlers for SMS interface
692          */
693         g_signal_connect(sms,
694                 "handle-send-msg",
695                 G_CALLBACK(on_sms_send_msg), ctx);
696
697         g_signal_connect(sms,
698                 "handle-read-msg",
699                 G_CALLBACK(on_sms_read_msg), ctx);
700
701         g_signal_connect(sms,
702                 "handle-save-msg",
703                 G_CALLBACK(on_sms_save_msg), ctx);
704
705         g_signal_connect(sms,
706                 "handle-delete-msg",
707                 G_CALLBACK(on_sms_delete_msg), ctx);
708
709         g_signal_connect(sms,
710                 "handle-get-msg-count",
711                 G_CALLBACK(on_sms_get_msg_count), ctx);
712
713         g_signal_connect(sms,
714                 "handle-get-sca",
715                 G_CALLBACK(on_sms_get_sca), ctx);
716
717         g_signal_connect(sms,
718                 "handle-set-sca",
719                 G_CALLBACK(on_sms_set_sca), ctx);
720
721         g_signal_connect(sms,
722                 "handle-get-cb-config",
723                 G_CALLBACK(on_sms_get_cb_config), ctx);
724
725         g_signal_connect(sms,
726                 "handle-set-cb-config",
727                 G_CALLBACK(on_sms_set_cb_config), ctx);
728
729         g_signal_connect(sms,
730                 "handle-set-mem-status",
731                 G_CALLBACK(on_sms_set_mem_status), ctx);
732
733         g_signal_connect(sms,
734                 "handle-get-pref-bearer",
735                 G_CALLBACK(on_sms_get_pref_bearer), ctx);
736
737         g_signal_connect(sms,
738                 "handle-set-pref-bearer",
739                 G_CALLBACK(on_sms_set_pref_bearer), ctx);
740
741         g_signal_connect(sms,
742                 "handle-set-delivery-report",
743                 G_CALLBACK(on_sms_set_delivery_report), ctx);
744
745         g_signal_connect(sms,
746                 "handle-set-msg-status",
747                 G_CALLBACK(on_sms_set_msg_status), ctx);
748
749         g_signal_connect(sms,
750                 "handle-get-sms-params",
751                 G_CALLBACK(on_sms_get_sms_params), ctx);
752
753         g_signal_connect(sms,
754                 "handle-set-sms-params",
755                 G_CALLBACK(on_sms_set_sms_params), ctx);
756
757         g_signal_connect(sms,
758                 "handle-get-sms-param-cnt",
759                 G_CALLBACK(on_sms_get_sms_param_cnt), ctx);
760
761         g_signal_connect(sms,
762                 "handle-get-sms-ready-status",
763                 G_CALLBACK(on_sms_get_sms_ready_status), ctx);
764
765         return TRUE;
766 }
767
768 gboolean dbus_plugin_sms_response(struct custom_data *ctx,
769         UserRequest *ur, struct dbus_request_info *dbus_info,
770         enum tcore_response_command command, unsigned int data_len, const void *data)
771 {
772         char *cpname = dbus_info ? GET_CP_NAME(dbus_info->invocation) : "";
773
774         switch (command) {
775         case TRESP_SMS_SEND_UMTS_MSG: {
776                 const struct tresp_sms_send_msg *resp = data;
777
778                 dbg("[%s] SEND_UMTS_MSG (result:[0x%x])", cpname, resp->result);
779
780                 telephony_sms_complete_send_msg(dbus_info->interface_object,
781                         dbus_info->invocation, resp->result);
782         }
783         break;
784
785         case TRESP_SMS_SEND_CDMA_MSG: {
786                 const struct tresp_sms_send_msg *resp = data;
787
788                 dbg("[%s] SEND_CDMA_MSG (result:[0x%x])", cpname, resp->result);
789
790                 telephony_sms_complete_send_msg(dbus_info->interface_object,
791                         dbus_info->invocation, resp->result);
792         }
793         break;
794
795         case TRESP_SMS_READ_MSG: {
796                 const struct tresp_sms_read_msg *resp = data;
797                 GVariant *sca = NULL, *packet_sca = NULL;
798                 GVariant *tpdu = NULL, *packet_tpdu = NULL;
799                 GVariantBuilder b;
800                 unsigned int i;
801
802                 dbg("[%s] READ_MSG (result:[0x%x])", cpname, resp->result);
803
804                 g_variant_builder_init(&b, G_VARIANT_TYPE("ay"));
805                 for (i = 0; i < SMS_SMSP_ADDRESS_LEN; i++)
806                         g_variant_builder_add(&b, "y", resp->dataInfo.smsData.sca[i]);
807                 sca = g_variant_builder_end(&b);
808
809                 g_variant_builder_init(&b, G_VARIANT_TYPE("ay"));
810                 for (i = 0; i < SMS_SMDATA_SIZE_MAX + 1; i++)
811                         g_variant_builder_add(&b, "y", resp->dataInfo.smsData.tpduData[i]);
812                 tpdu = g_variant_builder_end(&b);
813
814                 packet_sca = g_variant_new("v", sca);
815                 packet_tpdu = g_variant_new("v", tpdu);
816
817                 telephony_sms_complete_read_msg(dbus_info->interface_object,
818                         dbus_info->invocation, resp->result,
819                         resp->dataInfo.simIndex, resp->dataInfo.msgStatus,
820                         resp->dataInfo.smsData.format,
821                         packet_sca,
822                         resp->dataInfo.smsData.msgLength,
823                         packet_tpdu);
824         }
825         break;
826
827         case TRESP_SMS_SAVE_MSG: {
828                 const struct tresp_sms_save_msg *resp = data;
829
830                 dbg("[%s] SAVE_MSG (index:[%d] result:[0x%x])", cpname, resp->index, resp->result);
831
832                 telephony_sms_complete_save_msg(dbus_info->interface_object,
833                         dbus_info->invocation, resp->result, resp->index);
834         }
835         break;
836
837         case TRESP_SMS_DELETE_MSG: {
838                 const struct tresp_sms_delete_msg *resp = data;
839
840                 dbg("[%s] DELETE_MSG (index:[%d] result:[0x%x])", cpname, resp->index, resp->result);
841
842                 telephony_sms_complete_delete_msg(dbus_info->interface_object,
843                         dbus_info->invocation, resp->result, resp->index);
844         }
845         break;
846
847         case TRESP_SMS_GET_STORED_MSG_COUNT: {
848                 const struct tresp_sms_get_storedMsgCnt *resp = data;
849                 GVariant *list;
850                 GVariantBuilder b;
851                 unsigned int i;
852
853                 dbg("[%s] GET_STORED_MSG_COUNT (result:[0x%x])", cpname, resp->result);
854
855                 g_variant_builder_init(&b, G_VARIANT_TYPE("ai"));
856                 for (i = 0; i < resp->storedMsgCnt.totalCount; i++)
857                         g_variant_builder_add(&b, "i", resp->storedMsgCnt.indexList[i]);
858                 list = g_variant_builder_end(&b);
859
860                 telephony_sms_complete_get_msg_count(dbus_info->interface_object,
861                         dbus_info->invocation, resp->result,
862                         resp->storedMsgCnt.totalCount,
863                         resp->storedMsgCnt.usedCount,
864                         list);
865         }
866         break;
867
868         case TRESP_SMS_GET_SCA: {
869                 const struct tresp_sms_get_sca *resp = data;
870                 GVariant *sca = NULL, *packet_sca = NULL;
871                 GVariantBuilder b;
872                 unsigned int i;
873
874                 dbg("[%s] GET_SCA (result:[0x%x])", cpname, resp->result);
875
876                 g_variant_builder_init(&b, G_VARIANT_TYPE("ay"));
877                 for (i = 0; i < SMS_SMSP_ADDRESS_LEN + 1; i++)
878                         g_variant_builder_add(&b, "y", resp->scaAddress.diallingNum[i]);
879                 sca = g_variant_builder_end(&b);
880
881                 packet_sca = g_variant_new("v", sca);
882
883                 telephony_sms_complete_get_sca(dbus_info->interface_object,
884                         dbus_info->invocation, resp->result,
885                         resp->scaAddress.typeOfNum,
886                         resp->scaAddress.numPlanId,
887                         resp->scaAddress.dialNumLen,
888                         packet_sca);
889         }
890         break;
891
892         case TRESP_SMS_SET_SCA: {
893                 const struct tresp_sms_set_sca *resp = data;
894
895                 dbg("[%s] SET_SCA (result:[0x%x])", cpname, resp->result);
896
897                 telephony_sms_complete_set_sca(dbus_info->interface_object, dbus_info->invocation,
898                         resp->result);
899         }
900         break;
901
902         case TRESP_SMS_GET_CB_CONFIG: {
903                 const struct tresp_sms_get_cb_config *resp = data;
904                 GVariant *result = NULL;
905                 GVariantBuilder b;
906                 int i;
907
908                 dbg("[%s] GET_CB_CONFIG (result:[0x%x])", cpname, resp->result);
909
910                 g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}"));
911                 for (i = 0; i < resp->cbConfig.msgIdRangeCount; i++) {
912                         g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}"));
913
914                         if (resp->cbConfig.net3gppType == SMS_NETTYPE_3GPP) {
915                                 g_variant_builder_add(&b, "{sv}", "FromMsgId",
916                                         g_variant_new_uint16(resp->cbConfig.msgIDs[i].net3gpp.fromMsgId));
917                                 g_variant_builder_add(&b, "{sv}", "ToMsgId",
918                                         g_variant_new_uint16(resp->cbConfig.msgIDs[i].net3gpp.toMsgId));
919                         } else if (resp->cbConfig.net3gppType == SMS_NETTYPE_3GPP2) {
920                                 g_variant_builder_add(&b, "{sv}", "CBCategory",
921                                         g_variant_new_uint16(resp->cbConfig.msgIDs[i].net3gpp2.cbCategory));
922                                 g_variant_builder_add(&b, "{sv}", "CBLanguage",
923                                         g_variant_new_uint16(resp->cbConfig.msgIDs[i].net3gpp2.cbLanguage));
924                         } else {
925                                 dbg("Unknown 3gpp type");
926                                 return FALSE;
927                         }
928
929                         g_variant_builder_add(&b, "{sv}", "Selected",
930                                 g_variant_new_byte(resp->cbConfig.msgIDs[i].net3gpp.selected));
931                         g_variant_builder_close(&b);
932                 }
933                 result = g_variant_builder_end(&b);
934
935                 telephony_sms_complete_get_cb_config(dbus_info->interface_object,
936                         dbus_info->invocation, resp->result,
937                         resp->cbConfig.net3gppType,
938                         resp->cbConfig.cbEnabled,
939                         resp->cbConfig.msgIdMaxCount,
940                         resp->cbConfig.msgIdRangeCount,
941                         result);
942         }
943         break;
944
945         case TRESP_SMS_SET_CB_CONFIG: {
946                 const struct tresp_sms_set_cb_config *resp = data;
947
948                 dbg("[%s] SET_CB_CONFIG (result:[0x%x])", cpname, resp->result);
949
950                 telephony_sms_complete_set_cb_config(dbus_info->interface_object,
951                         dbus_info->invocation, resp->result);
952         }
953         break;
954
955         case TRESP_SMS_SET_MEM_STATUS: {
956                 const struct tresp_sms_set_mem_status *resp = data;
957
958                 dbg("[%s] SET_MEM_STATUS (result:[0x%x])", cpname, resp->result);
959
960                 telephony_sms_complete_set_mem_status(dbus_info->interface_object,
961                         dbus_info->invocation, resp->result);
962         }
963         break;
964
965         case TRESP_SMS_GET_PREF_BEARER: {
966                 const struct tresp_sms_get_pref_bearer *resp = data;
967
968                 dbg("[%s] GET_PREF_BEARER (result:[0x%x] svc:[0x%2x])", cpname, resp->result, resp->svc);
969
970                 telephony_sms_complete_get_pref_bearer(dbus_info->interface_object,
971                         dbus_info->invocation, resp->result, resp->svc);
972         }
973         break;
974
975         case TRESP_SMS_SET_PREF_BEARER: {
976                 const struct tresp_sms_set_pref_bearer *resp = data;
977
978                 dbg("[%s] SET_PREF_BEARER (result:[0x%x])", cpname, resp->result);
979
980                 telephony_sms_complete_set_pref_bearer(dbus_info->interface_object,
981                         dbus_info->invocation, resp->result);
982         }
983         break;
984
985         case TRESP_SMS_SET_DELIVERY_REPORT: {
986                 const struct tresp_sms_set_delivery_report *resp = data;
987
988                 dbg("[%s] SET_DELIVERY_REPORT (result:[0x%x])", cpname, resp->result);
989
990                 telephony_sms_complete_set_delivery_report(dbus_info->interface_object,
991                         dbus_info->invocation, resp->result);
992         }
993         break;
994
995         case TRESP_SMS_SET_MSG_STATUS: {
996                 const struct tresp_sms_set_mem_status *resp = data;
997
998                 dbg("[%s] SET_MSG_STATUS (result:[0x%x])", cpname, resp->result);
999
1000                 telephony_sms_complete_set_msg_status(dbus_info->interface_object,
1001                         dbus_info->invocation, resp->result);
1002         }
1003         break;
1004
1005         case TRESP_SMS_GET_PARAMS: {
1006                 const struct tresp_sms_get_params *resp = data;
1007                 GVariant *alphaId = NULL, *packet_alphaId = NULL;
1008                 GVariant *destDialNum = NULL, *packet_destDialNum = NULL;
1009                 GVariant *scaDialNum = NULL, *packet_scaDialNum = NULL;
1010                 GVariantBuilder b;
1011                 unsigned int i;
1012
1013                 dbg("[%s] GET_PARAMS (result:[0x%x])", cpname, resp->result);
1014
1015                 g_variant_builder_init(&b, G_VARIANT_TYPE("ay"));
1016                 for (i = 0; i < SMS_SMSP_ALPHA_ID_LEN_MAX + 1; i++)
1017                         g_variant_builder_add(&b, "y", resp->paramsInfo.szAlphaId[i]);
1018                 alphaId = g_variant_builder_end(&b);
1019
1020                 g_variant_builder_init(&b, G_VARIANT_TYPE("ay"));
1021                 for (i = 0; i < SMS_SMSP_ADDRESS_LEN + 1; i++)
1022                         g_variant_builder_add(&b, "y", resp->paramsInfo.tpDestAddr.diallingNum[i]);
1023                 destDialNum = g_variant_builder_end(&b);
1024
1025                 g_variant_builder_init(&b, G_VARIANT_TYPE("ay"));
1026                 for (i = 0; i < SMS_SMSP_ADDRESS_LEN + 1; i++)
1027                         g_variant_builder_add(&b, "y", resp->paramsInfo.tpSvcCntrAddr.diallingNum[i]);
1028                 scaDialNum = g_variant_builder_end(&b);
1029
1030                 packet_alphaId = g_variant_new("v", alphaId);
1031                 packet_destDialNum = g_variant_new("v", destDialNum);
1032                 packet_scaDialNum = g_variant_new("v", scaDialNum);
1033
1034                 telephony_sms_complete_get_sms_params(dbus_info->interface_object,
1035                         dbus_info->invocation, resp->result,
1036                         resp->paramsInfo.recordIndex,
1037                         resp->paramsInfo.recordLen,
1038                         resp->paramsInfo.alphaIdLen,
1039                         packet_alphaId,
1040                         resp->paramsInfo.paramIndicator,
1041                         resp->paramsInfo.tpDestAddr.dialNumLen,
1042                         resp->paramsInfo.tpDestAddr.typeOfNum,
1043                         resp->paramsInfo.tpDestAddr.numPlanId,
1044                         packet_destDialNum,
1045                         resp->paramsInfo.tpSvcCntrAddr.dialNumLen,
1046                         resp->paramsInfo.tpSvcCntrAddr.typeOfNum,
1047                         resp->paramsInfo.tpSvcCntrAddr.numPlanId,
1048                         packet_scaDialNum,
1049                         resp->paramsInfo.tpProtocolId,
1050                         resp->paramsInfo.tpDataCodingScheme,
1051                         resp->paramsInfo.tpValidityPeriod);
1052         }
1053         break;
1054
1055         case TRESP_SMS_SET_PARAMS:{
1056                 const struct tresp_sms_set_params *resp = data;
1057
1058                 dbg("[%s] SET_PARAMS (result:[0x%x])", cpname, resp->result);
1059
1060                 telephony_sms_complete_set_sms_params(dbus_info->interface_object,
1061                         dbus_info->invocation, resp->result);
1062         }
1063         break;
1064
1065         case TRESP_SMS_GET_PARAMCNT: {
1066                 const struct tresp_sms_get_paramcnt *resp = data;
1067
1068                 dbg("[%s] GET_PARAMCNT (result:[0x%x])", cpname, resp->result);
1069
1070                 telephony_sms_complete_get_sms_param_cnt(dbus_info->interface_object,
1071                         dbus_info->invocation, resp->result, resp->recordCount);
1072         }
1073         break;
1074
1075         default:
1076                 err("Unhandled/Unknown Response: [0x%x]", command);
1077         break;
1078         }
1079
1080         return TRUE;
1081 }
1082
1083 gboolean dbus_plugin_sms_notification(struct custom_data *ctx,
1084         CoreObject *source, TelephonyObjectSkeleton *object,
1085         enum tcore_notification_command command, unsigned int data_len, const void *data)
1086 {
1087         TelephonySms *sms;
1088         const char *cp_name;
1089
1090         if (!object) {
1091                 warn("object is NULL");
1092                 return FALSE;
1093         }
1094
1095         cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
1096
1097         sms = telephony_object_peek_sms(TELEPHONY_OBJECT(object));
1098         if (sms == NULL) {
1099                 err("sms object is NULL!!!");
1100                 return FALSE;
1101         }
1102
1103         switch (command) {
1104         case TNOTI_SMS_INCOM_MSG: {
1105                 const struct tnoti_sms_incoming_msg *noti = data;
1106                 gchar *sca = NULL;
1107                 gchar *tpdu = NULL;
1108
1109                 info("[%s] SMS_INCOM_MSG (len[%d])", cp_name, data_len);
1110
1111                 sca = g_base64_encode((const guchar *)(noti->msgInfo.sca), SMS_SMSP_ADDRESS_LEN);
1112                 tpdu = g_base64_encode((const guchar *)(noti->msgInfo.tpduData), SMS_SMDATA_SIZE_MAX + 1);
1113
1114                 telephony_sms_emit_incomming_msg(sms,
1115                         noti->msgInfo.format,
1116                         sca,
1117                         noti->msgInfo.msgLength,
1118                         tpdu);
1119
1120                 g_free(sca);
1121                 g_free(tpdu);
1122         }
1123         break;
1124
1125         case TNOTI_SMS_CB_INCOM_MSG: {
1126                 const struct tnoti_sms_cellBroadcast_msg *noti = data;
1127                 gchar *tpdu = NULL;
1128
1129                 info("[%s] SMS_CB_INCOM_MSG (len[%d])", cp_name, data_len);
1130
1131                 tpdu = g_base64_encode((const guchar*)(noti->cbMsg.msgData), SMS_CB_SIZE_MAX+1);
1132
1133                 telephony_sms_emit_incomming_cb_msg(sms,
1134                         noti->cbMsg.cbMsgType,
1135                         noti->cbMsg.length,
1136                         tpdu);
1137
1138                 g_free(tpdu);
1139         }
1140         break;
1141
1142         case TNOTI_SMS_ETWS_INCOM_MSG: {
1143                 const struct tnoti_sms_etws_msg *noti = data;
1144                 GVariant *msg_data = NULL, *packet_msg_data = NULL;
1145                 GVariantBuilder b;
1146                 unsigned int i;
1147
1148                 info("[%s] ETWS_INCOM_MSG (len[%d])", cp_name, data_len);
1149
1150                 g_variant_builder_init(&b, G_VARIANT_TYPE("ay"));
1151
1152                 for (i = 0; i < SMS_ETWS_SIZE_MAX + 1; i++)
1153                         g_variant_builder_add(&b, "y", noti->etwsMsg.msgData[i]);
1154                 msg_data = g_variant_builder_end(&b);
1155                 packet_msg_data = g_variant_new("v", msg_data);
1156
1157                 telephony_sms_emit_incomming_etws_msg(sms,
1158                         noti->etwsMsg.etwsMsgType,
1159                         noti->etwsMsg.length,
1160                         packet_msg_data);
1161         }
1162         break;
1163
1164         case TNOTI_SMS_INCOM_EX_MSG: {
1165                 info("[%s] SMS_INCOM_EX_MSG (len[%d])", cp_name, data_len);
1166         }
1167         break;
1168
1169         case TNOTI_SMS_CB_INCOM_EX_MSG: {
1170                 info("[%s] CB_INCOM_EX_MSG (len[%d])", cp_name, data_len);
1171         }
1172         break;
1173
1174         case TNOTI_SMS_MEMORY_STATUS: {
1175                 const struct tnoti_sms_memory_status *noti = data;
1176
1177                 info("[%s] SMS_MEMORY_STATUS (%d)", cp_name, noti->status);
1178
1179                 telephony_sms_emit_memory_status(sms, noti->status);
1180         }
1181         break;
1182
1183         case TNOTI_SMS_DEVICE_READY: {
1184                 const struct tnoti_sms_ready_status *noti = data;
1185
1186                 info("[%s] SMS_DEVICE_READY (%d)", cp_name, noti->status);
1187
1188 #ifdef ENABLE_KPI_LOGS
1189                 if (noti->status != SMS_READY_STATUS_NONE)
1190                         TIME_CHECK("[%s] SMS Service Ready", cp_name);
1191 #endif
1192
1193                 telephony_sms_emit_sms_ready(sms, noti->status);
1194         }
1195         break;
1196
1197         default:
1198                 err("Unhandled/Unknown Notification: [0x%x]", command);
1199         break;
1200         }
1201
1202         return TRUE;
1203 }