packaging: Bump to 1.17
[platform/upstream/ofono.git] / drivers / atmodem / sim.c
1 /*
2  *
3  *  oFono - Open Source Telephony
4  *
5  *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #define _GNU_SOURCE
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <errno.h>
31
32 #include <glib.h>
33
34 #include <ofono/log.h>
35 #include <ofono/modem.h>
36 #include <ofono/sim.h>
37
38 #include "gatchat.h"
39 #include "gatresult.h"
40 #include "simutil.h"
41 #include "vendor.h"
42
43 #include "atmodem.h"
44
45 #define EF_STATUS_INVALIDATED 0
46 #define EF_STATUS_VALID 1
47
48 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
49
50 struct sim_data {
51         GAtChat *chat;
52         unsigned int vendor;
53         guint ready_id;
54         struct at_util_sim_state_query *sim_state_query;
55 };
56
57 static const char *crsm_prefix[] = { "+CRSM:", NULL };
58 static const char *cpin_prefix[] = { "+CPIN:", NULL };
59 static const char *clck_prefix[] = { "+CLCK:", NULL };
60 static const char *huawei_cpin_prefix[] = { "^CPIN:", NULL };
61 static const char *xpincnt_prefix[] = { "+XPINCNT:", NULL };
62 static const char *zpinpuk_prefix[] = { "+ZPINPUK:", NULL };
63 static const char *pinnum_prefix[] = { "%PINNUM:", NULL };
64 static const char *oercn_prefix[] = { "_OERCN:", NULL };
65 static const char *cpinr_prefixes[] = { "+CPINR:", "+CPINRE:", NULL };
66 static const char *epin_prefix[] = { "*EPIN:", NULL };
67 static const char *spic_prefix[] = { "+SPIC:", NULL };
68 static const char *pct_prefix[] = { "#PCT:", NULL };
69 static const char *pnnm_prefix[] = { "+PNNM:", NULL };
70 static const char *qpinc_prefix[] = { "+QPINC:", NULL };
71 static const char *upincnt_prefix[] = { "+UPINCNT:", NULL };
72 static const char *none_prefix[] = { NULL };
73
74 static void at_crsm_info_cb(gboolean ok, GAtResult *result, gpointer user_data)
75 {
76         struct cb_data *cbd = user_data;
77         GAtResultIter iter;
78         ofono_sim_file_info_cb_t cb = cbd->cb;
79         struct ofono_error error;
80         const guint8 *response;
81         gint sw1, sw2, len;
82         int flen, rlen;
83         int str;
84         unsigned char access[3];
85         unsigned char file_status;
86
87         decode_at_error(&error, g_at_result_final_response(result));
88
89         if (!ok) {
90                 cb(&error, -1, -1, -1, NULL, EF_STATUS_INVALIDATED, cbd->data);
91                 return;
92         }
93
94         g_at_result_iter_init(&iter, result);
95
96         if (!g_at_result_iter_next(&iter, "+CRSM:"))
97                 goto error;
98
99         g_at_result_iter_next_number(&iter, &sw1);
100         g_at_result_iter_next_number(&iter, &sw2);
101
102         if (!g_at_result_iter_next_hexstring(&iter, &response, &len) ||
103                         (sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92) ||
104                         (sw1 == 0x90 && sw2 != 0x00)) {
105                 memset(&error, 0, sizeof(error));
106
107                 error.type = OFONO_ERROR_TYPE_SIM;
108                 error.error = (sw1 << 8) | sw2;
109
110                 cb(&error, -1, -1, -1, NULL, EF_STATUS_INVALIDATED, cbd->data);
111                 return;
112         }
113
114         DBG("crsm_info_cb: %02x, %02x, %i", sw1, sw2, len);
115
116         if (response[0] == 0x62) {
117                 ok = sim_parse_3g_get_response(response, len, &flen, &rlen,
118                                                 &str, access, NULL);
119
120                 file_status = EF_STATUS_VALID;
121         } else
122                 ok = sim_parse_2g_get_response(response, len, &flen, &rlen,
123                                                 &str, access, &file_status);
124
125         if (!ok)
126                 goto error;
127
128         cb(&error, flen, str, rlen, access, file_status, cbd->data);
129
130         return;
131
132 error:
133         CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL,
134                                 EF_STATUS_INVALIDATED, cbd->data);
135 }
136
137 static void at_sim_read_info(struct ofono_sim *sim, int fileid,
138                                 const unsigned char *path,
139                                 unsigned int path_len,
140                                 ofono_sim_file_info_cb_t cb, void *data)
141 {
142         struct sim_data *sd = ofono_sim_get_data(sim);
143         struct cb_data *cbd;
144         char buf[128];
145         unsigned int len;
146
147         if (sd->vendor == OFONO_VENDOR_OPTION_HSO) {
148                 unsigned char access[3] = { 0x00, 0x00, 0x00 };
149
150                 if (fileid == SIM_EFAD_FILEID) {
151                         CALLBACK_WITH_SUCCESS(cb, 4, 0, 0, access,
152                                                 EF_STATUS_VALID, data);
153                         return;
154                 }
155         }
156
157         cbd = cb_data_new(cb, data);
158
159         len = snprintf(buf, sizeof(buf), "AT+CRSM=192,%i", fileid);
160
161         switch (sd->vendor) {
162         default:
163                 if (path_len == 0)
164                         break;
165
166                 /* Fall through */
167         case OFONO_VENDOR_ZTE:
168         case OFONO_VENDOR_HUAWEI:
169         case OFONO_VENDOR_SIERRA:
170         case OFONO_VENDOR_SPEEDUP:
171         case OFONO_VENDOR_QUALCOMM_MSM:
172         case OFONO_VENDOR_SIMCOM:
173                 /* Maximum possible length */
174                 len += sprintf(buf + len, ",0,0,255");
175                 break;
176         }
177
178         if (path_len > 0) {
179                 len += sprintf(buf + len, ",,\"");
180
181                 for (; path_len; path_len--)
182                         len += sprintf(buf + len, "%02hhX", *path++);
183
184                 buf[len++] = '\"';
185                 buf[len] = '\0';
186         }
187
188         if (g_at_chat_send(sd->chat, buf, crsm_prefix,
189                                 at_crsm_info_cb, cbd, g_free) > 0)
190                 return;
191
192         g_free(cbd);
193
194         CALLBACK_WITH_FAILURE(cb, -1, -1, -1, NULL,
195                                 EF_STATUS_INVALIDATED, data);
196 }
197
198 static void at_crsm_read_cb(gboolean ok, GAtResult *result,
199                                 gpointer user_data)
200 {
201         struct cb_data *cbd = user_data;
202         GAtResultIter iter;
203         ofono_sim_read_cb_t cb = cbd->cb;
204         struct ofono_error error;
205         const guint8 *response;
206         gint sw1, sw2, len;
207
208         decode_at_error(&error, g_at_result_final_response(result));
209
210         if (!ok) {
211                 cb(&error, NULL, 0, cbd->data);
212                 return;
213         }
214
215         g_at_result_iter_init(&iter, result);
216
217         if (!g_at_result_iter_next(&iter, "+CRSM:")) {
218                 CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
219                 return;
220         }
221
222         g_at_result_iter_next_number(&iter, &sw1);
223         g_at_result_iter_next_number(&iter, &sw2);
224
225         if ((sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92 && sw1 != 0x9f) ||
226                         (sw1 == 0x90 && sw2 != 0x00)) {
227                 memset(&error, 0, sizeof(error));
228
229                 error.type = OFONO_ERROR_TYPE_SIM;
230                 error.error = (sw1 << 8) | sw2;
231
232                 cb(&error, NULL, 0, cbd->data);
233                 return;
234         }
235
236         if (!g_at_result_iter_next_hexstring(&iter, &response, &len)) {
237                 CALLBACK_WITH_FAILURE(cb, NULL, 0, cbd->data);
238                 return;
239         }
240
241         DBG("crsm_read_cb: %02x, %02x, %d", sw1, sw2, len);
242
243         cb(&error, response, len, cbd->data);
244 }
245
246 static void at_sim_read_binary(struct ofono_sim *sim, int fileid,
247                                 int start, int length,
248                                 const unsigned char *path,
249                                 unsigned int path_len,
250                                 ofono_sim_read_cb_t cb, void *data)
251 {
252         struct sim_data *sd = ofono_sim_get_data(sim);
253         struct cb_data *cbd = cb_data_new(cb, data);
254         char buf[64];
255         unsigned int len;
256
257         len = snprintf(buf, sizeof(buf), "AT+CRSM=176,%i,%i,%i,%i", fileid,
258                         start >> 8, start & 0xff, length);
259
260         if (path_len > 0) {
261                 buf[len++] = ',';
262                 buf[len++] = ',';
263                 buf[len++] = '\"';
264
265                 for (; path_len; path_len--)
266                         len += sprintf(buf + len, "%02hhX", *path++);
267
268                 buf[len++] = '\"';
269                 buf[len] = '\0';
270         }
271
272         if (g_at_chat_send(sd->chat, buf, crsm_prefix,
273                                 at_crsm_read_cb, cbd, g_free) > 0)
274                 return;
275
276         g_free(cbd);
277
278         CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
279 }
280
281 static void at_sim_read_record(struct ofono_sim *sim, int fileid,
282                                 int record, int length,
283                                 const unsigned char *path,
284                                 unsigned int path_len,
285                                 ofono_sim_read_cb_t cb, void *data)
286 {
287         struct sim_data *sd = ofono_sim_get_data(sim);
288         struct cb_data *cbd = cb_data_new(cb, data);
289         char buf[128];
290
291         snprintf(buf, sizeof(buf), "AT+CRSM=178,%i,%i,4,%i", fileid,
292                         record, length);
293
294         if (g_at_chat_send(sd->chat, buf, crsm_prefix,
295                                 at_crsm_read_cb, cbd, g_free) > 0)
296                 return;
297
298         g_free(cbd);
299
300         CALLBACK_WITH_FAILURE(cb, NULL, 0, data);
301 }
302
303 static void at_crsm_update_cb(gboolean ok, GAtResult *result,
304                                 gpointer user_data)
305 {
306         struct cb_data *cbd = user_data;
307         GAtResultIter iter;
308         ofono_sim_write_cb_t cb = cbd->cb;
309         struct ofono_error error;
310         gint sw1, sw2;
311
312         decode_at_error(&error, g_at_result_final_response(result));
313
314         if (!ok) {
315                 cb(&error, cbd->data);
316                 return;
317         }
318
319         g_at_result_iter_init(&iter, result);
320
321         if (!g_at_result_iter_next(&iter, "+CRSM:")) {
322                 CALLBACK_WITH_FAILURE(cb, cbd->data);
323                 return;
324         }
325
326         g_at_result_iter_next_number(&iter, &sw1);
327         g_at_result_iter_next_number(&iter, &sw2);
328
329         if ((sw1 != 0x90 && sw1 != 0x91 && sw1 != 0x92 && sw1 != 0x9f) ||
330                         (sw1 == 0x90 && sw2 != 0x00)) {
331                 memset(&error, 0, sizeof(error));
332
333                 error.type = OFONO_ERROR_TYPE_SIM;
334                 error.error = (sw1 << 8) | sw2;
335         }
336
337         DBG("crsm_update_cb: %02x, %02x", sw1, sw2);
338
339         cb(&error, cbd->data);
340 }
341
342 static void at_sim_update_file(struct ofono_sim *sim, int cmd, int fileid,
343                                 int p1, int p2, int p3,
344                                 const unsigned char *value,
345                                 const unsigned char *path,
346                                 unsigned int path_len,
347                                 ofono_sim_write_cb_t cb, void *data)
348 {
349         struct sim_data *sd = ofono_sim_get_data(sim);
350         struct cb_data *cbd = cb_data_new(cb, data);
351         char *buf;
352         int len, ret;
353         int size = 38 + p3 * 2;
354
355         DBG("");
356
357         buf = g_try_new(char, size);
358         if (buf == NULL)
359                 goto error;
360
361         len = sprintf(buf, "AT+CRSM=%i,%i,%i,%i,%i,\"", cmd, fileid,p1, p2, p3);
362
363         for (; p3; p3--)
364                 len += sprintf(buf + len, "%02hhX", *value++);
365
366         buf[len++] = '\"';
367         buf[len] = '\0';
368
369         ret = g_at_chat_send(sd->chat, buf, crsm_prefix,
370                                 at_crsm_update_cb, cbd, g_free);
371
372         g_free(buf);
373
374         if (ret > 0)
375                 return;
376
377 error:
378         g_free(cbd);
379
380         CALLBACK_WITH_FAILURE(cb, data);
381 }
382
383 static void at_sim_update_binary(struct ofono_sim *sim, int fileid,
384                                         int start, int length,
385                                         const unsigned char *value,
386                                         const unsigned char *path,
387                                         unsigned int path_len,
388                                         ofono_sim_write_cb_t cb, void *data)
389 {
390         at_sim_update_file(sim, 214, fileid, start >> 8, start & 0xff,
391                                 length, value, path, path_len, cb, data);
392 }
393
394 static void at_sim_update_record(struct ofono_sim *sim, int fileid,
395                                         int record, int length,
396                                         const unsigned char *value,
397                                         const unsigned char *path,
398                                         unsigned int path_len,
399                                         ofono_sim_write_cb_t cb, void *data)
400 {
401         at_sim_update_file(sim, 220, fileid, record, 4, length,
402                                 value, path, path_len, cb, data);
403 }
404
405 static void at_sim_update_cyclic(struct ofono_sim *sim, int fileid,
406                                         int length, const unsigned char *value,
407                                         const unsigned char *path,
408                                         unsigned int path_len,
409                                         ofono_sim_write_cb_t cb, void *data)
410 {
411         at_sim_update_file(sim, 220, fileid, 0, 3, length, value,
412                                 path, path_len, cb, data);
413 }
414
415 static void at_cimi_cb(gboolean ok, GAtResult *result, gpointer user_data)
416 {
417         struct cb_data *cbd = user_data;
418         GAtResultIter iter;
419         ofono_sim_imsi_cb_t cb = cbd->cb;
420         struct ofono_error error;
421         const char *imsi;
422         int i;
423
424         decode_at_error(&error, g_at_result_final_response(result));
425
426         if (!ok) {
427                 cb(&error, NULL, cbd->data);
428                 return;
429         }
430
431         g_at_result_iter_init(&iter, result);
432
433         for (i = 0; i < g_at_result_num_response_lines(result); i++)
434                 g_at_result_iter_next(&iter, NULL);
435
436         imsi = g_at_result_iter_raw_line(&iter);
437
438         DBG("cimi_cb: %s", imsi);
439
440         cb(&error, imsi, cbd->data);
441 }
442
443 static void at_read_imsi(struct ofono_sim *sim, ofono_sim_imsi_cb_t cb,
444                                 void *data)
445 {
446         struct sim_data *sd = ofono_sim_get_data(sim);
447         struct cb_data *cbd = cb_data_new(cb, data);
448
449         if (g_at_chat_send(sd->chat, "AT+CIMI", NULL,
450                                 at_cimi_cb, cbd, g_free) > 0)
451                 return;
452
453         g_free(cbd);
454
455         CALLBACK_WITH_FAILURE(cb, NULL, data);
456 }
457
458 static struct {
459         enum ofono_sim_password_type type;
460         const char *name;
461 } const at_sim_name[] = {
462         { OFONO_SIM_PASSWORD_NONE,              "READY"         },
463         { OFONO_SIM_PASSWORD_SIM_PIN,           "SIM PIN"       },
464         { OFONO_SIM_PASSWORD_SIM_PUK,           "SIM PUK"       },
465         { OFONO_SIM_PASSWORD_PHSIM_PIN,         "PH-SIM PIN"    },
466         { OFONO_SIM_PASSWORD_PHFSIM_PIN,        "PH-FSIM PIN"   },
467         { OFONO_SIM_PASSWORD_PHFSIM_PUK,        "PH-FSIM PUK"   },
468         { OFONO_SIM_PASSWORD_SIM_PIN2,          "SIM PIN2"      },
469         { OFONO_SIM_PASSWORD_SIM_PUK2,          "SIM PUK2"      },
470         { OFONO_SIM_PASSWORD_PHNET_PIN,         "PH-NET PIN"    },
471         { OFONO_SIM_PASSWORD_PHNET_PUK,         "PH-NET PUK"    },
472         { OFONO_SIM_PASSWORD_PHNETSUB_PIN,      "PH-NETSUB PIN" },
473         { OFONO_SIM_PASSWORD_PHNETSUB_PUK,      "PH-NETSUB PUK" },
474         { OFONO_SIM_PASSWORD_PHSP_PIN,          "PH-SP PIN"     },
475         { OFONO_SIM_PASSWORD_PHSP_PUK,          "PH-SP PUK"     },
476         { OFONO_SIM_PASSWORD_PHCORP_PIN,        "PH-CORP PIN"   },
477         { OFONO_SIM_PASSWORD_PHCORP_PUK,        "PH-CORP PUK"   },
478 };
479
480 #define BUILD_PIN_RETRIES_ARRAY(passwd_types, passwd_types_cnt, retry)  \
481         for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)                \
482                 retry[i] = -1;                                          \
483                                                                         \
484         for (i = 0; i < passwd_types_cnt; i++) {                        \
485                 int val;                                                \
486                                                                         \
487                 if (!g_at_result_iter_next_number(&iter, &val))         \
488                         goto error;                                     \
489                                                                         \
490                 retry[passwd_types[i]] = val;                           \
491                                                                         \
492                 DBG("retry counter id=%d, val=%d", passwd_types[i],     \
493                                         retry[passwd_types[i]]);        \
494         }                                                               \
495
496 static void huawei_cpin_cb(gboolean ok, GAtResult *result, gpointer user_data)
497 {
498         struct cb_data *cbd = user_data;
499         ofono_sim_pin_retries_cb_t cb = cbd->cb;
500         const char *final = g_at_result_final_response(result);
501         GAtResultIter iter;
502         struct ofono_error error;
503         int retries[OFONO_SIM_PASSWORD_INVALID];
504         size_t i;
505         static enum ofono_sim_password_type password_types[] = {
506                 OFONO_SIM_PASSWORD_SIM_PUK,
507                 OFONO_SIM_PASSWORD_SIM_PIN,
508                 OFONO_SIM_PASSWORD_SIM_PUK2,
509                 OFONO_SIM_PASSWORD_SIM_PIN2,
510         };
511
512         decode_at_error(&error, final);
513
514         if (!ok) {
515                 cb(&error, NULL, cbd->data);
516                 return;
517         }
518
519         g_at_result_iter_init(&iter, result);
520
521         if (!g_at_result_iter_next(&iter, "^CPIN:"))
522                 goto error;
523
524         /* Skip status since we are not interested in this */
525         if (!g_at_result_iter_skip_next(&iter))
526                 goto error;
527
528         /* Skip "overall counter" since we'll grab each one individually */
529         if (!g_at_result_iter_skip_next(&iter))
530                 goto error;
531
532         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
533                                 retries);
534
535         cb(&error, retries, cbd->data);
536
537         return;
538
539 error:
540         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
541 }
542
543 static void pinnum_cb(gboolean ok, GAtResult *result, gpointer user_data)
544 {
545         struct cb_data *cbd = user_data;
546         ofono_sim_pin_retries_cb_t cb = cbd->cb;
547         const char *final = g_at_result_final_response(result);
548         GAtResultIter iter;
549         struct ofono_error error;
550         int retries[OFONO_SIM_PASSWORD_INVALID];
551         size_t i;
552         static enum ofono_sim_password_type password_types[] = {
553                 OFONO_SIM_PASSWORD_SIM_PIN,
554                 OFONO_SIM_PASSWORD_SIM_PUK,
555                 OFONO_SIM_PASSWORD_SIM_PIN2,
556                 OFONO_SIM_PASSWORD_SIM_PUK2,
557         };
558
559
560         decode_at_error(&error, final);
561
562         if (!ok) {
563                 cb(&error, NULL, cbd->data);
564                 return;
565         }
566
567         g_at_result_iter_init(&iter, result);
568
569         if (!g_at_result_iter_next(&iter, "%PINNUM:"))
570                 goto error;
571
572         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
573                                 retries);
574
575         cb(&error, retries, cbd->data);
576
577         return;
578
579 error:
580         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
581 }
582
583 static void zpinpuk_cb(gboolean ok, GAtResult *result, gpointer user_data)
584 {
585         struct cb_data *cbd = user_data;
586         ofono_sim_pin_retries_cb_t cb = cbd->cb;
587         const char *final = g_at_result_final_response(result);
588         GAtResultIter iter;
589         struct ofono_error error;
590         int retries[OFONO_SIM_PASSWORD_INVALID];
591         size_t i;
592         static enum ofono_sim_password_type password_types[] = {
593                 OFONO_SIM_PASSWORD_SIM_PIN,
594                 OFONO_SIM_PASSWORD_SIM_PUK,
595         };
596
597
598         decode_at_error(&error, final);
599
600         if (!ok) {
601                 cb(&error, NULL, cbd->data);
602                 return;
603         }
604
605         g_at_result_iter_init(&iter, result);
606
607         if (!g_at_result_iter_next(&iter, "+ZPINPUK:"))
608                 goto error;
609
610         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
611                                 retries);
612
613         cb(&error, retries, cbd->data);
614
615         return;
616
617 error:
618         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
619 }
620
621 static void xpincnt_cb(gboolean ok, GAtResult *result, gpointer user_data)
622 {
623         struct cb_data *cbd = user_data;
624         ofono_sim_pin_retries_cb_t cb = cbd->cb;
625         const char *final = g_at_result_final_response(result);
626         GAtResultIter iter;
627         struct ofono_error error;
628         int retries[OFONO_SIM_PASSWORD_INVALID];
629         size_t i;
630         static enum ofono_sim_password_type password_types[] = {
631                 OFONO_SIM_PASSWORD_SIM_PIN,
632                 OFONO_SIM_PASSWORD_SIM_PIN2,
633                 OFONO_SIM_PASSWORD_SIM_PUK,
634                 OFONO_SIM_PASSWORD_SIM_PUK2,
635         };
636
637         decode_at_error(&error, final);
638
639         if (!ok) {
640                 cb(&error, NULL, cbd->data);
641                 return;
642         }
643
644         g_at_result_iter_init(&iter, result);
645
646         if (!g_at_result_iter_next(&iter, "+XPINCNT:"))
647                 goto error;
648
649         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
650                                 retries);
651
652         cb(&error, retries, cbd->data);
653
654         return;
655
656 error:
657         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
658 }
659
660 static void oercn_cb(gboolean ok, GAtResult *result, gpointer user_data)
661 {
662         struct cb_data *cbd = user_data;
663         ofono_sim_pin_retries_cb_t cb = cbd->cb;
664         const char *final = g_at_result_final_response(result);
665         GAtResultIter iter;
666         struct ofono_error error;
667         int retries[OFONO_SIM_PASSWORD_INVALID];
668         size_t i;
669         static enum ofono_sim_password_type password_types[] = {
670                 OFONO_SIM_PASSWORD_SIM_PIN,
671                 OFONO_SIM_PASSWORD_SIM_PUK,
672         };
673
674         decode_at_error(&error, final);
675
676         if (!ok) {
677                 cb(&error, NULL, cbd->data);
678                 return;
679         }
680
681         g_at_result_iter_init(&iter, result);
682
683         if (!g_at_result_iter_next(&iter, "_OERCN:"))
684                 goto error;
685
686         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
687                                 retries);
688
689         cb(&error, retries, cbd->data);
690
691         return;
692
693 error:
694         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
695 }
696
697 static void cpnnum_cb(gboolean ok, GAtResult *result, gpointer user_data)
698 {
699         struct cb_data *cbd = user_data;
700         ofono_sim_pin_retries_cb_t cb = cbd->cb;
701         const char *final = g_at_result_final_response(result);
702         GAtResultIter iter;
703         struct ofono_error error;
704         const char *line;
705         int num;
706         char **entries;
707         int retries[OFONO_SIM_PASSWORD_INVALID];
708         size_t i;
709
710         decode_at_error(&error, final);
711
712         if (!ok) {
713                 cb(&error, NULL, cbd->data);
714                 return;
715         }
716
717         g_at_result_iter_init(&iter, result);
718
719         for (num = 0; num < g_at_result_num_response_lines(result); num++)
720                 g_at_result_iter_next(&iter, NULL);
721
722         line = g_at_result_iter_raw_line(&iter);
723
724         DBG("%s", line);
725
726         for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
727                 retries[i] = -1;
728
729         entries = g_strsplit(line, "; ", -1);
730
731         for (num = 0; entries[num]; num++) {
732                 int retry;
733
734                 if (strlen(entries[num]) < 5)
735                         continue;
736
737                 retry = strtol(entries[num] + 5, NULL, 10);
738                 if (retry == 0 && errno == EINVAL)
739                         continue;
740
741                 if (g_str_has_prefix(entries[num], "PIN1=") == TRUE)
742                         retries[OFONO_SIM_PASSWORD_SIM_PIN] = retry;
743                 else if (g_str_has_prefix(entries[num], "PUK1=") == TRUE)
744                         retries[OFONO_SIM_PASSWORD_SIM_PUK] = retry;
745                 else if (g_str_has_prefix(entries[num], "PIN2=") == TRUE)
746                         retries[OFONO_SIM_PASSWORD_SIM_PIN2] = retry;
747                 else if (g_str_has_prefix(entries[num], "PUK2=") == TRUE)
748                         retries[OFONO_SIM_PASSWORD_SIM_PUK2] = retry;
749         }
750
751         g_strfreev(entries);
752
753         cb(&error, retries, cbd->data);
754 }
755
756 static void at_epin_cb(gboolean ok, GAtResult *result, gpointer user_data)
757 {
758         struct cb_data *cbd = user_data;
759         ofono_sim_pin_retries_cb_t cb = cbd->cb;
760         const char *final = g_at_result_final_response(result);
761         GAtResultIter iter;
762         struct ofono_error error;
763         int retries[OFONO_SIM_PASSWORD_INVALID];
764         size_t i;
765         static enum ofono_sim_password_type password_types[] = {
766                 OFONO_SIM_PASSWORD_SIM_PIN,
767                 OFONO_SIM_PASSWORD_SIM_PUK,
768                 OFONO_SIM_PASSWORD_SIM_PIN2,
769                 OFONO_SIM_PASSWORD_SIM_PUK2,
770         };
771
772         decode_at_error(&error, final);
773
774         if (!ok) {
775                 cb(&error, NULL, cbd->data);
776                 return;
777         }
778
779         g_at_result_iter_init(&iter, result);
780
781         if (!g_at_result_iter_next(&iter, "*EPIN:"))
782                 goto error;
783
784         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
785                                 retries);
786
787         cb(&error, retries, cbd->data);
788
789         return;
790
791 error:
792         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
793 }
794
795 static void at_cpinr_cb(gboolean ok, GAtResult *result, gpointer user_data)
796 {
797         struct cb_data *cbd = user_data;
798         ofono_sim_pin_retries_cb_t cb = cbd->cb;
799         GAtResultIter iter;
800         struct ofono_error error;
801         int retries[OFONO_SIM_PASSWORD_INVALID];
802         size_t len = sizeof(at_sim_name) / sizeof(*at_sim_name);
803         size_t i;
804
805         decode_at_error(&error, g_at_result_final_response(result));
806
807         if (!ok) {
808                 cb(&error, NULL, cbd->data);
809                 return;
810         }
811
812         for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
813                 retries[i] = -1;
814
815         g_at_result_iter_init(&iter, result);
816
817         /* Ignore +CPINRE results... */
818         while (g_at_result_iter_next(&iter, "+CPINR:")) {
819                 const char *name;
820                 int val;
821
822                 if (!g_at_result_iter_next_unquoted_string(&iter, &name))
823                         continue;
824
825                 if (!g_at_result_iter_next_number(&iter, &val))
826                         continue;
827
828                 for (i = 1; i < len; i++) {
829                         if (!strcmp(name, at_sim_name[i].name)) {
830                                 retries[at_sim_name[i].type] = val;
831                                 break;
832                         }
833                 }
834         }
835
836         cb(&error, retries, cbd->data);
837 }
838
839 static void at_spic_cb(gboolean ok, GAtResult *result, gpointer user_data)
840 {
841         struct cb_data *cbd = user_data;
842         ofono_sim_pin_retries_cb_t cb = cbd->cb;
843         const char *final = g_at_result_final_response(result);
844         GAtResultIter iter;
845         struct ofono_error error;
846         int retries[OFONO_SIM_PASSWORD_INVALID];
847         size_t i;
848         static enum ofono_sim_password_type password_types[] = {
849                 OFONO_SIM_PASSWORD_SIM_PIN,
850                 OFONO_SIM_PASSWORD_SIM_PUK,
851                 OFONO_SIM_PASSWORD_SIM_PIN2,
852                 OFONO_SIM_PASSWORD_SIM_PUK2,
853         };
854
855         decode_at_error(&error, final);
856
857         if (!ok) {
858                 cb(&error, NULL, cbd->data);
859                 return;
860         }
861
862         g_at_result_iter_init(&iter, result);
863
864         if (!g_at_result_iter_next(&iter, "+SPIC:"))
865                 goto error;
866
867         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
868                                 retries);
869
870         cb(&error, retries, cbd->data);
871
872         return;
873
874 error:
875         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
876 }
877
878 #define AT_PCT_SET_RETRIES(retries, pin_type, value) \
879         retries[pin_type] = value; \
880         DBG("retry counter id=%d, val=%d", pin_type, value);
881
882 static void at_pct_cb(gboolean ok, GAtResult *result, gpointer user_data)
883 {
884         struct cb_data *cbd = user_data;
885         ofono_sim_pin_retries_cb_t cb = cbd->cb;
886         struct ofono_sim *sim = cbd->user;
887         const char *final = g_at_result_final_response(result);
888         GAtResultIter iter;
889         struct ofono_error error;
890         int retries[OFONO_SIM_PASSWORD_INVALID];
891         size_t i;
892         enum ofono_sim_password_type pin_type;
893
894         decode_at_error(&error, final);
895
896         if (!ok) {
897                 cb(&error, NULL, cbd->data);
898                 return;
899         }
900
901         g_at_result_iter_init(&iter, result);
902
903         for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
904                 retries[i] = -1;
905
906         pin_type = ofono_sim_get_password_type(sim);
907         if (pin_type == OFONO_SIM_PASSWORD_NONE) {
908                 DBG("Note: No password required, returning maximum retries:");
909
910                 AT_PCT_SET_RETRIES(retries, OFONO_SIM_PASSWORD_SIM_PIN, 3);
911                 AT_PCT_SET_RETRIES(retries, OFONO_SIM_PASSWORD_SIM_PIN2, 3);
912                 AT_PCT_SET_RETRIES(retries, OFONO_SIM_PASSWORD_SIM_PUK, 10);
913                 AT_PCT_SET_RETRIES(retries, OFONO_SIM_PASSWORD_SIM_PUK2, 10);
914
915                 goto callback;
916         }
917
918         if (g_at_result_iter_next(&iter, "#PCT:") == FALSE)
919                 goto error;
920
921         if (g_at_result_iter_next_number(&iter, &retries[pin_type]) == FALSE)
922                 goto error;
923
924         DBG("retry counter id=%d, val=%d", pin_type, retries[pin_type]);
925
926 callback:
927         cb(&error, retries, cbd->data);
928
929         return;
930
931 error:
932         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
933 }
934
935 static void at_pnnm_cb(gboolean ok, GAtResult *result, gpointer user_data)
936 {
937         struct cb_data *cbd = user_data;
938         ofono_sim_pin_retries_cb_t cb = cbd->cb;
939         const char *final = g_at_result_final_response(result);
940         GAtResultIter iter;
941         struct ofono_error error;
942         int retries[OFONO_SIM_PASSWORD_INVALID];
943         size_t i;
944         static enum ofono_sim_password_type password_types[] = {
945                 OFONO_SIM_PASSWORD_SIM_PIN,
946                 OFONO_SIM_PASSWORD_SIM_PUK,
947         };
948
949         decode_at_error(&error, final);
950
951         if (!ok) {
952                 cb(&error, NULL, cbd->data);
953                 return;
954         }
955
956         g_at_result_iter_init(&iter, result);
957
958         if (!g_at_result_iter_next(&iter, "+PNNM:"))
959                 goto error;
960
961         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
962                                 retries);
963
964         cb(&error, retries, cbd->data);
965
966         return;
967
968 error:
969         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
970 }
971
972 static void at_qpinc_cb(gboolean ok, GAtResult *result, gpointer user_data)
973 {
974         struct cb_data *cbd = user_data;
975         ofono_sim_pin_retries_cb_t cb = cbd->cb;
976         const char *final = g_at_result_final_response(result);
977         GAtResultIter iter;
978         struct ofono_error error;
979         int retries[OFONO_SIM_PASSWORD_INVALID];
980         size_t i;
981
982         decode_at_error(&error, final);
983
984         if (!ok) {
985                 cb(&error, NULL, cbd->data);
986                 return;
987         }
988
989         for (i = 0; i < OFONO_SIM_PASSWORD_INVALID; i++)
990                 retries[i] = -1;
991
992         g_at_result_iter_init(&iter, result);
993
994         while (g_at_result_iter_next(&iter, "+QPINC:")) {
995                 const char *name;
996                 int pin, puk;
997
998                 if (!g_at_result_iter_next_string(&iter, &name))
999                         continue;
1000                 if (!g_at_result_iter_next_number(&iter, &pin))
1001                         continue;
1002                 if (!g_at_result_iter_next_number(&iter, &puk))
1003                         continue;
1004
1005                 if (!strcmp(name, "SC")) {
1006                         retries[OFONO_SIM_PASSWORD_SIM_PIN] = pin;
1007                         retries[OFONO_SIM_PASSWORD_SIM_PUK] = puk;
1008                 } else if (!strcmp(name, "P2")) {
1009                         retries[OFONO_SIM_PASSWORD_SIM_PIN2] = pin;
1010                         retries[OFONO_SIM_PASSWORD_SIM_PUK2] = puk;
1011                 }
1012         }
1013
1014         cb(&error, retries, cbd->data);
1015 }
1016
1017 static void upincnt_cb(gboolean ok, GAtResult *result, gpointer user_data)
1018 {
1019         struct cb_data *cbd = user_data;
1020         ofono_sim_pin_retries_cb_t cb = cbd->cb;
1021         const char *final = g_at_result_final_response(result);
1022         GAtResultIter iter;
1023         struct ofono_error error;
1024         int retries[OFONO_SIM_PASSWORD_INVALID];
1025         size_t i;
1026         static enum ofono_sim_password_type password_types[] = {
1027                 OFONO_SIM_PASSWORD_SIM_PIN,
1028                 OFONO_SIM_PASSWORD_SIM_PIN2,
1029                 OFONO_SIM_PASSWORD_SIM_PUK,
1030                 OFONO_SIM_PASSWORD_SIM_PUK2,
1031         };
1032
1033         decode_at_error(&error, final);
1034
1035         if (!ok) {
1036                 cb(&error, NULL, cbd->data);
1037                 return;
1038         }
1039
1040         g_at_result_iter_init(&iter, result);
1041
1042         if (!g_at_result_iter_next(&iter, "+UPINCNT:"))
1043                 goto error;
1044
1045         BUILD_PIN_RETRIES_ARRAY(password_types, ARRAY_SIZE(password_types),
1046                                 retries);
1047
1048         cb(&error, retries, cbd->data);
1049
1050         return;
1051
1052 error:
1053         CALLBACK_WITH_FAILURE(cb, NULL, cbd->data);
1054 }
1055
1056 static void at_pin_retries_query(struct ofono_sim *sim,
1057                                         ofono_sim_pin_retries_cb_t cb,
1058                                         void *data)
1059 {
1060         struct sim_data *sd = ofono_sim_get_data(sim);
1061         struct cb_data *cbd = cb_data_new(cb, data);
1062         cbd->user = sim;
1063
1064         DBG("");
1065
1066         switch (sd->vendor) {
1067         case OFONO_VENDOR_IFX:
1068                 if (g_at_chat_send(sd->chat, "AT+XPINCNT", xpincnt_prefix,
1069                                         xpincnt_cb, cbd, g_free) > 0)
1070                         return;
1071                 break;
1072         case OFONO_VENDOR_SPEEDUP:
1073                 if (g_at_chat_send(sd->chat, "AT+CPNNUM", NULL,
1074                                         cpnnum_cb, cbd, g_free) > 0)
1075                         return;
1076                 break;
1077         case OFONO_VENDOR_OPTION_HSO:
1078                 if (g_at_chat_send(sd->chat, "AT_OERCN?", oercn_prefix,
1079                                         oercn_cb, cbd, g_free) > 0)
1080                         return;
1081                 break;
1082         case OFONO_VENDOR_HUAWEI:
1083                 if (g_at_chat_send(sd->chat, "AT^CPIN?", huawei_cpin_prefix,
1084                                         huawei_cpin_cb, cbd, g_free) > 0)
1085                         return;
1086                 break;
1087         case OFONO_VENDOR_ICERA:
1088                 if (g_at_chat_send(sd->chat, "AT%PINNUM?", pinnum_prefix,
1089                                         pinnum_cb, cbd, g_free) > 0)
1090                         return;
1091                 break;
1092         case OFONO_VENDOR_ZTE:
1093                 if (g_at_chat_send(sd->chat, "AT+ZPINPUK=?", zpinpuk_prefix,
1094                                         zpinpuk_cb, cbd, g_free) > 0)
1095                         return;
1096                 break;
1097         case OFONO_VENDOR_MBM:
1098                 if (g_at_chat_send(sd->chat, "AT*EPIN?", epin_prefix,
1099                                         at_epin_cb, cbd, g_free) > 0)
1100                         return;
1101                 break;
1102         case OFONO_VENDOR_SIMCOM:
1103                 if (g_at_chat_send(sd->chat, "AT+SPIC", spic_prefix,
1104                                         at_spic_cb, cbd, g_free) > 0)
1105                         return;
1106                 break;
1107         case OFONO_VENDOR_TELIT:
1108                 if (g_at_chat_send(sd->chat, "AT#PCT", pct_prefix,
1109                                         at_pct_cb, cbd, g_free) > 0)
1110                         return;
1111                 break;
1112         case OFONO_VENDOR_ALCATEL:
1113                 if (g_at_chat_send(sd->chat, "AT+PNNM?", pnnm_prefix,
1114                                         at_pnnm_cb, cbd, g_free) > 0)
1115                         return;
1116                 break;
1117         case OFONO_VENDOR_QUECTEL:
1118                 if (g_at_chat_send(sd->chat, "AT+QPINC?", qpinc_prefix,
1119                                         at_qpinc_cb, cbd, g_free) > 0)
1120                         return;
1121                 break;
1122         case OFONO_VENDOR_UBLOX:
1123                 if (g_at_chat_send(sd->chat, "AT+UPINCNT", upincnt_prefix,
1124                                         upincnt_cb, cbd, g_free) > 0)
1125                         return;
1126                 break;
1127         default:
1128                 if (g_at_chat_send(sd->chat, "AT+CPINR", cpinr_prefixes,
1129                                         at_cpinr_cb, cbd, g_free) > 0)
1130                         return;
1131                 break;
1132         }
1133
1134         g_free(cbd);
1135
1136         CALLBACK_WITH_FAILURE(cb, NULL, data);
1137 }
1138
1139 static int needs_wavecom_sim_quirk(int vendor)
1140 {
1141         return vendor == OFONO_VENDOR_WAVECOM ||
1142                         vendor == OFONO_VENDOR_WAVECOM_Q2XXX;
1143 }
1144
1145 static void at_cpin_cb(gboolean ok, GAtResult *result, gpointer user_data)
1146 {
1147         struct cb_data *cbd = user_data;
1148         struct sim_data *sd = ofono_sim_get_data(cbd->user);
1149         GAtResultIter iter;
1150         ofono_sim_passwd_cb_t cb = cbd->cb;
1151         struct ofono_error error;
1152         const char *pin_required;
1153         int pin_type = OFONO_SIM_PASSWORD_INVALID;
1154         int i;
1155         int len = sizeof(at_sim_name) / sizeof(*at_sim_name);
1156         const char *final = g_at_result_final_response(result);
1157
1158         if (needs_wavecom_sim_quirk(sd->vendor) && ok && strlen(final) > 7)
1159                 decode_at_error(&error, "OK");
1160         else
1161                 decode_at_error(&error, final);
1162
1163         if (!ok) {
1164                 cb(&error, -1, cbd->data);
1165                 return;
1166         }
1167
1168         if (needs_wavecom_sim_quirk(sd->vendor)) {
1169                 /* +CPIN: <pin> */
1170                 pin_required = final + 7;
1171         } else {
1172                 g_at_result_iter_init(&iter, result);
1173
1174                 if (!g_at_result_iter_next(&iter, "+CPIN:")) {
1175                         CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
1176                         return;
1177                 }
1178
1179                 g_at_result_iter_next_unquoted_string(&iter, &pin_required);
1180         }
1181
1182         for (i = 0; i < len; i++) {
1183                 if (strcmp(pin_required, at_sim_name[i].name))
1184                         continue;
1185
1186                 pin_type = at_sim_name[i].type;
1187                 break;
1188         }
1189
1190         if (pin_type == OFONO_SIM_PASSWORD_INVALID) {
1191                 CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
1192                 return;
1193         }
1194
1195         DBG("crsm_pin_cb: %s", pin_required);
1196
1197         cb(&error, pin_type, cbd->data);
1198 }
1199
1200 static void at_pin_query(struct ofono_sim *sim, ofono_sim_passwd_cb_t cb,
1201                         void *data)
1202 {
1203         struct sim_data *sd = ofono_sim_get_data(sim);
1204         struct cb_data *cbd = cb_data_new(cb, data);
1205
1206         cbd->user = sim;
1207
1208         if (g_at_chat_send(sd->chat, "AT+CPIN?", cpin_prefix,
1209                                 at_cpin_cb, cbd, g_free) > 0)
1210                 return;
1211
1212         g_free(cbd);
1213
1214         CALLBACK_WITH_FAILURE(cb, -1, data);
1215 }
1216
1217 static void at_xsim_notify(GAtResult *result, gpointer user_data)
1218 {
1219         struct cb_data *cbd = user_data;
1220         struct sim_data *sd = cbd->user;
1221         ofono_sim_lock_unlock_cb_t cb = cbd->cb;
1222         struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
1223         GAtResultIter iter;
1224         int state;
1225
1226         g_at_result_iter_init(&iter, result);
1227
1228         if (!g_at_result_iter_next(&iter, "+XSIM:"))
1229                 return;
1230
1231         if (!g_at_result_iter_next_number(&iter, &state))
1232                 return;
1233
1234         switch (state) {
1235         case 3: /* PIN verified â€“ Ready */
1236                 break;
1237         default:
1238                 return;
1239         }
1240
1241         cb(&error, cbd->data);
1242
1243         g_at_chat_unregister(sd->chat, sd->ready_id);
1244         sd->ready_id = 0;
1245 }
1246
1247 static void at_epev_notify(GAtResult *result, gpointer user_data)
1248 {
1249         struct cb_data *cbd = user_data;
1250         struct sim_data *sd = cbd->user;
1251         ofono_sim_lock_unlock_cb_t cb = cbd->cb;
1252         struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
1253
1254         cb(&error, cbd->data);
1255
1256         g_at_chat_unregister(sd->chat, sd->ready_id);
1257         sd->ready_id = 0;
1258 }
1259
1260 static void at_qss_notify(GAtResult *result, gpointer user_data)
1261 {
1262         struct cb_data *cbd = user_data;
1263         struct sim_data *sd = cbd->user;
1264         ofono_sim_lock_unlock_cb_t cb = cbd->cb;
1265         struct ofono_error error = { .type = OFONO_ERROR_TYPE_NO_ERROR };
1266         GAtResultIter iter;
1267         int state;
1268
1269         g_at_result_iter_init(&iter, result);
1270
1271         if (!g_at_result_iter_next(&iter, "#QSS:"))
1272                 return;
1273
1274         if (!g_at_result_iter_next_number(&iter, &state))
1275                 return;
1276
1277         switch (state) {
1278         case 3: /* SIM inserted and READY. */
1279                 break;
1280         default:
1281                 return;
1282         }
1283
1284         cb(&error, cbd->data);
1285
1286         g_at_chat_unregister(sd->chat, sd->ready_id);
1287         sd->ready_id = 0;
1288 }
1289
1290 static void sim_state_cb(gboolean present, gpointer user_data)
1291 {
1292         struct cb_data *cbd = user_data;
1293         struct sim_data *sd = cbd->user;
1294         ofono_sim_lock_unlock_cb_t cb = cbd->cb;
1295
1296         at_util_sim_state_query_free(sd->sim_state_query);
1297         sd->sim_state_query = NULL;
1298
1299         if (present == 1)
1300                 CALLBACK_WITH_SUCCESS(cb, cbd->data);
1301         else
1302                 CALLBACK_WITH_FAILURE(cb, cbd->data);
1303 }
1304
1305 static void at_pin_send_cb(gboolean ok, GAtResult *result,
1306                                 gpointer user_data)
1307 {
1308         struct cb_data *cbd = user_data;
1309         struct sim_data *sd = cbd->user;
1310         ofono_sim_lock_unlock_cb_t cb = cbd->cb;
1311         struct ofono_error error;
1312
1313         decode_at_error(&error, g_at_result_final_response(result));
1314
1315         if (!ok)
1316                 goto done;
1317
1318         switch (sd->vendor) {
1319         case OFONO_VENDOR_IFX:
1320                 /*
1321                  * On the IFX modem, AT+CPIN? can return READY too
1322                  * early and so use +XSIM notification to detect
1323                  * the ready state of the SIM.
1324                  */
1325                 sd->ready_id = g_at_chat_register(sd->chat, "+XSIM",
1326                                                         at_xsim_notify,
1327                                                         FALSE, cbd, g_free);
1328                 return;
1329         case OFONO_VENDOR_MBM:
1330                 /*
1331                  * On the MBM modem, AT+CPIN? keeps returning SIM PIN
1332                  * for a moment after successful AT+CPIN="..", but then
1333                  * sends *EPEV when that changes.
1334                  */
1335                 sd->ready_id = g_at_chat_register(sd->chat, "*EPEV",
1336                                                         at_epev_notify,
1337                                                         FALSE, cbd, g_free);
1338                 return;
1339         case OFONO_VENDOR_TELIT:
1340                 /*
1341                  * On the Telit modem, AT+CPIN? can return READY too
1342                  * early and so use #QSS notification to detect
1343                  * the ready state of the SIM.
1344                  */
1345                 sd->ready_id = g_at_chat_register(sd->chat, "#QSS",
1346                                                         at_qss_notify,
1347                                                         FALSE, cbd, g_free);
1348                 return;
1349         case OFONO_VENDOR_ZTE:
1350         case OFONO_VENDOR_ALCATEL:
1351         case OFONO_VENDOR_HUAWEI:
1352         case OFONO_VENDOR_SIMCOM:
1353         case OFONO_VENDOR_SIERRA:
1354                 /*
1355                  * On ZTE modems, after pin is entered, SIM state is checked
1356                  * by polling CPIN as their modem doesn't provide unsolicited
1357                  * notification of SIM readiness.
1358                  *
1359                  * On SIMCOM modems, SIM is busy after pin is entered (we
1360                  * got a "+CME ERROR: 14" for the "AT+CPIN?" request) and
1361                  * ofono don't catch the "+CPIN: READY" message sent by the
1362                  * modem when SIM is ready. So, use extra CPIN to check the
1363                  * state.
1364                  */
1365                 sd->sim_state_query = at_util_sim_state_query_new(sd->chat,
1366                                                 2, 20, sim_state_cb, cbd,
1367                                                 g_free);
1368                 return;
1369         }
1370
1371 done:
1372         cb(&error, cbd->data);
1373
1374         g_free(cbd);
1375 }
1376
1377 static void at_pin_send(struct ofono_sim *sim, const char *passwd,
1378                         ofono_sim_lock_unlock_cb_t cb, void *data)
1379 {
1380         struct sim_data *sd = ofono_sim_get_data(sim);
1381         struct cb_data *cbd = cb_data_new(cb, data);
1382         char buf[64];
1383         int ret;
1384
1385         cbd->user = sd;
1386
1387         snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\"", passwd);
1388
1389         ret = g_at_chat_send(sd->chat, buf, none_prefix,
1390                                 at_pin_send_cb, cbd, NULL);
1391
1392         memset(buf, 0, sizeof(buf));
1393
1394         if (ret > 0)
1395                 return;
1396
1397         g_free(cbd);
1398
1399         CALLBACK_WITH_FAILURE(cb, data);
1400 }
1401
1402 static void at_pin_send_puk(struct ofono_sim *sim, const char *puk,
1403                                 const char *passwd,
1404                                 ofono_sim_lock_unlock_cb_t cb, void *data)
1405 {
1406         struct sim_data *sd = ofono_sim_get_data(sim);
1407         struct cb_data *cbd = cb_data_new(cb, data);
1408         char buf[64];
1409         int ret;
1410
1411         cbd->user = sd;
1412
1413         snprintf(buf, sizeof(buf), "AT+CPIN=\"%s\",\"%s\"", puk, passwd);
1414
1415         ret = g_at_chat_send(sd->chat, buf, none_prefix,
1416                                 at_pin_send_cb, cbd, NULL);
1417
1418         memset(buf, 0, sizeof(buf));
1419
1420         if (ret > 0)
1421                 return;
1422
1423         g_free(cbd);
1424
1425         CALLBACK_WITH_FAILURE(cb, data);
1426 }
1427
1428 static void at_lock_unlock_cb(gboolean ok, GAtResult *result,
1429                                 gpointer user_data)
1430 {
1431         struct cb_data *cbd = user_data;
1432         ofono_sim_lock_unlock_cb_t cb = cbd->cb;
1433         struct ofono_error error;
1434
1435         decode_at_error(&error, g_at_result_final_response(result));
1436
1437         cb(&error, cbd->data);
1438 }
1439
1440 static const char *const at_clck_cpwd_fac[] = {
1441         [OFONO_SIM_PASSWORD_SIM_PIN] = "SC",
1442         [OFONO_SIM_PASSWORD_SIM_PIN2] = "P2",
1443         [OFONO_SIM_PASSWORD_PHSIM_PIN] = "PS",
1444         [OFONO_SIM_PASSWORD_PHFSIM_PIN] = "PF",
1445         [OFONO_SIM_PASSWORD_PHNET_PIN] = "PN",
1446         [OFONO_SIM_PASSWORD_PHNETSUB_PIN] = "PU",
1447         [OFONO_SIM_PASSWORD_PHSP_PIN] = "PP",
1448         [OFONO_SIM_PASSWORD_PHCORP_PIN] = "PC",
1449 };
1450
1451 static void at_pin_enable(struct ofono_sim *sim,
1452                                 enum ofono_sim_password_type passwd_type,
1453                                 int enable, const char *passwd,
1454                                 ofono_sim_lock_unlock_cb_t cb, void *data)
1455 {
1456         struct sim_data *sd = ofono_sim_get_data(sim);
1457         struct cb_data *cbd = cb_data_new(cb, data);
1458         char buf[64];
1459         int ret;
1460         unsigned int len = sizeof(at_clck_cpwd_fac) / sizeof(*at_clck_cpwd_fac);
1461
1462         if (passwd_type >= len || at_clck_cpwd_fac[passwd_type] == NULL)
1463                 goto error;
1464
1465         snprintf(buf, sizeof(buf), "AT+CLCK=\"%s\",%i,\"%s\"",
1466                         at_clck_cpwd_fac[passwd_type], enable ? 1 : 0, passwd);
1467
1468         ret = g_at_chat_send(sd->chat, buf, none_prefix,
1469                                 at_lock_unlock_cb, cbd, g_free);
1470
1471         memset(buf, 0, sizeof(buf));
1472
1473         if (ret > 0)
1474                 return;
1475
1476 error:
1477         g_free(cbd);
1478
1479         CALLBACK_WITH_FAILURE(cb, data);
1480 }
1481
1482 static void at_change_passwd(struct ofono_sim *sim,
1483                                 enum ofono_sim_password_type passwd_type,
1484                                 const char *old_passwd, const char *new_passwd,
1485                                 ofono_sim_lock_unlock_cb_t cb, void *data)
1486 {
1487         struct sim_data *sd = ofono_sim_get_data(sim);
1488         struct cb_data *cbd = cb_data_new(cb, data);
1489         char buf[64];
1490         int ret;
1491         unsigned int len = sizeof(at_clck_cpwd_fac) / sizeof(*at_clck_cpwd_fac);
1492
1493         if (passwd_type >= len ||
1494                         at_clck_cpwd_fac[passwd_type] == NULL)
1495                 goto error;
1496
1497         snprintf(buf, sizeof(buf), "AT+CPWD=\"%s\",\"%s\",\"%s\"",
1498                         at_clck_cpwd_fac[passwd_type], old_passwd, new_passwd);
1499
1500         ret = g_at_chat_send(sd->chat, buf, none_prefix,
1501                                 at_lock_unlock_cb, cbd, g_free);
1502
1503         memset(buf, 0, sizeof(buf));
1504
1505         if (ret > 0)
1506                 return;
1507
1508 error:
1509         g_free(cbd);
1510
1511         CALLBACK_WITH_FAILURE(cb, data);
1512 }
1513
1514 static void at_lock_status_cb(gboolean ok, GAtResult *result,
1515                                 gpointer user_data)
1516 {
1517         struct cb_data *cbd = user_data;
1518         GAtResultIter iter;
1519         ofono_sim_locked_cb_t cb = cbd->cb;
1520         struct ofono_error error;
1521         int locked;
1522
1523         decode_at_error(&error, g_at_result_final_response(result));
1524
1525         if (!ok) {
1526                 cb(&error, -1, cbd->data);
1527                 return;
1528         }
1529
1530         g_at_result_iter_init(&iter, result);
1531
1532         if (!g_at_result_iter_next(&iter, "+CLCK:")) {
1533                 CALLBACK_WITH_FAILURE(cb, -1, cbd->data);
1534                 return;
1535         }
1536
1537         g_at_result_iter_next_number(&iter, &locked);
1538
1539         DBG("lock_status_cb: %i", locked);
1540
1541         cb(&error, locked, cbd->data);
1542 }
1543
1544 static void at_pin_query_enabled(struct ofono_sim *sim,
1545                                 enum ofono_sim_password_type passwd_type,
1546                                 ofono_sim_locked_cb_t cb, void *data)
1547 {
1548         struct sim_data *sd = ofono_sim_get_data(sim);
1549         struct cb_data *cbd = cb_data_new(cb, data);
1550         char buf[64];
1551         unsigned int len = sizeof(at_clck_cpwd_fac) / sizeof(*at_clck_cpwd_fac);
1552
1553         if (passwd_type >= len || at_clck_cpwd_fac[passwd_type] == NULL)
1554                 goto error;
1555
1556         snprintf(buf, sizeof(buf), "AT+CLCK=\"%s\",2",
1557                         at_clck_cpwd_fac[passwd_type]);
1558
1559         if (g_at_chat_send(sd->chat, buf, clck_prefix,
1560                                 at_lock_status_cb, cbd, g_free) > 0)
1561                 return;
1562
1563 error:
1564         g_free(cbd);
1565
1566         CALLBACK_WITH_FAILURE(cb, -1, data);
1567 }
1568
1569 static gboolean at_sim_register(gpointer user)
1570 {
1571         struct ofono_sim *sim = user;
1572
1573         ofono_sim_register(sim);
1574
1575         return FALSE;
1576 }
1577
1578 static int at_sim_probe(struct ofono_sim *sim, unsigned int vendor,
1579                                 void *data)
1580 {
1581         GAtChat *chat = data;
1582         struct sim_data *sd;
1583
1584         sd = g_new0(struct sim_data, 1);
1585         sd->chat = g_at_chat_clone(chat);
1586         sd->vendor = vendor;
1587
1588         if (sd->vendor == OFONO_VENDOR_MBM)
1589                 g_at_chat_send(sd->chat, "AT*EPEE=1", NULL, NULL, NULL, NULL);
1590
1591         ofono_sim_set_data(sim, sd);
1592         g_idle_add(at_sim_register, sim);
1593
1594         return 0;
1595 }
1596
1597 static void at_sim_remove(struct ofono_sim *sim)
1598 {
1599         struct sim_data *sd = ofono_sim_get_data(sim);
1600
1601         g_idle_remove_by_data(sim);
1602         /* Cleanup potential SIM state polling */
1603         at_util_sim_state_query_free(sd->sim_state_query);
1604
1605         ofono_sim_set_data(sim, NULL);
1606
1607         g_at_chat_unref(sd->chat);
1608         g_free(sd);
1609 }
1610
1611 static struct ofono_sim_driver driver = {
1612         .name                   = "atmodem",
1613         .probe                  = at_sim_probe,
1614         .remove                 = at_sim_remove,
1615         .read_file_info         = at_sim_read_info,
1616         .read_file_transparent  = at_sim_read_binary,
1617         .read_file_linear       = at_sim_read_record,
1618         .read_file_cyclic       = at_sim_read_record,
1619         .write_file_transparent = at_sim_update_binary,
1620         .write_file_linear      = at_sim_update_record,
1621         .write_file_cyclic      = at_sim_update_cyclic,
1622         .read_imsi              = at_read_imsi,
1623         .query_passwd_state     = at_pin_query,
1624         .query_pin_retries      = at_pin_retries_query,
1625         .send_passwd            = at_pin_send,
1626         .reset_passwd           = at_pin_send_puk,
1627         .lock                   = at_pin_enable,
1628         .change_passwd          = at_change_passwd,
1629         .query_locked           = at_pin_query_enabled,
1630 };
1631
1632 static struct ofono_sim_driver driver_noef = {
1633         .name                   = "atmodem-noef",
1634         .probe                  = at_sim_probe,
1635         .remove                 = at_sim_remove,
1636         .read_imsi              = at_read_imsi,
1637         .query_passwd_state     = at_pin_query,
1638         .query_pin_retries      = at_pin_retries_query,
1639         .send_passwd            = at_pin_send,
1640         .reset_passwd           = at_pin_send_puk,
1641         .lock                   = at_pin_enable,
1642         .change_passwd          = at_change_passwd,
1643         .query_locked           = at_pin_query_enabled,
1644 };
1645
1646 void at_sim_init(void)
1647 {
1648         ofono_sim_driver_register(&driver);
1649         ofono_sim_driver_register(&driver_noef);
1650 }
1651
1652 void at_sim_exit(void)
1653 {
1654         ofono_sim_driver_unregister(&driver);
1655         ofono_sim_driver_unregister(&driver_noef);
1656 }