50
/* This is a straightforward copy of the EF_smsp structure */
63
/* Sub-block used by PN_SMS */
87
uint8_t cseg; /* Current segment */
88
uint8_t tseg; /* Total segments */
50
103
GIsiClient *client;
52
/* This is a straightforward copy of the EF_smsp structure */
53
struct sim_parameters {
105
struct sim_efsmsp params;
66
static gboolean sca_query_resp_cb(GIsiClient *client,
67
const void *restrict data, size_t len,
68
uint16_t object, void *opaque)
70
const uint8_t *msg = data;
71
struct isi_cb_data *cbd = opaque;
108
static gboolean check_sim_status(const GIsiMessage *msg, uint8_t msgid,
114
if (g_isi_msg_error(msg) < 0) {
115
DBG("Error: %s", strerror(-g_isi_msg_error(msg)));
119
if (g_isi_msg_id(msg) != msgid) {
120
DBG("Unexpected msg: %s",
121
sms_message_id_name(g_isi_msg_id(msg)));
125
if (!g_isi_msg_data_get_byte(msg, 0, &type))
128
if (type != service) {
129
DBG("Unexpected service type: 0x%02X", type);
133
if (!g_isi_msg_data_get_byte(msg, 1, &cause))
136
if (cause != SIM_SERV_OK) {
137
DBG("Request failed: %s", sim_isi_cause_name(cause));
144
static gboolean check_sms_status(const GIsiMessage *msg, uint8_t msgid)
148
if (g_isi_msg_error(msg) < 0) {
149
DBG("Error: %s", strerror(-g_isi_msg_error(msg)));
153
if (g_isi_msg_id(msg) != msgid) {
154
DBG("Unexpected msg: %s",
155
sms_message_id_name(g_isi_msg_id(msg)));
159
if (!g_isi_msg_data_get_byte(msg, 0, &cause)) {
160
DBG("Unable to parse cause");
167
if (cause == SMS_ERR_PP_RESERVED) {
168
DBG("Request failed: 0x%02"PRIx8" (%s).\n\n Unable to "
169
"bootstrap SMS routing.\n It appears some other "
170
"component is already\n registered as the SMS "
171
"routing endpoint.\n As a consequence, "
172
"only sending SMSs is going to work.\n\n",
173
cause, sms_isi_cause_name(cause));
177
DBG("Request failed: %s", sms_isi_cause_name(cause));
181
static void sca_query_resp_cb(const GIsiMessage *msg, void *data)
183
struct isi_cb_data *cbd = data;
72
184
struct ofono_sms *sms = cbd->user;
73
185
struct sms_data *sd = ofono_sms_get_data(sms);
74
186
ofono_sms_sca_query_cb_t cb = cbd->cb;
76
188
struct ofono_phone_number sca;
189
struct sms_params *info;
190
size_t len = sizeof(struct sms_params);
94
DBG("ISI client error: %d", g_isi_client_error(client));
98
if (len < 31 || msg[0] != SIM_SMS_RESP || msg[1] != READ_PARAMETER)
101
if (msg[3] != SIM_SERV_OK)
104
memset(¶ms, 0, sizeof(params));
105
if (len > 3 + sizeof(params))
106
len = 3 + sizeof(params);
107
memcpy(¶ms, msg + 3, len - 3);
109
if (params.alphalen > 17)
110
params.alphalen = 17;
111
else if (params.alphalen < 1)
113
params.alpha[params.alphalen - 1] = '\0';
115
sd->params.absent = params.absent;
116
sd->params.tp_pid = params.tp_pid;
117
sd->params.tp_dcs = params.tp_dcs;
118
sd->params.tp_vp = params.tp_vp;
119
memcpy(sd->params.dst, params.dst, sizeof(sd->params.dst));
120
memcpy(sd->params.sca, params.sca, sizeof(sd->params.sca));
121
sd->params.alphalen = params.alphalen;
122
memcpy(sd->params.alpha, params.alpha, sizeof(sd->params.alpha));
193
if (!check_sim_status(msg, SIM_SMS_RESP, READ_PARAMETER))
196
if (!g_isi_msg_data_get_struct(msg, 2, (const void **) &info, len))
199
if (info->alphalen > 17)
201
else if (info->alphalen < 1)
204
info->alpha[info->alphalen - 1] = '\0';
206
sd->params.absent = info->absent;
207
sd->params.tp_pid = info->tp_pid;
208
sd->params.tp_dcs = info->tp_dcs;
209
sd->params.tp_vp = info->tp_vp;
211
memcpy(sd->params.dst, info->dst, sizeof(sd->params.dst));
212
memcpy(sd->params.sca, info->sca, sizeof(sd->params.sca));
214
sd->params.alphalen = info->alphalen;
215
memcpy(sd->params.alpha, info->alpha, sizeof(sd->params.alpha));
125
* Bitmask indicating absense of parameters --
218
* Bitmask indicating absence of parameters --
126
219
* If second bit is set it indicates that the SCA is absent
128
if (params.absent & 0x2)
131
bcd_len = params.sca[0];
133
if (bcd_len <= 1 || bcd_len > 12)
136
extract_bcd_number(params.sca + 2, bcd_len - 1, sca.number);
137
sca.type = 0x80 | params.sca[1];
221
if (info->absent & 0x2)
224
bcd_len = info->sca[0];
226
if (bcd_len == 0 || bcd_len > 12)
229
extract_bcd_number(info->sca + 2, bcd_len - 1, sca.number);
230
sca.type = 0x80 | info->sca[1];
139
232
CALLBACK_WITH_SUCCESS(cb, &sca, cbd->data);
143
236
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
147
239
static void isi_sca_query(struct ofono_sms *sms,
236
static gboolean submit_resp_cb(GIsiClient *client,
237
const void *restrict data, size_t len,
238
uint16_t object, void *opaque)
313
static void submit_resp_cb(const GIsiMessage *msg, void *data)
240
const uint8_t *msg = data;
241
struct isi_cb_data *cbd = opaque;
315
struct isi_cb_data *cbd = data;
242
316
ofono_sms_submit_cb_t cb = cbd->cb;
317
struct sms_report *report;
318
size_t len = sizeof(struct sms_report);
245
319
GIsiSubBlockIter iter;
248
DBG("ISI client error: %d", g_isi_client_error(client));
252
if (len < 3 || msg[0] != SMS_MESSAGE_SEND_RESP)
255
for (g_isi_sb_iter_init(&iter, msg, len, 3);
256
g_isi_sb_iter_is_valid(&iter);
257
g_isi_sb_iter_next(&iter)) {
263
switch (g_isi_sb_iter_get_id(&iter)) {
267
if (!g_isi_sb_iter_get_byte(&iter, &type, 2)
268
|| !g_isi_sb_iter_get_byte(&iter, &cause, 3)
269
|| !g_isi_sb_iter_get_byte(&iter, &ref, 4))
273
DBG("Submit error: 0x%"PRIx8" (type 0x%"PRIx8")",
278
DBG("cause=0x%"PRIx8", type 0x%"PRIx8", mr=0x%"PRIx8,
285
DBG("skipped sub-block: %s (%zu bytes)",
286
sms_subblock_name(g_isi_sb_iter_get_id(&iter)),
287
g_isi_sb_iter_get_len(&iter));
295
CALLBACK_WITH_SUCCESS(cb, mr, cbd->data);
321
if (!check_sms_status(msg, SMS_MESSAGE_SEND_RESP))
324
for (g_isi_sb_iter_init(&iter, msg, 2);
325
g_isi_sb_iter_is_valid(&iter);
326
g_isi_sb_iter_next(&iter)) {
328
if (g_isi_sb_iter_get_id(&iter) != SMS_GSM_REPORT)
331
if (!g_isi_sb_iter_get_struct(&iter, (void **) &report, len, 2))
334
if (report->cause != SMS_OK)
337
CALLBACK_WITH_SUCCESS(cb, report->ref, cbd->data);
299
342
CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
303
345
static void isi_submit(struct ofono_sms *sms, unsigned char *pdu,
372
static void send_status_ind_cb(GIsiClient *client,
373
const void *restrict data, size_t len,
374
uint16_t object, void *opaque)
376
const uint8_t *msg = data;
378
if (!msg || len < 6 || msg[0] != SMS_MESSAGE_SEND_STATUS_IND)
381
DBG("status=0x%"PRIx8", mr=0x%"PRIx8", route=0x%"PRIx8
417
static void isi_bearer_query(struct ofono_sms *sms,
418
ofono_sms_bearer_query_cb_t cb, void *data)
420
DBG("Not implemented");
421
CALLBACK_WITH_FAILURE(cb, -1, data);
424
static void isi_bearer_set(struct ofono_sms *sms, int bearer,
425
ofono_sms_bearer_set_cb_t cb, void *data)
427
DBG("Not implemented");
428
CALLBACK_WITH_FAILURE(cb, data);
431
static void send_status_ind_cb(const GIsiMessage *msg, void *data)
433
struct sms_status *info;
434
size_t len = sizeof(struct sms_status);
438
if (g_isi_msg_id(msg) != SMS_MESSAGE_SEND_STATUS_IND)
441
if (!g_isi_msg_data_get_struct(msg, 0, (const void **) &info, len))
444
DBG("status=0x%"PRIx8", ref=0x%"PRIx8", route=0x%"PRIx8
382
445
", cseg=0x%"PRIx8", tseg=0x%"PRIx8,
383
msg[1], msg[2], msg[3], msg[4], msg[5]);
446
info->status, info->ref, info->route, info->cseg,
385
449
DBG("TODO: Status notification");
388
static gboolean report_resp_cb(GIsiClient *client,
389
const void *restrict data, size_t len,
390
uint16_t object, void *opaque)
452
static void report_resp_cb(const GIsiMessage *msg, void *data)
392
const uint8_t *msg = data;
395
DBG("ISI client error: %d", g_isi_client_error(client));
399
if (len < 3 || msg[0] != SMS_GSM_RECEIVED_PP_REPORT_RESP)
402
DBG("Report resp cause=0x%"PRIx8, msg[1]);
456
if (g_isi_msg_error(msg) < 0)
459
if (g_isi_msg_id(msg) != SMS_GSM_RECEIVED_PP_REPORT_RESP)
462
if (!g_isi_msg_data_get_byte(msg, 0, &cause))
465
DBG("Report resp cause=0x%"PRIx8, cause);
407
468
static gboolean send_deliver_report(GIsiClient *client, gboolean success)
422
483
0, 0, 0, /* Filler */
423
484
0, /* Sub blocks */
426
return g_isi_send(client, msg, sizeof(msg), SMS_TIMEOUT,
427
report_resp_cb, NULL, NULL) != NULL;
430
static void routing_ntf_cb(GIsiClient *client,
431
const void *restrict data, size_t len,
432
uint16_t object, void *opaque)
434
const uint8_t *msg = data;
435
struct ofono_sms *sms = opaque;
486
size_t len = sizeof(msg);
488
return g_isi_client_send(client, msg, len, report_resp_cb, NULL, NULL);
491
static gboolean parse_sms_address(GIsiSubBlockIter *iter, struct sms_addr *add)
495
if (!g_isi_sb_iter_get_byte(iter, &add->type, 2))
498
if (!g_isi_sb_iter_get_byte(iter, &add->len, 3))
504
if (!g_isi_sb_iter_get_struct(iter, (void **) &add->data, add->len, 4))
510
static gboolean parse_sms_tpdu(GIsiSubBlockIter *iter, struct sms_common *com)
514
if (!g_isi_sb_iter_get_byte(iter, &com->len, 2))
520
if (!g_isi_sb_iter_get_struct(iter, (void **) &com->data, com->len, 4))
526
static gboolean parse_gsm_tpdu(GIsiSubBlockIter *parent, struct sms_addr *add,
527
struct sms_common *com)
436
529
GIsiSubBlockIter iter;
440
uint8_t *tpdu = NULL;
441
uint8_t tpdu_len = 0;
443
unsigned char pdu[176];
445
if (!msg || len < 7 || msg[0] != SMS_PP_ROUTING_NTF
446
|| msg[3] != SMS_GSM_TPDU)
449
for (g_isi_sb_iter_init(&iter, msg, len, 7);
450
g_isi_sb_iter_is_valid(&iter);
451
g_isi_sb_iter_next(&iter)) {
531
for (g_isi_sb_subiter_init(parent, &iter, 2);
532
g_isi_sb_iter_is_valid(&iter);
533
g_isi_sb_iter_next(&iter)) {
453
535
switch (g_isi_sb_iter_get_id(&iter)) {
459
536
case SMS_ADDRESS:
461
if (!g_isi_sb_iter_get_byte(&iter, &type, 2)
462
|| !g_isi_sb_iter_get_byte(&iter, &data_len, 3)
463
|| !g_isi_sb_iter_get_data(&iter, &data, 4)
464
|| type != SMS_GSM_0411_ADDRESS)
538
if (!parse_sms_address(&iter, add))
541
if (add->type != SMS_GSM_0411_ADDRESS)
471
546
case SMS_COMMON_DATA:
473
if (!g_isi_sb_iter_get_byte(&iter, &data_len, 2)
474
|| !g_isi_sb_iter_get_data(&iter, &data, 4))
548
if (!parse_sms_tpdu(&iter, com))
482
DBG("skipped sub-block: %s (%zu bytes)",
483
sms_subblock_name(g_isi_sb_iter_get_id(&iter)),
484
g_isi_sb_iter_get_len(&iter));
488
if (!tpdu || !sca || tpdu_len + sca_len > sizeof(pdu))
491
memcpy(pdu, sca, sca_len);
492
memcpy(pdu + sca_len, tpdu, tpdu_len);
494
ofono_sms_deliver_notify(sms, pdu, tpdu_len + sca_len, tpdu_len);
496
/* FIXME: We should not ack the DELIVER unless it has been
558
static void routing_ntf_cb(const GIsiMessage *msg, void *data)
560
struct ofono_sms *sms = data;
561
struct sms_data *sd = ofono_sms_get_data(sms);
562
struct sms_common tpdu;
563
struct sms_addr addr;
564
GIsiSubBlockIter iter;
568
if (g_isi_msg_id(msg) != SMS_PP_ROUTING_NTF)
571
for (g_isi_sb_iter_init(&iter, msg, 2);
572
g_isi_sb_iter_is_valid(&iter);
573
g_isi_sb_iter_next(&iter)) {
575
if (g_isi_sb_iter_get_id(&iter) != SMS_GSM_TPDU)
578
if (!parse_gsm_tpdu(&iter, &addr, &tpdu))
582
if (tpdu.data == NULL || addr.data == NULL ||
583
tpdu.len + addr.len > sizeof(pdu))
586
memcpy(pdu, addr.data, addr.len);
587
memcpy(pdu + addr.len, tpdu.data, tpdu.len);
589
ofono_sms_deliver_notify(sms, pdu, tpdu.len + addr.len, tpdu.len);
592
* FIXME: We should not ack the DELIVER unless it has been
497
593
* reliably stored, i.e., written to disk. Currently, there is
498
594
* no such indication from core, so we just blindly trust that
499
* it did The Right Thing here. */
500
send_deliver_report(client, TRUE);
595
* it did The Right Thing here.
597
send_deliver_report(sd->client, TRUE);
503
static gboolean routing_resp_cb(GIsiClient *client,
504
const void *restrict data, size_t len,
505
uint16_t object, void *opaque)
600
static void routing_resp_cb(const GIsiMessage *msg, void *data)
507
const unsigned char *msg = data;
508
struct ofono_sms *sms = opaque;
511
DBG("ISI client error: %d", g_isi_client_error(client));
515
if (len < 3 || msg[0] != SMS_PP_ROUTING_RESP)
518
if (msg[1] != SMS_OK) {
520
if (msg[1] == SMS_ERR_PP_RESERVED) {
521
DBG("Request failed: 0x%02"PRIx8" (%s).\n\n "
522
"Unable to bootstrap SMS routing.\n "
523
"It appears some other component is "
524
"already\n registered as the SMS "
525
"routing endpoint.\n As a consequence, "
526
"receiving SMSs is NOT going to work.\n "
527
"On the other hand, sending might work.\n\n",
528
msg[1], sms_isi_cause_name(msg[1]));
529
ofono_sms_register(sms);
534
g_isi_subscribe(client, SMS_PP_ROUTING_NTF, routing_ntf_cb, sms);
602
struct ofono_sms *sms = data;
603
struct sms_data *sd = ofono_sms_get_data(sms);
605
if (!check_sms_status(msg, SMS_PP_ROUTING_RESP))
608
g_isi_client_ntf_subscribe(sd->client, SMS_PP_ROUTING_NTF,
609
routing_ntf_cb, sms);
536
611
ofono_sms_register(sms);
540
DBG("Unable to bootstrap SMS routing.");
614
static void sim_reachable_cb(const GIsiMessage *msg, void *data)
616
struct ofono_sms *sms = data;
617
struct sms_data *sd = ofono_sms_get_data(sms);
619
const uint8_t req[] = {
622
0x01, /* Sub-block count */
624
0x08, /* Sub-block length */
625
SMS_GSM_TPDU_ROUTING,
627
0x00, 0x00, 0x00, /* Filler */
628
0x00 /* Sub-sub-block count */
630
size_t len = sizeof(req);
632
if (g_isi_msg_error(msg) < 0) {
633
DBG("unable to find SIM resource");
634
g_isi_client_destroy(sd->sim);
638
g_isi_client_ind_subscribe(sd->client, SMS_MESSAGE_SEND_STATUS_IND,
639
send_status_ind_cb, sms);
640
g_isi_client_send(sd->client, req, len, routing_resp_cb, sms, NULL);
643
static void sms_reachable_cb(const GIsiMessage *msg, void *data)
645
struct ofono_sms *sms = data;
646
struct sms_data *sd = ofono_sms_get_data(sms);
648
if (g_isi_msg_error(msg) < 0) {
649
DBG("unable to find SMS resource");
653
ISI_VERSION_DBG(msg);
655
g_isi_client_verify(sd->sim, sim_reachable_cb, sms, NULL);
544
658
static int isi_sms_probe(struct ofono_sms *sms, unsigned int vendor,
547
GIsiModem *idx = user;
548
struct sms_data *data = g_try_new0(struct sms_data, 1);
551
const unsigned char msg[] = {
554
0x01, /* Sub-block count */
556
0x08, /* Sub-block length */
557
SMS_GSM_TPDU_ROUTING,
559
0x00, 0x00, 0x00, /* Filler */
560
0x00 /* Sub-sub-block count */
566
data->params.absent = 0xff;
567
data->params.alphalen = 1; /* Includes final UCS2-coded NUL */
569
data->client = g_isi_client_create(idx, PN_SMS);
573
data->sim = g_isi_client_create(idx, PN_SIM);
575
g_isi_client_destroy(data->client);
579
ofono_sms_set_data(sms, data);
581
debug = getenv("OFONO_ISI_DEBUG");
582
if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "sms") == 0)) {
583
g_isi_client_set_debug(data->client, sms_debug, NULL);
584
g_isi_client_set_debug(data->sim, sim_debug, NULL);
587
g_isi_subscribe(data->client, SMS_MESSAGE_SEND_STATUS_IND,
588
send_status_ind_cb, sms);
589
if (!g_isi_send(data->client, msg, sizeof(msg), SMS_TIMEOUT,
590
routing_resp_cb, sms, NULL))
591
DBG("Failed to set SMS routing.");
661
GIsiModem *modem = user;
662
struct sms_data *sd = g_try_new0(struct sms_data, 1);
667
sd->params.absent = 0xFF;
668
sd->params.alphalen = 1; /* Includes final UCS2-coded NUL */
670
sd->client = g_isi_client_create(modem, PN_SMS);
671
if (sd->client == NULL)
674
sd->sim = g_isi_client_create(modem, PN_SIM);
678
g_isi_client_set_timeout(sd->client, SMS_TIMEOUT);
679
g_isi_client_set_timeout(sd->sim, SIM_TIMEOUT);
681
ofono_sms_set_data(sms, sd);
683
g_isi_client_verify(sd->client, sms_reachable_cb, sms, NULL);
688
g_isi_client_destroy(sd->client);
596
693
static void isi_sms_remove(struct ofono_sms *sms)
598
struct sms_data *data = ofono_sms_get_data(sms);
695
struct sms_data *sd = ofono_sms_get_data(sms);
600
const unsigned char msg[] = {
697
const uint8_t msg[] = {
601
698
SMS_PP_ROUTING_REQ,
602
699
SMS_ROUTING_RELEASE,
603
700
0x01, /* Sub-block count */