blob: 509d0476f8ad5aabcd55d5e07b6c881413727c6a [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/***************************************************************/
2//
3//²Î¼û ÖйúÁªÍ¨esimÄ£×éÀ©Õ¹Ö¸Áî¼¼Êõ¹æ·¶
4//
5/***************************************************************/
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <ctype.h>
11#include <sys/time.h>
12#include <termios.h>
13#include <errno.h>
14
15#include "lpa_inner.h"
16
17
18#define SMDP_PORT 443
19#define SMDP_DL_INTERVAL 95//ÏÂÔØ¼ä¸ô>90s
20
21
22//´¥·¢·þÎñÆ÷httpÇëÇó
23static char smdp_https_req[] =
24 "POST /gsma/rsp2/es9plus/%s HTTP/1.1\r\n"
25 "Host: %s\r\n"
26 "User-Agent: gsma-rsp-lpad\r\n"
27 "X-Admin-Protocol: gsma/rsp/v2.2.0\r\n"
28 "Content-Type: application/json\r\n"
29 "Content-Length: %d\r\n"
30 "\r\n%s\r\n";
31
32static https_context_t g_https_ct = {0};
33static char g_transid[MAX_TRANSID_LEN] = {0};
34char curent_iccid[ICCID_LEN+1] = {0};
35
36extern char g_imei[MAX_IMEI_LEN];
37
38//iccid from bpp install result, if null, failed
39//ISD-P AID, tag '4F';ICCID, tag '5A'. if succ, has AID
40static int lpa_parse_iccid_apdu(char *apdu, char *iccid, int size)
41{
42 int apdu_len = strlen(apdu);
43 unsigned char *apdu_byte = malloc(apdu_len/2 + 1);
44 int apdu_byte_len = 0;
45 char *tag_hex = NULL;
46 char has_iccid[ICCID_LEN+1] = {0};
47
48 if (apdu_byte == NULL) {
49 printf("lpa_parse_iccid_apdu no memory\n");
50 return -1;
51 }
52 memset(apdu_byte, 0, apdu_len/2 + 1);
53
54 apdu_byte_len = string2bytes(apdu, apdu_byte, apdu_len);
55
56 tag_hex = lpa_tlv_get_val_by_tag(apdu_byte, apdu_byte_len, 0x4F);
57 if (tag_hex == NULL) {
58 printf("lpa_parse_iccid_apdu not find AID\n");
59 free(apdu_byte);
60 return -1;
61 }
62 printf("lpa aid:%s\n", tag_hex);
63 free(tag_hex);
64 tag_hex = NULL;
65
66 tag_hex = lpa_tlv_get_val_by_tag(apdu_byte, apdu_byte_len, 0x5A);
67 if (tag_hex == NULL) {
68 printf("lpa_parse_iccid_apdu not find iccid\n");
69 free(apdu_byte);
70 return -1;
71
72 }
73
74 snprintf(iccid, size, "%s", tag_hex);
75
76 sc_cfg_get("lpa_bpp_iccid", has_iccid, sizeof(has_iccid));
77 if (strcmp(iccid, has_iccid) != 0) {
78 sc_cfg_set("lpa_bpp_iccid", iccid);
79 sc_cfg_save();
80 printf("lpa iccid not same?\n");
81 }
82
83 printf("lpa iccid:%s\n", iccid);
84
85 free(apdu_byte);
86 free(tag_hex);
87 return 0;
88}
89
90static int lpa_connect_smdp(char *host)
91{
92 SSL_library_init();
93
94 g_https_ct.port=SMDP_PORT;
95 g_https_ct.host=host;
96 g_https_ct.path=NULL;
97 return https_init(&g_https_ct);
98}
99
100static void lpa_disconn_smdp(char *host)
101{
102 https_uninit(&g_https_ct);
103}
104
105static char *lpa_smdp_session(char *path, char *req_data, int *res_len)
106{
107 int ret = -1;
108 int cont_len = 0;
109 char *https_req = NULL;
110 char *https_resp = NULL;
111 int https_req_len = strlen(smdp_https_req)+strlen(path)+strlen(g_https_ct.host)+strlen(req_data)+32;
112
113 *res_len = -1;
114
115 if (https_req_len > SMDP_HTTP_MAX_LEN)
116 return NULL;
117
118 https_req = malloc(https_req_len);
119 if (https_req == NULL)
120 return NULL;
121
122 memset(https_req, 0, https_req_len);
123 g_https_ct.path = path;
124 ret = snprintf(https_req, https_req_len, smdp_https_req,
125 g_https_ct.path, g_https_ct.host, strlen(req_data), req_data);
126
127 printf("[https_smdp]req[%d]:##%s##\n", strlen(https_req), https_req);
128 ret = https_write(&g_https_ct, https_req, ret);
129 if (ret == -1) {
130 //EAGAIN?
131 free(https_req);
132 printf("[https_smdp] https_write err:%d.\n", errno);
133 return NULL;
134 }
135
136 ret = https_get_status_code(&g_https_ct, &cont_len);
137 if(ret == 200) {
138 printf("[https_smdp] https_recv len:%d.\n", cont_len);
139 if (cont_len == HTTP_CHUNKED_FLAG) {
140 ret = https_read_chunked_content(&g_https_ct, &https_resp, SMDP_HTTP_MAX_LEN);
141 if(ret > 0) {
142 *res_len = ret;
143 https_resp[ret] = '\0'; //×Ö·û´®½áÊø±êʶ
144 printf("[https_smdp] https_write https_resp_content##%s##\n",https_resp);
145 }
146 printf("[https_smdp] https_resp chunk %d!!!\n", ret);
147 }
148 else {
149 if (cont_len >= SMDP_HTTP_MAX_LEN) {
150 free(https_req);
151 printf("[https_smdp] https_recv too long = %d.\n", cont_len);
152 return NULL;
153 }
154 https_resp = malloc(cont_len + 1);
155 if (https_resp == NULL) {
156 free(https_req);
157 return NULL;
158 }
159
160 memset(https_resp, 0, cont_len + 1);
161 ret = https_read_content(&g_https_ct, https_resp, cont_len);
162 if(ret > 0) {
163 *res_len = ret;
164 https_resp[ret] = '\0'; //×Ö·û´®½áÊø±êʶ
165 printf("[https_smdp] https_read_content##%s##\n",https_resp);
166 }
167 else {
168 *res_len = -1;
169 free(https_req);
170 free(https_resp);
171 return NULL;
172 }
173 }
174 }
175 else if(ret == 204) {
176 *res_len = 0;
177 }
178 else {
179 printf("[https_smdp] https_resp code = %d.\n", ret);
180 }
181
182 free(https_req);
183 return https_resp;
184}
185/***************************************************************/
186//
187//ÌáÈ¡stringÀàÐÍÊý¾Ý
188//
189/***************************************************************/
190static char *lpa_parse_json_str(char *srcStr, char *key)
191{
192 cJSON *root = NULL;
193 cJSON *object = NULL;
194 char *value_str = NULL;
195 int value_len = 0;
196
197 root = cJSON_Parse(srcStr);
198 if (root == NULL) {
199 printf("root == NULL\n");
200 return NULL;
201 }
202
203 object = cJSON_GetObjectItem(root, key);
204 if (object == NULL) {
205 printf("key: %s not find\n", key);
206 cJSON_Delete(root);
207 return NULL;
208 }
209 //printf("key:%s-value:%s\n", key, object->valuestring);
210 value_len = strlen(object->valuestring);
211
212 value_str = malloc(value_len + 1);
213 if (value_str == NULL) {
214 cJSON_Delete(root);
215 return NULL;
216
217 }
218 memset(value_str, 0, value_len + 1);
219 strncpy(value_str, object->valuestring, value_len);
220
221 cJSON_Delete(root);
222 return value_str;
223}
224
225/***************************************************************/
226//
227//ÌáÈ¡stringÀàÐ͵Äbase64Êý¾Ý->decode->hex string
228//
229/***************************************************************/
230static char *lpa_parse_json_decode(char *srcStr, char *key)
231{
232 cJSON *root = NULL;
233 cJSON *object = NULL;
234 char *value_byte = NULL;
235 char *value_str = NULL;
236 int value_len = 0;
237
238 root = cJSON_Parse(srcStr);
239 if (root == NULL) {
240 printf("root == NULL\n");
241 return NULL;
242 }
243
244 object = cJSON_GetObjectItem(root, key);
245 if (object == NULL) {
246 printf("key: %s not find\n", key);
247 cJSON_Delete(root);
248 return NULL;
249 }
250
251 //printf("key:%s-value:%s\n", key, object->valuestring);
252 value_byte = lpa_base64_decode(object->valuestring, strlen(object->valuestring), &value_len);
253 if (value_byte == NULL) {
254 printf("lpa_base64_decode fail\n");
255 cJSON_Delete(root);
256 return NULL;
257 }
258
259 value_str = malloc(value_len*2 + 1);
260 if (value_str == NULL) {
261 free(value_byte);
262 cJSON_Delete(root);
263 return NULL;
264
265 }
266
267 memset(value_str, 0, value_len*2 + 1);
268 bytes2string(value_byte, value_str, value_len);
269 *(value_str + value_len*2) = '\0';
270 //printf("key:%s(%d)-hex:%s\n", key, value_len*2, value_str);
271 free(value_byte);
272 cJSON_Delete(root);
273 return value_str;
274}
275
276/***************************************************************/
277//
278//char srcStr[] =
279//"{"
280// "\"header\" : {"
281// "\"functionExecutionStatus\" : {"
282// "\"status\" : \"Executed-Success\""
283// "}"
284// "},"
285// "\"serverSigned1\": \"MEKAEAK3+mF5GUrrl+BlIUcujtSBEFK4u91WT/9GbQX+6pX/aoCDCmVzaW0ud28uY26EEEYRuTYzeka9iSyW+gSFF44=\","
286// "\"transactionId\": \"02B7FA6179194AEB97E06521472E8ED4\","
287// "\"serverSignature1\": \"XzdA9J6G6txPTOeOjQThaH/u/Wy/LOcZYec9reC65gjva7waj0XFBs0k551ynos1izFUpXbF8vctFw+/Enqu5aDQTA==\","
288// "\"serverCertificate\": \"MIIC1jCCAn2gAwIBAgIDAYb6MAoGCCqGSM49BAMCMH4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQIDAVKSUxJTjESMBAGA1UEBwwJQ0hBTkdDSFVOMQ0wCwYDVQQLDARDVUNBMQswCQYDVQQKDAJDVTEvMC0GA1UEAwwmQ2hpbmEgVW5pY29tIGVTSU0gUm9vdCBDQSBOSVNUUCBCWlRFU1QwHhcNMTkxMjI1MTUyNzEyWhcNMjAxMjI0MTUyNzEyWjB5MQswCQYDVQQGEwJDTjEnMCUGA1UECwweSW5ub3ZhdGl2ZSBCdXNpbmVzcyBEZXBhcnRtZW50MQ4wDAYDVQQKDAVWc2VuczExMC8GA1UEAwwoVW5pY29tIFZzZW5zIENvbW11bmljYXRpb24gQ28uIEx0ZChUZXN0KTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABC0BAmyq7voWvhezfZnAoQyRb5CgvPjFuGr7c4arFsbBFNYcv7w5C3Tp3wHD03HkIIhPuZrkx9kWNYeBrekfBw6jge4wgeswHwYDVR0jBBgwFoAUfA5UcBQ+qJmO2d8wBXTJLlqayx8wHQYDVR0OBBYEFC2+UJhg5G9/+zlI3mqf7YMrZHPMMA4GA1UdDwEB/wQEAwIHgDAXBgNVHSABAf8EDTALMAkGB2eBEgECAQQwFQYDVR0RBA4wDIgKKwYBBAGC9UYCBDBpBgNVHR8EYjBgMC6gLKAqhihodHRwOi8vY3JsLnVuaS1jYS5jb20uY24vZG93bmxvYWQvbjEuY3JsMC6gLKAqhihodHRwOi8vY3JsLnVuaS1jYS5jb20uY24vZG93bmxvYWQvbjIuY3JsMAoGCCqGSM49BAMCA0cAMEQCIBEAZfg9hJIax/xRpVIAjjmENrPr7q97E0Hv2s+8aOPDAiBaURKuxxzZ8/P0DKE7SmW+AhbxBl1TQd09sM6+Plzu9A==\","
289// "\"euiccCiPKIdToBeUsed\": \"BBR8DlRwFD6omY7Z3zAFdMkuWprLHw==\""
290//"}";
291//
292/***************************************************************/
293static char *lpa_parse_initauth_resp(char *srcStr)
294{
295 char *transid = NULL;
296 char *signed_hex = NULL;
297 char *signature_hex = NULL;
298 char *ciPKId_hex = NULL;
299 char *certificate_hex = NULL;
300
301 char *authser_apdu = NULL;
302 //1 transid
303 //2 get sig...
304 //3 genaner at and send
305
306 transid = lpa_parse_json_str(srcStr, "transactionId");
307 if (transid == NULL)
308 goto parse_END;
309 snprintf(g_transid, sizeof(g_transid), "%s", transid);
310
311
312 signed_hex = lpa_parse_json_decode(srcStr, "serverSigned1");
313 if (signed_hex == NULL)
314 goto parse_END;
315
316 signature_hex = lpa_parse_json_decode(srcStr, "serverSignature1");
317 if (signature_hex == NULL)
318 goto parse_END;
319
320 ciPKId_hex = lpa_parse_json_decode(srcStr, "euiccCiPKIdToBeUsed");
321 if (ciPKId_hex == NULL)
322 goto parse_END;
323
324 certificate_hex = lpa_parse_json_decode(srcStr, "serverCertificate");
325 if (certificate_hex == NULL)
326 goto parse_END;
327
328//×îºóÒ»¶ÎÊÇɶ£¿ctxparams
329//80E29103£¿91±íʾ½öÒ»¶Î»òÕß×îºóÒ»¶Î
330//×î×îºóµÄ00²»ËãÔÚ³¤¶ÈÄÚ
331// 80E21100FFBF38(00 = i, ff =len)
332// ffÖ®ºó×¶àÉÙÏß²»¹Ü
333// ÏÈËãbf38ºó×¶àÉÙ£¬½«bf38ºóÊý¾ÝÏÈ×éºÃ£¬ÔÙ¼Ó
334// 80E2110iLLÀ´·Ö¸îat
335// ²¢ÔÚ×îºóÒ»¶ÎÏ·¢ºó¶ÁÈÏÖ¤·þÎñÆ÷µÄ²ÎÊýat
336
337 //matchingId´Ó¼¤»îÂëÖÐÈ¡£¬Ä¿Ç°Ã»ÓÃ
338 authser_apdu = AuthenticateServer(signed_hex, signature_hex, ciPKId_hex, certificate_hex, "", g_imei);
339
340
341parse_END:
342 if (transid != NULL)
343 free(transid);
344 if (signed_hex != NULL)
345 free(signed_hex);
346 if (signature_hex != NULL)
347 free(signature_hex);
348 if (ciPKId_hex != NULL)
349 free(ciPKId_hex);
350 if (certificate_hex != NULL)
351 free(certificate_hex);
352
353 return authser_apdu;
354}
355
356static char *lpa_parse_authcli_resp(char *srcStr)
357{
358 char *transid = NULL;
359 char *signed2_hex = NULL;
360 char *signature2_hex = NULL;
361 char *certi_hex = NULL;
362 //char *meta_hex = NULL;
363
364 char *predl_apdu = NULL;
365
366 transid = lpa_parse_json_str(srcStr, "transactionId");
367 if (transid == NULL)
368 goto parse_END;
369 snprintf(g_transid, sizeof(g_transid), "%s", transid);
370
371
372 signed2_hex = lpa_parse_json_decode(srcStr, "smdpSigned2");
373 if (signed2_hex == NULL)
374 goto parse_END;
375
376 signature2_hex = lpa_parse_json_decode(srcStr, "smdpSignature2");
377 if (signature2_hex == NULL)
378 goto parse_END;
379
380 certi_hex = lpa_parse_json_decode(srcStr, "smdpCertificate");
381 if (certi_hex == NULL)
382 goto parse_END;
383
384 //meta_hex = lpa_parse_json_decode(srcStr, "profileMetadata");
385 //if (meta_hex == NULL)
386 // goto parse_END;
387
388 predl_apdu = PrepareDownload(transid, signed2_hex, signature2_hex, certi_hex, "");
389
390parse_END:
391 if (transid != NULL)
392 free(transid);
393 if (signed2_hex != NULL)
394 free(signed2_hex);
395 if (signature2_hex != NULL)
396 free(signature2_hex);
397 if (certi_hex != NULL)
398 free(certi_hex);
399 //if (meta_hex != NULL)
400 // free(meta_hex);
401
402 return predl_apdu;
403}
404
405static char *lpa_parse_getbpp_resp(char *srcStr)
406{
407 char *transid = NULL;
408 char *bpp_b64 = NULL;
409
410 char *notify_apdu = NULL;
411
412 transid = lpa_parse_json_str(srcStr, "transactionId");
413 if (transid == NULL)
414 goto parse_END;
415 snprintf(g_transid, sizeof(g_transid), "%s", transid);
416
417
418 bpp_b64 = lpa_parse_json_str(srcStr, "boundProfilePackage");
419 if (bpp_b64 == NULL)
420 goto parse_END;
421
422 notify_apdu = LoadBoundProfilePackage(bpp_b64);
423
424parse_END:
425 if (transid != NULL)
426 free(transid);
427 if (bpp_b64 != NULL)
428 free(bpp_b64);
429
430 return notify_apdu;
431}
432
433
434//·µ»ØjsonÊý¾Ý¸øÏÂÒ»²½µ÷ÓÃ
435static char *lpa_initauth(void)
436{
437 int ret = -1;
438 char *euiccChallenge = NULL;
439 char *euiccInfo1 = NULL;
440 char *ia_json = NULL;
441 char *https_resp = NULL;
442 char *resp_apdu = NULL;
443
444 euiccChallenge = GetEUICCChallenge();
445 if (euiccChallenge == NULL) {
446 return NULL;
447 }
448
449 euiccInfo1 = GetEUICCInfo(TRUE);
450 if (euiccInfo1 == NULL) {
451 free(euiccChallenge);
452 return NULL;
453 }
454
455 ia_json = InitiateAuthentication(euiccChallenge, euiccInfo1, g_https_ct.host);
456 if (ia_json == NULL) {
457 free(euiccChallenge);
458 free(euiccInfo1);
459 return NULL;
460 }
461
462 https_resp = lpa_smdp_session("initiateAuthentication", ia_json, &ret);
463 if (https_resp != NULL) {
464 resp_apdu = lpa_parse_initauth_resp(https_resp);
465 free(https_resp);
466 }
467
468 free(euiccChallenge);
469 free(euiccInfo1);
470 free(ia_json);
471 return resp_apdu;
472}
473
474static char *lpa_authclient(char *as_apdu)
475{
476 int ret = -1;
477
478 char *ac_json = NULL;
479 char *https_resp = NULL;
480 char *resp_apdu = NULL;
481
482 ac_json = AuthenticateClient(g_transid, as_apdu);
483 if (ac_json == NULL) {
484 return NULL;
485 }
486
487 https_resp = lpa_smdp_session("authenticateClient", ac_json, &ret);
488 if (https_resp != NULL) {
489 resp_apdu = lpa_parse_authcli_resp(https_resp);
490 free(https_resp);
491 }
492
493 free(ac_json);
494 return resp_apdu;
495}
496
497static char *lpa_getbpp(char *pdl_apdu)
498{
499 int ret = -1;
500
501 char *bpp_json = NULL;
502 char *https_resp = NULL;
503 char *resp_apdu = NULL;
504
505 bpp_json = GetBoundProfilePackage(g_transid, pdl_apdu);
506 if (bpp_json == NULL) {
507 return NULL;
508 }
509
510 https_resp = lpa_smdp_session("getBoundProfilePackage", bpp_json, &ret);
511 if (ret > 0) {
512 resp_apdu = lpa_parse_getbpp_resp(https_resp);
513 free(https_resp);
514 }
515
516 free(bpp_json);
517 return resp_apdu;
518}
519
520static int lpa_notification(char *notify_apdu)
521{
522 int ret = -1;
523
524 char *notify_json = NULL;
525 char *https_resp = NULL;
526
527 notify_json = HandleNotification(notify_apdu);
528 if (notify_json == NULL) {
529 return ret;
530 }
531 https_resp = lpa_smdp_session("handleNotification", notify_json, &ret);
532 if (https_resp != NULL)
533 free(https_resp);
534 //no resp?
535
536 free(notify_json);
537 return ret;
538}
539
540/***************************************************************/
541//
542//"1$esim.wo.cn$$1.3.6.1.4.1.47814.2.4"
543//
544/***************************************************************/
545static char *parse_accode(char *activecode)
546{
547 char *save = NULL;
548 char *host = NULL;
549 char *tmp = NULL;
550 tmp = strtok_r(activecode, "$", &save);
551 if (tmp == NULL)
552 return NULL;
553 tmp = strtok_r(NULL, "$", &save);
554 if (tmp == NULL)
555 return NULL;
556
557 host = malloc(APDU_RESP_LEN);
558 if (host == NULL)
559 return NULL;
560 memset(host, 0, APDU_RESP_LEN);
561 strncpy(host, tmp, APDU_RESP_LEN-1);
562
563 printf("server:%s\n", host);
564 return host;
565}
566
567static int downloadProfile(char *smdpAddress)
568{
569 int res = -1;
570 char *authser_apdu = NULL;//auth server apdu
571 char *predl_apdu = NULL;//prepare download apdu
572 char *notify_apdu = NULL;//Notification apdu
573 int notify_res = -1;
574 int notify_check = -1;
575 //1 creat https
576 //2 get auth, send
577
578 res = lpa_connect_smdp(smdpAddress);
579 if (res != 0) {
580 res = -2;
581 goto download_END;
582 }
583
584 authser_apdu = lpa_initauth();
585 if (authser_apdu == NULL || strlen(authser_apdu) == 0) {
586 res = -2;
587 goto download_END;
588 }
589
590 predl_apdu = lpa_authclient(authser_apdu);
591 if (predl_apdu == NULL || strlen(predl_apdu) == 0) {
592 res = -2;
593 goto download_END;
594 }
595
596 notify_apdu = lpa_getbpp(predl_apdu);
597 if (notify_apdu == NULL || strlen(notify_apdu) == 0) {
598 res = -2;
599 goto download_END;
600 }
601//dtest
602#if 1
603 notify_res = lpa_notification(notify_apdu);
604 if (notify_res == -1) {
605 printf("lpa_notification fail\n");
606 //goto download_END;//skip, use updata result
607 }
608#endif
609
610 notify_check = lpa_parse_iccid_apdu(notify_apdu, curent_iccid, sizeof(curent_iccid));
611 if (notify_check == -1)
612 goto download_END;
613
614
615 res = 0;
616download_END:
617 if (authser_apdu != NULL)
618 free(authser_apdu);
619 if (predl_apdu != NULL)
620 free(predl_apdu);
621 if (notify_apdu != NULL)
622 free(notify_apdu);
623
624 lpa_disconn_smdp(smdpAddress);
625 return res;
626}
627
628/***************************************************************/
629//
630//ÊäÈ뼤»îÂ뷽ʽÏÂÔØprofile
631//È·ÈÏÂëδÓà confirmcode = NULL
632//
633/***************************************************************/
634int downloadProfileByAc(char *activecode, char *confirmcode)
635{
636 int res = -1;
637 char *smdpAddress = NULL;
638
639 char dl_retry[6] = {0};
640 int count = 0;
641 int i = 0;
642
643 sc_cfg_get("lpa_dl_retry", dl_retry, sizeof(dl_retry));
644 count = atoi(dl_retry);
645 printf("lpa_updata_retry:%s,%d\n", dl_retry, count);
646 if (count <= 0 || count > 10) { //kw 3
647 count = 1;
648 }
649
650 smdpAddress = parse_accode(activecode);
651 if (smdpAddress == NULL)
652 return -1;
653
654 for (i = 0; i < count; i++) {
655 res = downloadProfile(smdpAddress);
656 if (res == -2 && i < count-1) {
657 //retry
658 sleep(SMDP_DL_INTERVAL);
659 continue;
660 }
661 break;
662 }
663
664 free(smdpAddress);
665 return res;
666}
667
668#if 0
669int downloadProfileByEid(void)
670{
671 int res = -1;
672 char *smdpAddress = "esim.wo.cn";//get from default
673
674 res = downloadProfile(smdpAddress);
675
676 return res;
677}
678#endif
679
680/***************************************************************/
681//
682//ÆôÓÃprofile
683//in: iccid 20
684//
685//parse 8001xx return xx:
686//0£ºOK
687//1£ºiccidOrAidNotFound£»
688//2£ºprofileNotInDisabledState£»
689//3£ºdisallowedByPolicy£»
690//4£ºwrongProfileReenabling£»
691//5£ºcatBusy£»
692//127£ºundefinedError
693//ÆäÓà·µ»ØÖµ²Î¿¼6.10½Ú
694//
695/***************************************************************/
696int enableProfile(char *iccid)
697{
698 char *apdu = NULL;
699 int res = 127;
700 apdu = EnableProfile(iccid);
701 if (apdu == NULL)
702 return 127;
703 errno = 0;
704 res = strtol(apdu, NULL, 16);
705 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
706 {
707 printf("strtol errno %d: %s\n", errno, strerror(errno));
708 }
709 free(apdu);
710 return res;
711}
712
713/***************************************************************/
714//
715//½ûÓÃprofile
716//
717/***************************************************************/
718int disableProfile(char * iccid)
719{
720 char *apdu = NULL;
721 int res = 127;
722 apdu = DisableProfile(iccid);
723 if (apdu == NULL)
724 return 127;
725 errno = 0;
726 res = strtol(apdu, NULL, 16);
727 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
728 {
729 printf("strtol errno %d: %s\n", errno, strerror(errno));
730 }
731 free(apdu);
732 return res;
733}
734
735
736/***************************************************************/
737//
738//ɾ³ýprofile
739//
740/***************************************************************/
741int deleteProfile(char * iccid)
742{
743 char *apdu = NULL;
744 int res = 127;
745 apdu = DeleteProfile(iccid);
746 if (apdu == NULL)
747 return 127;
748 errno = 0;
749 res = strtol(apdu, NULL, 16);
750 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
751 {
752 printf("strtol errno %d: %s\n", errno, strerror(errno));
753 }
754 free(apdu);
755 return res;
756}
757
758
759int memoryReset(void)
760{
761 char *apdu = NULL;
762 int res = 127;
763 apdu = EUICCMemoryReset();
764 if (apdu == NULL)
765 return 127;
766 errno = 0;
767 res = strtol(apdu, NULL, 16);
768 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
769 {
770 printf("strtol errno %d: %s\n", errno, strerror(errno));
771 }
772 free(apdu);
773 return res;
774}
775
776//limit 10
777static char *lap_parse_profile_list(char *pdu, int *list_n)
778{
779 char *js_list = NULL;
780
781 char *profile = NULL;
782 char *iccid = NULL;
783 char *state = NULL;
784 int status = 0;
785 int i = 0;
786 char *tmp_pdu = pdu;
787 char *offset = NULL;
788
789 js_list = malloc(APDU_RESP_LEN);
790 if (js_list == NULL)
791 return NULL;
792 memset(js_list, 0, APDU_RESP_LEN);
793
794 while(i < 10 && strlen(tmp_pdu) > 0) {
795 profile = lpa_tag_apdu_from_atresp(tmp_pdu, 0xE3);
796 if (profile == NULL)
797 break;
798
799 iccid = lpa_tag_apdu_from_atresp(tmp_pdu, 0x5A);
800 if (iccid == NULL) {
801 free(profile);
802 break;
803 }
804 lpa_trans_iccid(iccid, strlen(iccid));
805
806 state = lpa_tag_apdu_from_atresp(tmp_pdu, 0x9F70);
807 if (state == NULL) {
808 free(profile);
809 free(iccid);
810 break;
811 }
812 errno = 0;
813 status = strtol(state, NULL, 16);
814 if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
815 {
816 printf("strtol errno %d: %s\n", errno, strerror(errno));
817 }
818 if (i == 0) {
819 snprintf(js_list, APDU_RESP_LEN,
820 "{\"ICCID\":\"%s\",\"STATUS\":%d}", iccid, status);
821 }
822 else {
823 snprintf(js_list + strlen(js_list), APDU_RESP_LEN - strlen(js_list),
824 ",{\"ICCID\":\"%s\",\"STATUS\":%d}", iccid, status);
825 }
826
827 offset = strstr(tmp_pdu, profile);
828 if (offset == NULL) {
829 free(profile);
830 free(iccid);
831 free(state);
832 break;
833 }
834 tmp_pdu = offset + strlen(profile);
835 free(profile);
836 free(iccid);
837 free(state);
838 i++;
839
840 }
841 *list_n = i;
842 return js_list;
843}
844
845/***************************************************************/
846//
847//·µ»Ø¸öÊý£¬ºÍjson array[iccid, state]
848//
849/***************************************************************/
850int getProfileList(char **info)
851{
852 char *apdu = NULL;
853 int prof_num = 0;
854
855 apdu = GetProfilesInfo(NULL);
856 if (apdu == NULL)
857 return prof_num;
858
859
860 *info = lap_parse_profile_list(apdu, &prof_num);
861
862
863 free(apdu);
864 return prof_num;
865}
866