[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/lib/liblpa/lpa_esim_api.c b/ap/lib/liblpa/lpa_esim_api.c
new file mode 100755
index 0000000..509d047
--- /dev/null
+++ b/ap/lib/liblpa/lpa_esim_api.c
@@ -0,0 +1,866 @@
+/***************************************************************/
+//
+//²Î¼û ÖйúÁªÍ¨esimÄ£×éÀ©Õ¹Ö¸Áî¼¼Êõ¹æ·¶
+//
+/***************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <termios.h>
+#include <errno.h>
+
+#include "lpa_inner.h"
+
+
+#define SMDP_PORT 443
+#define SMDP_DL_INTERVAL 95//ÏÂÔØ¼ä¸ô>90s
+
+
+//´¥·¢·þÎñÆ÷httpÇëÇó
+static char smdp_https_req[] =
+ "POST /gsma/rsp2/es9plus/%s HTTP/1.1\r\n"
+ "Host: %s\r\n"
+ "User-Agent: gsma-rsp-lpad\r\n"
+ "X-Admin-Protocol: gsma/rsp/v2.2.0\r\n"
+ "Content-Type: application/json\r\n"
+ "Content-Length: %d\r\n"
+ "\r\n%s\r\n";
+
+static https_context_t g_https_ct = {0};
+static char g_transid[MAX_TRANSID_LEN] = {0};
+char curent_iccid[ICCID_LEN+1] = {0};
+
+extern char g_imei[MAX_IMEI_LEN];
+
+//iccid from bpp install result, if null, failed
+//ISD-P AID, tag '4F';ICCID, tag '5A'. if succ, has AID
+static int lpa_parse_iccid_apdu(char *apdu, char *iccid, int size)
+{
+ int apdu_len = strlen(apdu);
+ unsigned char *apdu_byte = malloc(apdu_len/2 + 1);
+ int apdu_byte_len = 0;
+ char *tag_hex = NULL;
+ char has_iccid[ICCID_LEN+1] = {0};
+
+ if (apdu_byte == NULL) {
+ printf("lpa_parse_iccid_apdu no memory\n");
+ return -1;
+ }
+ memset(apdu_byte, 0, apdu_len/2 + 1);
+
+ apdu_byte_len = string2bytes(apdu, apdu_byte, apdu_len);
+
+ tag_hex = lpa_tlv_get_val_by_tag(apdu_byte, apdu_byte_len, 0x4F);
+ if (tag_hex == NULL) {
+ printf("lpa_parse_iccid_apdu not find AID\n");
+ free(apdu_byte);
+ return -1;
+ }
+ printf("lpa aid:%s\n", tag_hex);
+ free(tag_hex);
+ tag_hex = NULL;
+
+ tag_hex = lpa_tlv_get_val_by_tag(apdu_byte, apdu_byte_len, 0x5A);
+ if (tag_hex == NULL) {
+ printf("lpa_parse_iccid_apdu not find iccid\n");
+ free(apdu_byte);
+ return -1;
+
+ }
+
+ snprintf(iccid, size, "%s", tag_hex);
+
+ sc_cfg_get("lpa_bpp_iccid", has_iccid, sizeof(has_iccid));
+ if (strcmp(iccid, has_iccid) != 0) {
+ sc_cfg_set("lpa_bpp_iccid", iccid);
+ sc_cfg_save();
+ printf("lpa iccid not same?\n");
+ }
+
+ printf("lpa iccid:%s\n", iccid);
+
+ free(apdu_byte);
+ free(tag_hex);
+ return 0;
+}
+
+static int lpa_connect_smdp(char *host)
+{
+ SSL_library_init();
+
+ g_https_ct.port=SMDP_PORT;
+ g_https_ct.host=host;
+ g_https_ct.path=NULL;
+ return https_init(&g_https_ct);
+}
+
+static void lpa_disconn_smdp(char *host)
+{
+ https_uninit(&g_https_ct);
+}
+
+static char *lpa_smdp_session(char *path, char *req_data, int *res_len)
+{
+ int ret = -1;
+ int cont_len = 0;
+ char *https_req = NULL;
+ char *https_resp = NULL;
+ int https_req_len = strlen(smdp_https_req)+strlen(path)+strlen(g_https_ct.host)+strlen(req_data)+32;
+
+ *res_len = -1;
+
+ if (https_req_len > SMDP_HTTP_MAX_LEN)
+ return NULL;
+
+ https_req = malloc(https_req_len);
+ if (https_req == NULL)
+ return NULL;
+
+ memset(https_req, 0, https_req_len);
+ g_https_ct.path = path;
+ ret = snprintf(https_req, https_req_len, smdp_https_req,
+ g_https_ct.path, g_https_ct.host, strlen(req_data), req_data);
+
+ printf("[https_smdp]req[%d]:##%s##\n", strlen(https_req), https_req);
+ ret = https_write(&g_https_ct, https_req, ret);
+ if (ret == -1) {
+ //EAGAIN?
+ free(https_req);
+ printf("[https_smdp] https_write err:%d.\n", errno);
+ return NULL;
+ }
+
+ ret = https_get_status_code(&g_https_ct, &cont_len);
+ if(ret == 200) {
+ printf("[https_smdp] https_recv len:%d.\n", cont_len);
+ if (cont_len == HTTP_CHUNKED_FLAG) {
+ ret = https_read_chunked_content(&g_https_ct, &https_resp, SMDP_HTTP_MAX_LEN);
+ if(ret > 0) {
+ *res_len = ret;
+ https_resp[ret] = '\0'; //×Ö·û´®½áÊø±êʶ
+ printf("[https_smdp] https_write https_resp_content##%s##\n",https_resp);
+ }
+ printf("[https_smdp] https_resp chunk %d!!!\n", ret);
+ }
+ else {
+ if (cont_len >= SMDP_HTTP_MAX_LEN) {
+ free(https_req);
+ printf("[https_smdp] https_recv too long = %d.\n", cont_len);
+ return NULL;
+ }
+ https_resp = malloc(cont_len + 1);
+ if (https_resp == NULL) {
+ free(https_req);
+ return NULL;
+ }
+
+ memset(https_resp, 0, cont_len + 1);
+ ret = https_read_content(&g_https_ct, https_resp, cont_len);
+ if(ret > 0) {
+ *res_len = ret;
+ https_resp[ret] = '\0'; //×Ö·û´®½áÊø±êʶ
+ printf("[https_smdp] https_read_content##%s##\n",https_resp);
+ }
+ else {
+ *res_len = -1;
+ free(https_req);
+ free(https_resp);
+ return NULL;
+ }
+ }
+ }
+ else if(ret == 204) {
+ *res_len = 0;
+ }
+ else {
+ printf("[https_smdp] https_resp code = %d.\n", ret);
+ }
+
+ free(https_req);
+ return https_resp;
+}
+/***************************************************************/
+//
+//ÌáÈ¡stringÀàÐÍÊý¾Ý
+//
+/***************************************************************/
+static char *lpa_parse_json_str(char *srcStr, char *key)
+{
+ cJSON *root = NULL;
+ cJSON *object = NULL;
+ char *value_str = NULL;
+ int value_len = 0;
+
+ root = cJSON_Parse(srcStr);
+ if (root == NULL) {
+ printf("root == NULL\n");
+ return NULL;
+ }
+
+ object = cJSON_GetObjectItem(root, key);
+ if (object == NULL) {
+ printf("key: %s not find\n", key);
+ cJSON_Delete(root);
+ return NULL;
+ }
+ //printf("key:%s-value:%s\n", key, object->valuestring);
+ value_len = strlen(object->valuestring);
+
+ value_str = malloc(value_len + 1);
+ if (value_str == NULL) {
+ cJSON_Delete(root);
+ return NULL;
+
+ }
+ memset(value_str, 0, value_len + 1);
+ strncpy(value_str, object->valuestring, value_len);
+
+ cJSON_Delete(root);
+ return value_str;
+}
+
+/***************************************************************/
+//
+//ÌáÈ¡stringÀàÐ͵Äbase64Êý¾Ý->decode->hex string
+//
+/***************************************************************/
+static char *lpa_parse_json_decode(char *srcStr, char *key)
+{
+ cJSON *root = NULL;
+ cJSON *object = NULL;
+ char *value_byte = NULL;
+ char *value_str = NULL;
+ int value_len = 0;
+
+ root = cJSON_Parse(srcStr);
+ if (root == NULL) {
+ printf("root == NULL\n");
+ return NULL;
+ }
+
+ object = cJSON_GetObjectItem(root, key);
+ if (object == NULL) {
+ printf("key: %s not find\n", key);
+ cJSON_Delete(root);
+ return NULL;
+ }
+
+ //printf("key:%s-value:%s\n", key, object->valuestring);
+ value_byte = lpa_base64_decode(object->valuestring, strlen(object->valuestring), &value_len);
+ if (value_byte == NULL) {
+ printf("lpa_base64_decode fail\n");
+ cJSON_Delete(root);
+ return NULL;
+ }
+
+ value_str = malloc(value_len*2 + 1);
+ if (value_str == NULL) {
+ free(value_byte);
+ cJSON_Delete(root);
+ return NULL;
+
+ }
+
+ memset(value_str, 0, value_len*2 + 1);
+ bytes2string(value_byte, value_str, value_len);
+ *(value_str + value_len*2) = '\0';
+ //printf("key:%s(%d)-hex:%s\n", key, value_len*2, value_str);
+ free(value_byte);
+ cJSON_Delete(root);
+ return value_str;
+}
+
+/***************************************************************/
+//
+//char srcStr[] =
+//"{"
+// "\"header\" : {"
+// "\"functionExecutionStatus\" : {"
+// "\"status\" : \"Executed-Success\""
+// "}"
+// "},"
+// "\"serverSigned1\": \"MEKAEAK3+mF5GUrrl+BlIUcujtSBEFK4u91WT/9GbQX+6pX/aoCDCmVzaW0ud28uY26EEEYRuTYzeka9iSyW+gSFF44=\","
+// "\"transactionId\": \"02B7FA6179194AEB97E06521472E8ED4\","
+// "\"serverSignature1\": \"XzdA9J6G6txPTOeOjQThaH/u/Wy/LOcZYec9reC65gjva7waj0XFBs0k551ynos1izFUpXbF8vctFw+/Enqu5aDQTA==\","
+// "\"serverCertificate\": \"MIIC1jCCAn2gAwIBAgIDAYb6MAoGCCqGSM49BAMCMH4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQIDAVKSUxJTjESMBAGA1UEBwwJQ0hBTkdDSFVOMQ0wCwYDVQQLDARDVUNBMQswCQYDVQQKDAJDVTEvMC0GA1UEAwwmQ2hpbmEgVW5pY29tIGVTSU0gUm9vdCBDQSBOSVNUUCBCWlRFU1QwHhcNMTkxMjI1MTUyNzEyWhcNMjAxMjI0MTUyNzEyWjB5MQswCQYDVQQGEwJDTjEnMCUGA1UECwweSW5ub3ZhdGl2ZSBCdXNpbmVzcyBEZXBhcnRtZW50MQ4wDAYDVQQKDAVWc2VuczExMC8GA1UEAwwoVW5pY29tIFZzZW5zIENvbW11bmljYXRpb24gQ28uIEx0ZChUZXN0KTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABC0BAmyq7voWvhezfZnAoQyRb5CgvPjFuGr7c4arFsbBFNYcv7w5C3Tp3wHD03HkIIhPuZrkx9kWNYeBrekfBw6jge4wgeswHwYDVR0jBBgwFoAUfA5UcBQ+qJmO2d8wBXTJLlqayx8wHQYDVR0OBBYEFC2+UJhg5G9/+zlI3mqf7YMrZHPMMA4GA1UdDwEB/wQEAwIHgDAXBgNVHSABAf8EDTALMAkGB2eBEgECAQQwFQYDVR0RBA4wDIgKKwYBBAGC9UYCBDBpBgNVHR8EYjBgMC6gLKAqhihodHRwOi8vY3JsLnVuaS1jYS5jb20uY24vZG93bmxvYWQvbjEuY3JsMC6gLKAqhihodHRwOi8vY3JsLnVuaS1jYS5jb20uY24vZG93bmxvYWQvbjIuY3JsMAoGCCqGSM49BAMCA0cAMEQCIBEAZfg9hJIax/xRpVIAjjmENrPr7q97E0Hv2s+8aOPDAiBaURKuxxzZ8/P0DKE7SmW+AhbxBl1TQd09sM6+Plzu9A==\","
+// "\"euiccCiPKIdToBeUsed\": \"BBR8DlRwFD6omY7Z3zAFdMkuWprLHw==\""
+//"}";
+//
+/***************************************************************/
+static char *lpa_parse_initauth_resp(char *srcStr)
+{
+ char *transid = NULL;
+ char *signed_hex = NULL;
+ char *signature_hex = NULL;
+ char *ciPKId_hex = NULL;
+ char *certificate_hex = NULL;
+
+ char *authser_apdu = NULL;
+ //1 transid
+ //2 get sig...
+ //3 genaner at and send
+
+ transid = lpa_parse_json_str(srcStr, "transactionId");
+ if (transid == NULL)
+ goto parse_END;
+ snprintf(g_transid, sizeof(g_transid), "%s", transid);
+
+
+ signed_hex = lpa_parse_json_decode(srcStr, "serverSigned1");
+ if (signed_hex == NULL)
+ goto parse_END;
+
+ signature_hex = lpa_parse_json_decode(srcStr, "serverSignature1");
+ if (signature_hex == NULL)
+ goto parse_END;
+
+ ciPKId_hex = lpa_parse_json_decode(srcStr, "euiccCiPKIdToBeUsed");
+ if (ciPKId_hex == NULL)
+ goto parse_END;
+
+ certificate_hex = lpa_parse_json_decode(srcStr, "serverCertificate");
+ if (certificate_hex == NULL)
+ goto parse_END;
+
+//×îºóÒ»¶ÎÊÇɶ£¿ctxparams
+//80E29103£¿91±íʾ½öÒ»¶Î»òÕß×îºóÒ»¶Î
+//×î×îºóµÄ00²»ËãÔÚ³¤¶ÈÄÚ
+// 80E21100FFBF38(00 = i, ff =len)
+// ffÖ®ºó×¶àÉÙÏß²»¹Ü
+// ÏÈËãbf38ºó×¶àÉÙ£¬½«bf38ºóÊý¾ÝÏÈ×éºÃ£¬ÔÙ¼Ó
+// 80E2110iLLÀ´·Ö¸îat
+// ²¢ÔÚ×îºóÒ»¶ÎÏ·¢ºó¶ÁÈÏÖ¤·þÎñÆ÷µÄ²ÎÊýat
+
+ //matchingId´Ó¼¤»îÂëÖÐÈ¡£¬Ä¿Ç°Ã»ÓÃ
+ authser_apdu = AuthenticateServer(signed_hex, signature_hex, ciPKId_hex, certificate_hex, "", g_imei);
+
+
+parse_END:
+ if (transid != NULL)
+ free(transid);
+ if (signed_hex != NULL)
+ free(signed_hex);
+ if (signature_hex != NULL)
+ free(signature_hex);
+ if (ciPKId_hex != NULL)
+ free(ciPKId_hex);
+ if (certificate_hex != NULL)
+ free(certificate_hex);
+
+ return authser_apdu;
+}
+
+static char *lpa_parse_authcli_resp(char *srcStr)
+{
+ char *transid = NULL;
+ char *signed2_hex = NULL;
+ char *signature2_hex = NULL;
+ char *certi_hex = NULL;
+ //char *meta_hex = NULL;
+
+ char *predl_apdu = NULL;
+
+ transid = lpa_parse_json_str(srcStr, "transactionId");
+ if (transid == NULL)
+ goto parse_END;
+ snprintf(g_transid, sizeof(g_transid), "%s", transid);
+
+
+ signed2_hex = lpa_parse_json_decode(srcStr, "smdpSigned2");
+ if (signed2_hex == NULL)
+ goto parse_END;
+
+ signature2_hex = lpa_parse_json_decode(srcStr, "smdpSignature2");
+ if (signature2_hex == NULL)
+ goto parse_END;
+
+ certi_hex = lpa_parse_json_decode(srcStr, "smdpCertificate");
+ if (certi_hex == NULL)
+ goto parse_END;
+
+ //meta_hex = lpa_parse_json_decode(srcStr, "profileMetadata");
+ //if (meta_hex == NULL)
+ // goto parse_END;
+
+ predl_apdu = PrepareDownload(transid, signed2_hex, signature2_hex, certi_hex, "");
+
+parse_END:
+ if (transid != NULL)
+ free(transid);
+ if (signed2_hex != NULL)
+ free(signed2_hex);
+ if (signature2_hex != NULL)
+ free(signature2_hex);
+ if (certi_hex != NULL)
+ free(certi_hex);
+ //if (meta_hex != NULL)
+ // free(meta_hex);
+
+ return predl_apdu;
+}
+
+static char *lpa_parse_getbpp_resp(char *srcStr)
+{
+ char *transid = NULL;
+ char *bpp_b64 = NULL;
+
+ char *notify_apdu = NULL;
+
+ transid = lpa_parse_json_str(srcStr, "transactionId");
+ if (transid == NULL)
+ goto parse_END;
+ snprintf(g_transid, sizeof(g_transid), "%s", transid);
+
+
+ bpp_b64 = lpa_parse_json_str(srcStr, "boundProfilePackage");
+ if (bpp_b64 == NULL)
+ goto parse_END;
+
+ notify_apdu = LoadBoundProfilePackage(bpp_b64);
+
+parse_END:
+ if (transid != NULL)
+ free(transid);
+ if (bpp_b64 != NULL)
+ free(bpp_b64);
+
+ return notify_apdu;
+}
+
+
+//·µ»ØjsonÊý¾Ý¸øÏÂÒ»²½µ÷ÓÃ
+static char *lpa_initauth(void)
+{
+ int ret = -1;
+ char *euiccChallenge = NULL;
+ char *euiccInfo1 = NULL;
+ char *ia_json = NULL;
+ char *https_resp = NULL;
+ char *resp_apdu = NULL;
+
+ euiccChallenge = GetEUICCChallenge();
+ if (euiccChallenge == NULL) {
+ return NULL;
+ }
+
+ euiccInfo1 = GetEUICCInfo(TRUE);
+ if (euiccInfo1 == NULL) {
+ free(euiccChallenge);
+ return NULL;
+ }
+
+ ia_json = InitiateAuthentication(euiccChallenge, euiccInfo1, g_https_ct.host);
+ if (ia_json == NULL) {
+ free(euiccChallenge);
+ free(euiccInfo1);
+ return NULL;
+ }
+
+ https_resp = lpa_smdp_session("initiateAuthentication", ia_json, &ret);
+ if (https_resp != NULL) {
+ resp_apdu = lpa_parse_initauth_resp(https_resp);
+ free(https_resp);
+ }
+
+ free(euiccChallenge);
+ free(euiccInfo1);
+ free(ia_json);
+ return resp_apdu;
+}
+
+static char *lpa_authclient(char *as_apdu)
+{
+ int ret = -1;
+
+ char *ac_json = NULL;
+ char *https_resp = NULL;
+ char *resp_apdu = NULL;
+
+ ac_json = AuthenticateClient(g_transid, as_apdu);
+ if (ac_json == NULL) {
+ return NULL;
+ }
+
+ https_resp = lpa_smdp_session("authenticateClient", ac_json, &ret);
+ if (https_resp != NULL) {
+ resp_apdu = lpa_parse_authcli_resp(https_resp);
+ free(https_resp);
+ }
+
+ free(ac_json);
+ return resp_apdu;
+}
+
+static char *lpa_getbpp(char *pdl_apdu)
+{
+ int ret = -1;
+
+ char *bpp_json = NULL;
+ char *https_resp = NULL;
+ char *resp_apdu = NULL;
+
+ bpp_json = GetBoundProfilePackage(g_transid, pdl_apdu);
+ if (bpp_json == NULL) {
+ return NULL;
+ }
+
+ https_resp = lpa_smdp_session("getBoundProfilePackage", bpp_json, &ret);
+ if (ret > 0) {
+ resp_apdu = lpa_parse_getbpp_resp(https_resp);
+ free(https_resp);
+ }
+
+ free(bpp_json);
+ return resp_apdu;
+}
+
+static int lpa_notification(char *notify_apdu)
+{
+ int ret = -1;
+
+ char *notify_json = NULL;
+ char *https_resp = NULL;
+
+ notify_json = HandleNotification(notify_apdu);
+ if (notify_json == NULL) {
+ return ret;
+ }
+ https_resp = lpa_smdp_session("handleNotification", notify_json, &ret);
+ if (https_resp != NULL)
+ free(https_resp);
+ //no resp?
+
+ free(notify_json);
+ return ret;
+}
+
+/***************************************************************/
+//
+//"1$esim.wo.cn$$1.3.6.1.4.1.47814.2.4"
+//
+/***************************************************************/
+static char *parse_accode(char *activecode)
+{
+ char *save = NULL;
+ char *host = NULL;
+ char *tmp = NULL;
+ tmp = strtok_r(activecode, "$", &save);
+ if (tmp == NULL)
+ return NULL;
+ tmp = strtok_r(NULL, "$", &save);
+ if (tmp == NULL)
+ return NULL;
+
+ host = malloc(APDU_RESP_LEN);
+ if (host == NULL)
+ return NULL;
+ memset(host, 0, APDU_RESP_LEN);
+ strncpy(host, tmp, APDU_RESP_LEN-1);
+
+ printf("server:%s\n", host);
+ return host;
+}
+
+static int downloadProfile(char *smdpAddress)
+{
+ int res = -1;
+ char *authser_apdu = NULL;//auth server apdu
+ char *predl_apdu = NULL;//prepare download apdu
+ char *notify_apdu = NULL;//Notification apdu
+ int notify_res = -1;
+ int notify_check = -1;
+ //1 creat https
+ //2 get auth, send
+
+ res = lpa_connect_smdp(smdpAddress);
+ if (res != 0) {
+ res = -2;
+ goto download_END;
+ }
+
+ authser_apdu = lpa_initauth();
+ if (authser_apdu == NULL || strlen(authser_apdu) == 0) {
+ res = -2;
+ goto download_END;
+ }
+
+ predl_apdu = lpa_authclient(authser_apdu);
+ if (predl_apdu == NULL || strlen(predl_apdu) == 0) {
+ res = -2;
+ goto download_END;
+ }
+
+ notify_apdu = lpa_getbpp(predl_apdu);
+ if (notify_apdu == NULL || strlen(notify_apdu) == 0) {
+ res = -2;
+ goto download_END;
+ }
+//dtest
+#if 1
+ notify_res = lpa_notification(notify_apdu);
+ if (notify_res == -1) {
+ printf("lpa_notification fail\n");
+ //goto download_END;//skip, use updata result
+ }
+#endif
+
+ notify_check = lpa_parse_iccid_apdu(notify_apdu, curent_iccid, sizeof(curent_iccid));
+ if (notify_check == -1)
+ goto download_END;
+
+
+ res = 0;
+download_END:
+ if (authser_apdu != NULL)
+ free(authser_apdu);
+ if (predl_apdu != NULL)
+ free(predl_apdu);
+ if (notify_apdu != NULL)
+ free(notify_apdu);
+
+ lpa_disconn_smdp(smdpAddress);
+ return res;
+}
+
+/***************************************************************/
+//
+//ÊäÈ뼤»îÂ뷽ʽÏÂÔØprofile
+//È·ÈÏÂëδÓà confirmcode = NULL
+//
+/***************************************************************/
+int downloadProfileByAc(char *activecode, char *confirmcode)
+{
+ int res = -1;
+ char *smdpAddress = NULL;
+
+ char dl_retry[6] = {0};
+ int count = 0;
+ int i = 0;
+
+ sc_cfg_get("lpa_dl_retry", dl_retry, sizeof(dl_retry));
+ count = atoi(dl_retry);
+ printf("lpa_updata_retry:%s,%d\n", dl_retry, count);
+ if (count <= 0 || count > 10) { //kw 3
+ count = 1;
+ }
+
+ smdpAddress = parse_accode(activecode);
+ if (smdpAddress == NULL)
+ return -1;
+
+ for (i = 0; i < count; i++) {
+ res = downloadProfile(smdpAddress);
+ if (res == -2 && i < count-1) {
+ //retry
+ sleep(SMDP_DL_INTERVAL);
+ continue;
+ }
+ break;
+ }
+
+ free(smdpAddress);
+ return res;
+}
+
+#if 0
+int downloadProfileByEid(void)
+{
+ int res = -1;
+ char *smdpAddress = "esim.wo.cn";//get from default
+
+ res = downloadProfile(smdpAddress);
+
+ return res;
+}
+#endif
+
+/***************************************************************/
+//
+//ÆôÓÃprofile
+//in: iccid 20
+//
+//parse 8001xx return xx:
+//0£ºOK
+//1£ºiccidOrAidNotFound£»
+//2£ºprofileNotInDisabledState£»
+//3£ºdisallowedByPolicy£»
+//4£ºwrongProfileReenabling£»
+//5£ºcatBusy£»
+//127£ºundefinedError
+//ÆäÓà·µ»ØÖµ²Î¿¼6.10½Ú
+//
+/***************************************************************/
+int enableProfile(char *iccid)
+{
+ char *apdu = NULL;
+ int res = 127;
+ apdu = EnableProfile(iccid);
+ if (apdu == NULL)
+ return 127;
+ errno = 0;
+ res = strtol(apdu, NULL, 16);
+ if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+ {
+ printf("strtol errno %d: %s\n", errno, strerror(errno));
+ }
+ free(apdu);
+ return res;
+}
+
+/***************************************************************/
+//
+//½ûÓÃprofile
+//
+/***************************************************************/
+int disableProfile(char * iccid)
+{
+ char *apdu = NULL;
+ int res = 127;
+ apdu = DisableProfile(iccid);
+ if (apdu == NULL)
+ return 127;
+ errno = 0;
+ res = strtol(apdu, NULL, 16);
+ if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+ {
+ printf("strtol errno %d: %s\n", errno, strerror(errno));
+ }
+ free(apdu);
+ return res;
+}
+
+
+/***************************************************************/
+//
+//ɾ³ýprofile
+//
+/***************************************************************/
+int deleteProfile(char * iccid)
+{
+ char *apdu = NULL;
+ int res = 127;
+ apdu = DeleteProfile(iccid);
+ if (apdu == NULL)
+ return 127;
+ errno = 0;
+ res = strtol(apdu, NULL, 16);
+ if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+ {
+ printf("strtol errno %d: %s\n", errno, strerror(errno));
+ }
+ free(apdu);
+ return res;
+}
+
+
+int memoryReset(void)
+{
+ char *apdu = NULL;
+ int res = 127;
+ apdu = EUICCMemoryReset();
+ if (apdu == NULL)
+ return 127;
+ errno = 0;
+ res = strtol(apdu, NULL, 16);
+ if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+ {
+ printf("strtol errno %d: %s\n", errno, strerror(errno));
+ }
+ free(apdu);
+ return res;
+}
+
+//limit 10
+static char *lap_parse_profile_list(char *pdu, int *list_n)
+{
+ char *js_list = NULL;
+
+ char *profile = NULL;
+ char *iccid = NULL;
+ char *state = NULL;
+ int status = 0;
+ int i = 0;
+ char *tmp_pdu = pdu;
+ char *offset = NULL;
+
+ js_list = malloc(APDU_RESP_LEN);
+ if (js_list == NULL)
+ return NULL;
+ memset(js_list, 0, APDU_RESP_LEN);
+
+ while(i < 10 && strlen(tmp_pdu) > 0) {
+ profile = lpa_tag_apdu_from_atresp(tmp_pdu, 0xE3);
+ if (profile == NULL)
+ break;
+
+ iccid = lpa_tag_apdu_from_atresp(tmp_pdu, 0x5A);
+ if (iccid == NULL) {
+ free(profile);
+ break;
+ }
+ lpa_trans_iccid(iccid, strlen(iccid));
+
+ state = lpa_tag_apdu_from_atresp(tmp_pdu, 0x9F70);
+ if (state == NULL) {
+ free(profile);
+ free(iccid);
+ break;
+ }
+ errno = 0;
+ status = strtol(state, NULL, 16);
+ if (errno == ERANGE)// kw ERRNO.NOT_CHECKED
+ {
+ printf("strtol errno %d: %s\n", errno, strerror(errno));
+ }
+ if (i == 0) {
+ snprintf(js_list, APDU_RESP_LEN,
+ "{\"ICCID\":\"%s\",\"STATUS\":%d}", iccid, status);
+ }
+ else {
+ snprintf(js_list + strlen(js_list), APDU_RESP_LEN - strlen(js_list),
+ ",{\"ICCID\":\"%s\",\"STATUS\":%d}", iccid, status);
+ }
+
+ offset = strstr(tmp_pdu, profile);
+ if (offset == NULL) {
+ free(profile);
+ free(iccid);
+ free(state);
+ break;
+ }
+ tmp_pdu = offset + strlen(profile);
+ free(profile);
+ free(iccid);
+ free(state);
+ i++;
+
+ }
+ *list_n = i;
+ return js_list;
+}
+
+/***************************************************************/
+//
+//·µ»Ø¸öÊý£¬ºÍjson array[iccid, state]
+//
+/***************************************************************/
+int getProfileList(char **info)
+{
+ char *apdu = NULL;
+ int prof_num = 0;
+
+ apdu = GetProfilesInfo(NULL);
+ if (apdu == NULL)
+ return prof_num;
+
+
+ *info = lap_parse_profile_list(apdu, &prof_num);
+
+
+ free(apdu);
+ return prof_num;
+}
+