86
103
for (i = 0; i < N; i++) {
87
104
if (fileid == info[i].fileid) {
88
cbd = isi_cb_data_new((void *)&info[i], cb, data);
105
cbd = isi_cb_data_new((void *) &info[i], cb, data);
89
106
g_idle_add(fake_file_info, cbd);
94
DBG("Not implemented (fileid = %04x)", fileid);
111
DBG("Fileid %04X not implemented", fileid);
95
112
CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL, 0, data);
98
static gboolean spn_resp_cb(GIsiClient *client,
99
const void *restrict data, size_t len,
100
uint16_t object, void *opaque)
102
const unsigned char *msg = data;
103
struct isi_cb_data *cbd = opaque;
115
static gboolean check_response_status(const GIsiMessage *msg, uint8_t msgid,
121
if (g_isi_msg_error(msg) < 0) {
122
DBG("Error: %s", strerror(-g_isi_msg_error(msg)));
126
if (g_isi_msg_id(msg) != msgid) {
127
DBG("Unexpected msg: %s",
128
sim_message_id_name(g_isi_msg_id(msg)));
132
if (!g_isi_msg_data_get_byte(msg, 1, &cause) || cause != SIM_SERV_OK) {
133
DBG("Request failed: %s", sim_isi_cause_name(cause));
137
if (!g_isi_msg_data_get_byte(msg, 0, &type) || type != service) {
138
DBG("Unexpected service: 0x%02X", type);
144
static void spn_resp_cb(const GIsiMessage *msg, void *data)
146
struct isi_cb_data *cbd = data;
104
147
ofono_sim_read_cb_t cb = cbd->cb;
105
unsigned char *spn = NULL;
106
unsigned char buffer[17];
149
const struct sim_spn *resp = NULL;
150
size_t len = sizeof(struct sim_spn);
152
uint8_t spn[SIM_MAX_SPN_LENGTH + 1];
110
DBG("ISI client error: %d", g_isi_client_error(client));
114
if (len < 39 || msg[0] != SIM_SERV_PROV_NAME_RESP
115
|| msg[1] != SIM_ST_READ_SERV_PROV_NAME)
118
if (msg[2] != SIM_SERV_OK) {
119
DBG("Request failed: %s (0x%02X)",
120
sim_isi_cause_name(msg[2]), msg[2]);
155
if (!check_response_status(msg, SIM_SERV_PROV_NAME_RESP,
156
SIM_ST_READ_SERV_PROV_NAME))
159
if (!g_isi_msg_data_get_struct(msg, 2, (const void **) &resp, len))
126
162
/* Set display condition bits */
127
spn[0] = ((msg[38] & 1) << 1) + (msg[37] & 1);
129
/* Dirty conversion from 16bit unicode to ascii */
130
for (i = 0; i < 16; i++) {
131
unsigned char c = msg[3 + i * 2 + 1];
163
spn[0] = (resp->disp_home & 0x01) | ((resp->disp_roam & 0x01) << 1);
165
/* Convert from a NULL-terminated UCS-2 string to ASCII */
166
for (i = 0; i < SIM_MAX_SPN_LENGTH; i++) {
167
uint16_t c = resp->name[i] >> 8 | resp->name[i] << 8;
134
171
else if (!g_ascii_isprint(c))
141
CALLBACK_WITH_SUCCESS(cb, spn, 17, cbd->data);
143
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
177
CALLBACK_WITH_SUCCESS(cb, spn, sizeof(spn), cbd->data);
181
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
149
184
static gboolean isi_read_spn(struct ofono_sim *sim, struct isi_cb_data *cbd)
151
186
struct sim_data *sd = ofono_sim_get_data(sim);
153
const unsigned char msg[] = {
188
const uint8_t msg[] = {
154
189
SIM_SERV_PROV_NAME_REQ,
155
190
SIM_ST_READ_SERV_PROV_NAME,
162
return g_isi_request_make(sd->client, msg, sizeof(msg),
163
SIM_TIMEOUT, spn_resp_cb, cbd) != NULL;
197
return g_isi_client_send(sd->client, msg, sizeof(msg),
198
spn_resp_cb, cbd, g_free);
166
static gboolean read_iccid_resp_cb(GIsiClient *client,
167
const void *restrict data, size_t len,
168
uint16_t object, void *user)
201
static void read_iccid_resp_cb(const GIsiMessage *msg, void *data)
170
struct isi_cb_data *cbd = user;
203
struct isi_cb_data *cbd = data;
171
204
ofono_sim_read_cb_t cb = cbd->cb;
172
const unsigned char *msg = data;
173
const unsigned char *iccid = NULL;
176
DBG("ISI client error: %d", g_isi_client_error(client));
180
if (len < 3 || msg[0] != SIM_READ_FIELD_RESP || msg[1] != ICC)
183
if (msg[2] == SIM_SERV_OK && len >= 13)
186
DBG("Error reading ICC ID");
190
CALLBACK_WITH_SUCCESS(cb, iccid, 10, cbd->data);
192
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
205
struct sim_iccid *icc;
206
size_t len = sizeof(struct sim_iccid);
208
if (!check_response_status(msg, SIM_READ_FIELD_RESP, ICC))
211
if (!g_isi_msg_data_get_struct(msg, 2, (const void **) &icc, len))
214
CALLBACK_WITH_SUCCESS(cb, icc->id, 10, cbd->data);
218
CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
198
221
static gboolean isi_read_iccid(struct ofono_sim *sim, struct isi_cb_data *cbd)
200
223
struct sim_data *sd = ofono_sim_get_data(sim);
201
const unsigned char req[] = { SIM_READ_FIELD_REQ, ICC };
225
const uint8_t req[] = {
206
return g_isi_request_make(sd->client, req, sizeof(req), SIM_TIMEOUT,
207
read_iccid_resp_cb, cbd) != NULL;
233
return g_isi_client_send(sd->client, req, sizeof(req),
234
read_iccid_resp_cb, cbd, g_free);
210
237
static void isi_read_file_transparent(struct ofono_sim *sim, int fileid,
211
238
int start, int length,
212
239
ofono_sim_read_cb_t cb, void *data)
214
struct isi_cb_data *cbd = isi_cb_data_new(sim, cb, data);
241
struct isi_cb_data *cbd;
216
DBG("fileid = %04x", fileid);
244
cbd = isi_cb_data_new(sim, cb, data);
218
248
switch (fileid) {
219
249
case SIM_EFSPN_FILEID:
221
if (isi_read_spn(sim, cbd))
250
done = isi_read_spn(sim, cbd);
225
253
case SIM_EF_ICCID_FILEID:
227
if (isi_read_iccid(sim, cbd))
254
done = isi_read_iccid(sim, cbd);
232
DBG("Not implemented (fileid = %04x)", fileid);
264
DBG("Fileid %04X not implemented", fileid);
235
267
CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
274
306
int length, const unsigned char *value,
275
307
ofono_sim_write_cb_t cb, void *data)
277
DBG("Not implemented (fileid = %04x)", fileid);
309
DBG("Fileid %04X not implemented", fileid);
278
310
CALLBACK_WITH_FAILURE(cb, data);
281
static gboolean imsi_resp_cb(GIsiClient *client,
282
const void *restrict data, size_t len,
283
uint16_t object, void *opaque)
313
static void imsi_resp_cb(const GIsiMessage *msg, void *data)
285
const unsigned char *msg = data;
286
struct isi_cb_data *cbd = opaque;
315
struct isi_cb_data *cbd = data;
287
316
ofono_sim_imsi_cb_t cb = cbd->cb;
318
struct sim_imsi *resp;
319
size_t len = sizeof(struct sim_imsi);
289
321
char imsi[SIM_MAX_IMSI_LENGTH + 1];
295
DBG("ISI client error: %d", g_isi_client_error(client));
299
if (len < 5 || msg[0] != SIM_IMSI_RESP_READ_IMSI)
302
if (msg[1] != READ_IMSI || msg[2] != SIM_SERV_OK)
306
if (octets != 8 || octets > len)
324
if (!check_response_status(msg, SIM_IMSI_RESP_READ_IMSI, READ_IMSI))
327
if (!g_isi_msg_data_get_struct(msg, 2, (const void **) &resp, len))
311
330
/* Ignore the low-order semi-octet of the first byte */
312
imsi[j] = ((msg[i] & 0xF0) >> 4) + '0';
314
for (i++, j++; i < octets && j < SIM_MAX_IMSI_LENGTH; i++) {
331
imsi[0] = ((resp->imsi[0] & 0xF0) >> 4) + '0';
333
for (i = 1, j = 1; i < resp->length && j < SIM_MAX_IMSI_LENGTH; i++) {
317
imsi[j++] = (msg[i] & 0x0F) + '0';
319
nibble = (msg[i] & 0xF0) >> 4;
336
imsi[j++] = (resp->imsi[i] & 0x0F) + '0';
337
nibble = (resp->imsi[i] & 0xF0) >> 4;
320
338
if (nibble != 0x0F)
321
339
imsi[j++] = nibble + '0';
325
343
CALLBACK_WITH_SUCCESS(cb, imsi, cbd->data);
329
347
CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
336
350
static void isi_read_imsi(struct ofono_sim *sim,
393
397
struct sim_data *sd = ofono_sim_get_data(sim);
395
const unsigned char req[] = {
399
const uint8_t req[] = {
396
400
SIM_NETWORK_INFO_REQ,
400
g_isi_request_make(sd->client, req, sizeof(req), SIM_TIMEOUT,
401
read_hplmn_resp_cb, sim);
403
size_t len = sizeof(req);
408
g_isi_client_send(sd->client, req, len, read_hplmn_resp_cb, sim, NULL);
404
static void sim_ind_cb(GIsiClient *client,
405
const void *restrict data, size_t len,
406
uint16_t object, void *opaque)
411
static void sim_ind_cb(const GIsiMessage *msg, void *data)
408
struct ofono_sim *sim = opaque;
413
struct ofono_sim *sim = data;
409
414
struct sim_data *sd = ofono_sim_get_data(sim);
410
const unsigned char *msg = data;
417
if (sd == NULL || g_isi_msg_id(msg) != SIM_IND || sd->registered)
420
if (!g_isi_msg_data_get_byte(msg, 0, &status))
417
425
isi_sim_register(sim);
419
428
case SIM_ST_INFO:
420
429
isi_read_hplmn(sim);
425
static void sim_reachable_cb(GIsiClient *client, gboolean alive,
426
uint16_t object, void *opaque)
434
static void sim_reachable_cb(const GIsiMessage *msg, void *data)
428
struct ofono_sim *sim = opaque;
436
struct ofono_sim *sim = data;
431
DBG("SIM client: %s", strerror(-g_isi_client_error(client)));
432
ofono_sim_remove(sim);
438
if (g_isi_msg_error(msg) < 0)
436
DBG("%s (v.%03d.%03d) reachable",
437
pn_resource_name(g_isi_client_resource(client)),
438
g_isi_version_major(client),
439
g_isi_version_minor(client));
441
g_isi_subscribe(client, SIM_IND, sim_ind_cb, opaque);
443
/* Check if SIM is ready. */
441
ISI_VERSION_DBG(msg);
443
/* Check if SIM is ready by reading HPLMN */
444
444
isi_read_hplmn(sim);
447
447
static int isi_sim_probe(struct ofono_sim *sim, unsigned int vendor,
450
GIsiModem *idx = user;
451
struct sim_data *sd = g_try_new0(struct sim_data, 1);
452
const char *debug = getenv("OFONO_ISI_DEBUG");
457
sd->client = g_isi_client_create(idx, PN_SIM);
450
GIsiModem *modem = user;
453
sd = g_try_new0(struct sim_data, 1);
457
sd->client = g_isi_client_create(modem, PN_SIM);
458
if (sd->client == NULL) {
461
463
ofono_sim_set_data(sim, sd);
463
if (debug && (strcmp(debug, "all") == 0 || strcmp(debug, "sim") == 0))
464
g_isi_client_set_debug(sd->client, sim_debug, NULL);
466
g_isi_verify(sd->client, sim_reachable_cb, sim);
465
g_isi_client_ind_subscribe(sd->client, SIM_IND, sim_ind_cb, sim);
466
g_isi_client_verify(sd->client, sim_reachable_cb, sim, NULL);