| /***************************************************************/ | |
| // | |
| //²Î¼û ÖйúÁªÍ¨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; | |
| } | |