| /***************************************************************/ | |
| // | |
| //²Î¼û LPA½Ó¿ÚÎĵµV0.1 SGP.22, ·µ»ØAPDU | |
| // | |
| /***************************************************************/ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <ctype.h> | |
| #include <sys/time.h> | |
| #include <time.h> | |
| #include <termios.h> | |
| #include "lpa_inner.h" | |
| #define LPA_TRIGGER_DATA_LEN 512 | |
| #define TRIGGER_HTTP_REQ_LEN 512 | |
| #define TRIGGER_HTTP_RESP_LEN 512 | |
| #define HASH_SIZE 16 | |
| #define HASH_HEX_SIZE 33 | |
| #define MAX_TIME_LEN 24 | |
| #define MAX_APPID_LEN 65 | |
| #define MAX_URL_LEN 129 | |
| int g_chan_id = 0; //logical channel | |
| static int g_open_channel_flag = 0; | |
| extern char curent_iccid[ICCID_LEN+1]; | |
| //use nv | |
| //#define APPID "O8XTcVkZ8L4RDv1V" | |
| //#define APPSECRET "WNbHQlRV9JKeqpVWSurQWZLXwDs5T9Dl" | |
| //#define TRIGGER_PORT 61622 | |
| //#define TRIGGER_HOST "serviceplatformt.esim.chinaunicom.cn" | |
| //#define TRIGGER_EVENT_URL "/esim_uni_plus_server/api/event" | |
| //#define TRIGGER_UPDATA_URL "/esim_uni_plus_server/api/updata" | |
| //´¥·¢·þÎñÆ÷httpÇëÇó | |
| static char trigger_https_req[] = | |
| "POST %s HTTP/1.1\r\n" | |
| "Host: %s\r\n" | |
| "Content-Type: application/json\r\n" | |
| "Content-Length: %d\r\n" | |
| "Accept: */*\r\n" | |
| "\r\n%s\r\n"; | |
| static char trigger_https_event[] = | |
| "{" | |
| "\"HEAD\": {" | |
| "\"APPID\": \"%s\"," | |
| "\"TIME\": \"%s\"," | |
| "\"TRANSID\": \"%s\"," | |
| "\"TOKEN\": \"%s\"" | |
| "}," | |
| "\"BODY\": {" | |
| "\"EID\": \"%s\"," | |
| "\"IMEI\": \"%s\"" | |
| "}" | |
| "}"; | |
| static char trigger_https_updata[] = | |
| "{" | |
| "\"HEAD\": {" | |
| "\"APPID\": \"%s\"," | |
| "\"TIME\": \"%s\"," | |
| "\"TRANSID\": \"%s\"," | |
| "\"TOKEN\": \"%s\"" | |
| "}," | |
| "\"BODY\": {" | |
| "\"EID\": \"%s\"," | |
| "\"IMEI\": \"%s\"," | |
| "\"EXEC_RESULT\": %d," | |
| "\"EXEC_REASON\": \"%s\"," | |
| "\"DATA_INFO\": [%s]" | |
| "}" | |
| "}"; | |
| char g_imei[MAX_IMEI_LEN] = {0}; | |
| /***************************************************************/ | |
| // | |
| //imei | |
| // | |
| /***************************************************************/ | |
| static int lpa_get_imei(char *imei, int size) | |
| { | |
| int ret = -1; | |
| char t_imei[MAX_IMEI_LEN] = {0}; | |
| void *p2[] = {t_imei}; | |
| sc_cfg_get ("imei", imei, size); | |
| if (strlen(imei) < 15) { | |
| ret = get_modem_info("AT+CGSN\r\n", "%s", p2); | |
| if(ret == 0) { | |
| snprintf(imei, size, "%s", t_imei); | |
| } | |
| return ret; | |
| } | |
| return 0; | |
| } | |
| static int lpa_get_iccid(char *iccid, int size) | |
| { | |
| int ret = -1; | |
| char t_iccid[ICCID_LEN+1] = {0}; | |
| void *p2[] = {t_iccid}; | |
| ret = get_modem_info("AT+ZICCID?\r\n", "%s", p2); | |
| if(ret == 0) { | |
| snprintf(iccid, size, "%s", t_iccid); | |
| } | |
| return ret; | |
| } | |
| /***************************************************************/ | |
| // | |
| //time | |
| // | |
| /***************************************************************/ | |
| static int lpa_get_time(char *time, int size) | |
| { | |
| struct tm ptm = {0}; | |
| struct timeval now_time = {0}; | |
| gettimeofday(&now_time, NULL); | |
| localtime_r(&now_time.tv_sec, &ptm); | |
| snprintf(time, size, "%d-%02d-%02d %02d:%02d:%02d %03d", | |
| ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec, now_time.tv_usec/1000); | |
| //printf("lpa_get_time: %s\n", time); | |
| return 0; | |
| } | |
| static int lpa_get_transid(char *transid, int size, char *imei) | |
| { | |
| struct tm ptm = {0}; | |
| struct timeval now_time = {0}; | |
| gettimeofday(&now_time, NULL); | |
| localtime_r(&now_time.tv_sec, &ptm); | |
| snprintf(transid, size, "%s%04d%02d%02d%02d%02d%02d%03d", | |
| imei, ptm.tm_year + 1900, ptm.tm_mon + 1, ptm.tm_mday, ptm.tm_hour, ptm.tm_min, ptm.tm_sec, now_time.tv_usec/1000); | |
| //printf("lpa_get_transid: %s\n", transid); | |
| return 0; | |
| } | |
| //0 fail 1 succ | |
| static int lpa_get_exeres(char *exe_reason, int len) | |
| { | |
| sc_cfg_get("lpa_last_res", exe_reason, len); | |
| if (0 == strcmp(exe_reason,"success")) | |
| return 1; | |
| return 0; | |
| } | |
| /***************************************************************/ | |
| // | |
| // | |
| // | |
| /***************************************************************/ | |
| static char *lpa_get_trigger_data(void) | |
| { | |
| int ret = -1; | |
| //char imei[MAX_IMEI_LEN] = {0}; | |
| char time[MAX_TIME_LEN] = {0}; | |
| char transid[MAX_TRANSID_LEN] = {0}; | |
| char *eid = NULL; | |
| lpa_MD5_CTX md5ctx = {0}; | |
| unsigned char hash[HASH_SIZE] = {0}; | |
| char token[HASH_HEX_SIZE] = {0}; | |
| char *js_data = NULL; | |
| char appid[MAX_APPID_LEN] = {0}; | |
| char appsecret[MAX_APPID_LEN] = {0}; | |
| sc_cfg_get("lpa_appid", appid, sizeof(appid)); | |
| sc_cfg_get("lpa_appsecret", appsecret, sizeof(appsecret)); | |
| lpa_get_time(time, sizeof(time)); | |
| lpa_get_transid(transid, sizeof(transid), g_imei); | |
| lpa_MD5_Init(&md5ctx); | |
| lpa_MD5_Update(&md5ctx, appid, strlen(appid)); | |
| lpa_MD5_Update(&md5ctx, transid, strlen(transid)); | |
| lpa_MD5_Update(&md5ctx, time, strlen(time)); | |
| lpa_MD5_Update(&md5ctx, appsecret, strlen(appsecret)); | |
| lpa_MD5_Final(hash, &md5ctx); | |
| //token lower case | |
| bytes2string_lower(hash, token, sizeof(hash)); | |
| eid = GetEID(); | |
| if (eid == NULL) { | |
| return NULL; | |
| } | |
| js_data = malloc(LPA_TRIGGER_DATA_LEN); | |
| if (js_data != NULL) { | |
| memset(js_data, 0, LPA_TRIGGER_DATA_LEN); | |
| snprintf(js_data, LPA_TRIGGER_DATA_LEN, trigger_https_event, | |
| appid, time, transid, token, eid, g_imei); | |
| //printf("trigger json:-%s-\n", js_data); | |
| } | |
| free(eid); | |
| return js_data; | |
| } | |
| static char *lpa_get_updata_data(void) | |
| { | |
| int ret = -1; | |
| //char imei[MAX_IMEI_LEN] = {0}; | |
| char time[MAX_TIME_LEN] = {0}; | |
| char transid[MAX_TRANSID_LEN] = {0}; | |
| char *eid = NULL; | |
| lpa_MD5_CTX md5ctx = {0}; | |
| unsigned char hash[HASH_SIZE] = {0}; | |
| char token[HASH_HEX_SIZE] = {0}; | |
| char *js_data = NULL; | |
| char exe_reason[200] = {0}; | |
| int exe_res = 0; | |
| char *pro_list = NULL; | |
| char appid[MAX_APPID_LEN] = {0}; | |
| char appsecret[MAX_APPID_LEN] = {0}; | |
| sc_cfg_get("lpa_appid", appid, sizeof(appid)); | |
| sc_cfg_get("lpa_appsecret", appsecret, sizeof(appsecret)); | |
| lpa_get_time(time, sizeof(time)); | |
| lpa_get_transid(transid, sizeof(transid), g_imei); | |
| lpa_MD5_Init(&md5ctx); | |
| lpa_MD5_Update(&md5ctx, appid, strlen(appid)); | |
| lpa_MD5_Update(&md5ctx, transid, strlen(transid)); | |
| lpa_MD5_Update(&md5ctx, time, strlen(time)); | |
| lpa_MD5_Update(&md5ctx, appsecret, strlen(appsecret)); | |
| lpa_MD5_Final(hash, &md5ctx); | |
| //token lower case | |
| bytes2string_lower(hash, token, sizeof(hash)); | |
| eid = GetEID(); | |
| if (eid == NULL) { | |
| return NULL; | |
| } | |
| exe_res = lpa_get_exeres(exe_reason, sizeof(exe_reason)); | |
| getProfileList(&pro_list); | |
| js_data = malloc(LPA_TRIGGER_DATA_LEN); | |
| if (js_data != NULL) { | |
| memset(js_data, 0, LPA_TRIGGER_DATA_LEN); | |
| if (pro_list != NULL) { | |
| snprintf(js_data, LPA_TRIGGER_DATA_LEN, trigger_https_updata, | |
| appid, time, transid, token, eid, g_imei, exe_res, exe_reason, pro_list); | |
| } | |
| else { | |
| snprintf(js_data, LPA_TRIGGER_DATA_LEN, trigger_https_updata, | |
| appid, time, transid, token, eid, g_imei, exe_res, exe_reason, ""); | |
| } | |
| //printf("trigger json:-%s-\n", js_data); | |
| } | |
| if (pro_list != NULL) | |
| free(pro_list); | |
| free(eid); | |
| return js_data; | |
| } | |
| static int lpa_get_profile_state(char *iccid) | |
| { | |
| char *apdu = NULL; | |
| char *state = NULL; | |
| int status = 0; | |
| apdu = GetProfilesInfo(iccid); | |
| if (apdu == NULL) | |
| return -1; | |
| state = lpa_tag_apdu_from_atresp(apdu, 0x9F70); | |
| if (state == NULL) { | |
| free(apdu); | |
| return -1; | |
| } | |
| errno = 0; | |
| status = strtol(state, NULL, 16); | |
| if (errno == ERANGE)// kw ERRNO.NOT_CHECKED | |
| { | |
| printf("strtol errno %d: %s\n", errno, strerror(errno)); | |
| } | |
| free(state); | |
| free(apdu); | |
| return status; | |
| } | |
| //µ±Ç°iccidÊÇ·ñΪ¼¤»î״̬µÄprofile | |
| static int lpa_get_cur_iccid_state(void) | |
| { | |
| char cur_iccid[ICCID_LEN+1] = {0}; | |
| lpa_get_iccid(cur_iccid, sizeof(cur_iccid)); | |
| lpa_trans_iccid(cur_iccid, strlen(cur_iccid)); | |
| if (strlen(cur_iccid) == ICCID_LEN) { | |
| return lpa_get_profile_state(cur_iccid); | |
| } | |
| return -1; | |
| } | |
| /***************************************************************/ | |
| // | |
| // | |
| // | |
| /***************************************************************/ | |
| static char *lpa_parse_trigger_resp(char *srcStr, int *next_step) | |
| { | |
| cJSON *root = NULL; | |
| cJSON *object = NULL; | |
| cJSON *object2 = NULL; | |
| cJSON *array = NULL; | |
| char *accode_apdu = NULL; | |
| root = cJSON_Parse(srcStr); | |
| if (root == NULL) { | |
| printf("root == NULL\n"); | |
| return NULL; | |
| } | |
| object = cJSON_GetObjectItem(root, "BODY"); | |
| if (object == NULL) { | |
| printf("BODY not find\n"); | |
| cJSON_Delete(root); | |
| return NULL; | |
| } | |
| object2 = cJSON_GetObjectItem(object, "NEXT_STEP"); | |
| if (object2 == NULL) { | |
| printf("NEXT_STEP not find\n"); | |
| cJSON_Delete(root); | |
| return NULL; | |
| } | |
| printf("NEXT_STEP:%d\n", object2->valueint); | |
| *next_step = object2->valueint; | |
| if (object2->valueint == 2 || object2->valueint == 3 | |
| || object2->valueint == 4) { | |
| object2 = cJSON_GetObjectItem(object, "ICCID"); | |
| if (object2 == NULL) { | |
| printf("ICCID not find\n"); | |
| cJSON_Delete(root); | |
| return NULL; | |
| } | |
| printf("ICCID:%s\n", object2->valuestring); | |
| accode_apdu = malloc(APDU_RESP_LEN); | |
| if (accode_apdu != NULL) { | |
| memset(accode_apdu, 0, APDU_RESP_LEN); | |
| strncpy(accode_apdu, object2->valuestring, APDU_RESP_LEN-1); | |
| lpa_trans_iccid(accode_apdu, strlen(accode_apdu)); | |
| printf("ICCID-Trans:-%s-\n", accode_apdu); | |
| } | |
| } | |
| else if (object2->valueint == 1) { | |
| object2 = cJSON_GetObjectItem(object, "COMMAND"); | |
| if (object2 == NULL) { | |
| printf("COMMAND not find\n"); | |
| cJSON_Delete(root); | |
| return NULL; | |
| } | |
| array = cJSON_GetArrayItem(object2, 0); | |
| if (array == NULL) { | |
| printf("COMMAND no item\n"); | |
| cJSON_Delete(root); | |
| return NULL; | |
| } | |
| printf("COMMAND:%s\n", array->valuestring); | |
| accode_apdu = malloc(APDU_RESP_LEN); | |
| if (accode_apdu != NULL) { | |
| memset(accode_apdu, 0, APDU_RESP_LEN); | |
| strncpy(accode_apdu, array->valuestring, APDU_RESP_LEN-1); | |
| printf("accode or apdu:-%s-\n", accode_apdu); | |
| } | |
| } | |
| cJSON_Delete(root); | |
| return accode_apdu; | |
| } | |
| static char *lpa_parse_updata_resp(char *srcStr) | |
| { | |
| cJSON *root = NULL; | |
| cJSON *object = NULL; | |
| cJSON *object2 = NULL; | |
| cJSON *array = NULL; | |
| char *code = NULL; | |
| root = cJSON_Parse(srcStr); | |
| if (root == NULL) { | |
| printf("root == NULL\n"); | |
| return NULL; | |
| } | |
| object = cJSON_GetObjectItem(root, "HEAD"); | |
| if (object == NULL) { | |
| printf("HEAD not find\n"); | |
| cJSON_Delete(root); | |
| return NULL; | |
| } | |
| object2 = cJSON_GetObjectItem(object, "CODE"); | |
| if (object2 == NULL) { | |
| printf("CODE not find\n"); | |
| cJSON_Delete(root); | |
| return NULL; | |
| } | |
| printf("CODE:%s\n", object2->valuestring); | |
| code = malloc(APDU_RESP_LEN); | |
| if (code != NULL) { | |
| memset(code, 0, APDU_RESP_LEN); | |
| strncpy(code, object2->valuestring, APDU_RESP_LEN-1); | |
| } | |
| cJSON_Delete(root); | |
| return code; | |
| } | |
| static void lpa_open_cfun(void) | |
| { | |
| int cfun_stat = -1; | |
| void *p2[] = {&cfun_stat}; | |
| get_modem_info("AT+CFUN?\r\n", "%d", p2); | |
| if (cfun_stat != 1) { | |
| get_modem_info("AT+CFUN=0\r\n", NULL, NULL); | |
| get_modem_info("AT+CFUN=1\r\n", NULL, NULL); | |
| lpa_close_logical_channel(0); | |
| } | |
| } | |
| //wifiʱ·ÀÖ¹ËÑÍøµÄsim¿¨²Ù×÷´ò¶Ïesim·Ö¶Îд¿¨ | |
| static void lpa_close_cfun(void) | |
| { | |
| char ps_wan[20] = {0}; | |
| char def_wan[20] = {0}; | |
| int cfun_stat = -1; | |
| void *p2[] = {&cfun_stat}; | |
| sc_cfg_get("pswan", ps_wan, sizeof(ps_wan)); | |
| sc_cfg_get("default_wan_name", def_wan, sizeof(def_wan)); | |
| if (strncmp(def_wan, ps_wan, strlen(ps_wan)) != 0) { | |
| get_modem_info("AT+CFUN?\r\n", "%d", p2); | |
| if (cfun_stat == 1) { | |
| get_modem_info("AT+CFUN=4\r\n", NULL, NULL); | |
| } | |
| } | |
| } | |
| static int lpa_exe_updata(void) | |
| { | |
| int code = -1; | |
| int i = 0; | |
| char updata_retry[6] = {0}; | |
| int count = 0; | |
| //dtest | |
| #if 1 | |
| sc_cfg_get("lpa_updata_retry", updata_retry, sizeof(updata_retry)); | |
| count = atoi(updata_retry); | |
| if (count <= 0 || count > 10) { //kw 3 | |
| count = 1; | |
| } | |
| if (0 == lpa_check_status(60)) { | |
| printf("lpa_exe_updata not ready\n"); | |
| return -1; | |
| } | |
| for (i = 0; i < count; i++) { | |
| code = lpa_trigger_updata(); | |
| if (code == 0 || i == count-1) | |
| break; | |
| //retry | |
| sleep(30); | |
| } | |
| if (code != 0) { | |
| printf("lpa_exe_updata updata fail\n"); | |
| return -1; | |
| } | |
| #endif | |
| return 0; | |
| } | |
| //check sim && net && sntp ready | |
| int lpa_check_status(int retry) | |
| { | |
| int i = 0; | |
| int res = -1; | |
| //+ZPBIC | |
| for(i = 0; i < retry; i++) { | |
| char sntp_res[20] = {0}; | |
| sc_cfg_get("zpbic_pb", sntp_res, sizeof(sntp_res)); | |
| if (strcmp(sntp_res, "ready") == 0) { | |
| res = 1; | |
| break; | |
| } | |
| printf("lpa zpbic_pb: %s\n", sntp_res); | |
| sleep(6); | |
| } | |
| if (res != 1) { | |
| printf("lpa sim not ready\n"); | |
| return 0; | |
| } | |
| //net | |
| res = -1; | |
| for(i = 0; i < retry; i++) { | |
| res = default_route_check(); | |
| if (res == 1) | |
| break; | |
| printf("lpa default_route_check: %d\n", res); | |
| sleep(6); | |
| } | |
| if (res != 1) { | |
| printf("lpa check net timeout\n"); | |
| return 0; | |
| } | |
| //sntp, no +zmmi | |
| res = -1; | |
| for(i = 0; i < retry; i++) { | |
| char sntp_res[20] = {0}; | |
| sc_cfg_get("sntp_process_result", sntp_res, sizeof(sntp_res)); | |
| if (strcmp(sntp_res, "success") == 0) { | |
| res = 1; | |
| break; | |
| } | |
| printf("lpa sntp_process_result: %s\n", sntp_res); | |
| sleep(6); | |
| } | |
| if (res != 1) { | |
| printf("lpa check sntp timeout\n"); | |
| return 0; | |
| } | |
| //open channel | |
| res = -1; | |
| for(i = 0; i < 4; i++) { | |
| res = lpa_open_logical_channel(); | |
| if (res == 0) | |
| break; | |
| printf("lpa lpa_open_logical_channel: %d\n", res); | |
| sleep(2); | |
| } | |
| if (res != 0) { | |
| printf("lpa open channel fail\n"); | |
| return 0; | |
| } | |
| ////select app id | |
| res = -1; | |
| for(i = 0; i < 4; i++) { | |
| res = lpa_select_aid(); | |
| if (res == 0) | |
| break; | |
| printf("lpa lpa_select_aid: %d\n", res); | |
| sleep(2); | |
| } | |
| if (res != 0) { | |
| printf("lpa select fail\n"); | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| //²éѯһЩ¹Ì¶¨²ÎÊý | |
| int lpa_init(void) | |
| { | |
| //zpbic && sntp && net ok, if use wlan close modem, open channel select isdr | |
| if (0 == lpa_check_status(60)) { | |
| printf("lpa not ready\n"); | |
| return -1; | |
| } | |
| if(0 != lpa_get_imei(g_imei, sizeof(g_imei))) { | |
| printf("lpa no imei\n"); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| int lpa_uninit(void) | |
| { | |
| lpa_close_logical_channel(1); | |
| return 0; | |
| } | |
| static char *lpa_tigger_session(char *path, char *req_data) | |
| { | |
| int ret = -1; | |
| int cont_len = 0; | |
| https_context_t https_ct = {0}; | |
| char trigger_port[6] = {0}; | |
| char trigger_host[MAX_URL_LEN] = {0}; | |
| char *https_req = NULL; | |
| char *https_resp = NULL; | |
| int https_req_len = 0; | |
| //kw 3 | |
| //if (https_req_len > TRIG_HTTP_MAX_LEN) | |
| // return NULL; | |
| sc_cfg_get("lpa_trigger_port", trigger_port, sizeof(trigger_port)); | |
| sc_cfg_get("lpa_trigger_host", trigger_host, sizeof(trigger_host)); | |
| SSL_library_init(); | |
| https_ct.port = atoi(trigger_port); | |
| https_ct.host = trigger_host; | |
| https_ct.path = path; | |
| ret = https_init(&https_ct); | |
| if (ret != 0) { | |
| printf("[trigger] https_init fail\n"); | |
| return NULL; | |
| } | |
| https_req_len = strlen(trigger_https_req)+strlen(https_ct.path)+strlen(https_ct.host)+strlen(req_data)+32; | |
| https_req = malloc(https_req_len); | |
| if (https_req == NULL) { | |
| https_uninit(&https_ct); | |
| return NULL; | |
| } | |
| memset(https_req, 0, https_req_len); | |
| ret = snprintf(https_req, https_req_len, trigger_https_req, | |
| https_ct.path, https_ct.host, strlen(req_data), req_data); | |
| printf("[trigger] request##%s##\n", https_req); | |
| ret = https_write(&https_ct, https_req, ret); | |
| printf("[trigger] https_write ret = %d.\n", ret); | |
| ret = https_get_status_code(&https_ct, &cont_len); | |
| printf("[trigger] https_recv code = %d.\n", ret); | |
| if(ret == 200 && (cont_len > 0 && cont_len < TRIG_HTTP_MAX_LEN)) | |
| { | |
| https_resp = malloc(cont_len + 1); | |
| if (https_resp == NULL) { | |
| https_uninit(&https_ct); | |
| free(https_req); | |
| printf("[trigger] https_resp_cont NULL.\n"); | |
| return NULL; | |
| } | |
| memset(https_resp, 0, cont_len + 1); | |
| ret = https_read_content(&https_ct, https_resp, cont_len); | |
| if(cont_len == ret) | |
| { | |
| https_resp[ret] = '\0'; //×Ö·û´®½áÊø±êʶ | |
| printf("[trigger] https_write https_resp_content = \n %s.\n", https_resp); | |
| } | |
| } | |
| https_uninit(&https_ct); | |
| free(https_req); | |
| return https_resp; | |
| } | |
| /***************************************************************/ | |
| // | |
| //´Ó´¥·¢·þÎñÆ÷²éѯָÁî | |
| // | |
| /***************************************************************/ | |
| char *lpa_trigger_event(int *next_step) | |
| { | |
| char *trigger_data = NULL; | |
| char *https_resp_cont = NULL; | |
| char *command = NULL; | |
| char trigger_event[MAX_URL_LEN] = {0}; | |
| trigger_data = lpa_get_trigger_data(); | |
| if (trigger_data == NULL) { | |
| printf("[trigger] request data NULL.\n"); | |
| return NULL; | |
| } | |
| sc_cfg_get("lpa_trigger_event_url", trigger_event, sizeof(trigger_event)); | |
| https_resp_cont = lpa_tigger_session(trigger_event, trigger_data); | |
| if (https_resp_cont != NULL) { | |
| command = lpa_parse_trigger_resp(https_resp_cont, next_step); | |
| free(https_resp_cont); | |
| } | |
| free(trigger_data); | |
| return command; | |
| } | |
| /***************************************************************/ | |
| // | |
| //Ïò´¥·¢·þÎñÆ÷Éϱ¨Êý¾Ý | |
| // | |
| /***************************************************************/ | |
| int lpa_trigger_updata(void) | |
| { | |
| char *trigger_data = NULL; | |
| char *https_resp_cont = NULL; | |
| char *code = NULL; | |
| int res_code = -1; | |
| char trigger_updata[MAX_URL_LEN] = {0}; | |
| trigger_data = lpa_get_updata_data(); | |
| if (trigger_data == NULL) { | |
| printf("[trigger] request data NULL.\n"); | |
| return NULL; | |
| } | |
| sc_cfg_get("lpa_trigger_updata_url", trigger_updata, sizeof(trigger_updata)); | |
| https_resp_cont = lpa_tigger_session(trigger_updata, trigger_data); | |
| if (https_resp_cont != NULL) { | |
| code = lpa_parse_updata_resp(https_resp_cont); | |
| if (code != NULL) { | |
| errno = 0; | |
| res_code = strtol(code, NULL, 10); | |
| if (errno == ERANGE)// kw ERRNO.NOT_CHECKED | |
| { | |
| printf("strtol errno %d: %s\n", errno, strerror(errno)); | |
| } | |
| free(code); | |
| } | |
| free(https_resp_cont); | |
| } | |
| free(trigger_data); | |
| return res_code; | |
| } | |
| //µôµçµÈ³¡¾°£¬Èç´æÔÚiccid¼¤»î²¢Éϱ¨£¬²»´æÔÚÖ±½Ó×ßevent£¬ÖØÐ´¥·¢ÏÂÔØµÈ²Ù×÷ | |
| int lpa_exception_process(void) | |
| { | |
| char has_iccid[ICCID_LEN+1] = {0}; | |
| int status = 0; | |
| int res = 0; | |
| sc_cfg_get("lpa_bpp_iccid", has_iccid, sizeof(has_iccid)); | |
| if (strlen(has_iccid) == ICCID_LEN) { | |
| status = lpa_get_profile_state(has_iccid); | |
| if (status == 1 || status == 0) { | |
| res = lpa_enable_profile(has_iccid); | |
| if (res == 0) { | |
| sc_cfg_set("lpa_bpp_iccid", ""); | |
| sc_cfg_save(); | |
| return 0; | |
| } | |
| return -1; | |
| } | |
| } | |
| return 0; | |
| } | |
| int lpa_download_profile(char *activecode, char *confirmcode) | |
| { | |
| int res = -1; | |
| lpa_close_cfun(); | |
| memset(curent_iccid, 0, sizeof(curent_iccid)); | |
| res = downloadProfileByAc(activecode, confirmcode); | |
| //²»¹Ü³É¹¦Óë·ñ£¬¶¼ÒªÉϱ¨ | |
| res = lpa_enable_profile(curent_iccid); | |
| if (res == 0) { | |
| sc_cfg_set("lpa_bpp_iccid", ""); | |
| sc_cfg_save(); | |
| } | |
| lpa_open_cfun(); | |
| return res; | |
| } | |
| int lpa_enable_profile(char *iccid) | |
| { | |
| int res = 0; | |
| int code = 0; | |
| res = enableProfile(iccid); | |
| if (res == 0) { | |
| sc_cfg_set("zpbic_pb", "");//wait sim ready | |
| sc_cfg_set("lpa_last_res", "success"); | |
| lpa_close_logical_channel(0); | |
| sleep(2); | |
| } | |
| else if (res == 2) { | |
| sc_cfg_set("lpa_last_res", "success"); | |
| } | |
| else { | |
| sc_cfg_set("lpa_last_res", "fail"); | |
| } | |
| code = lpa_exe_updata(); | |
| if (code != 0) { | |
| printf("lpa_enable_profile updata fail\n"); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| int lpa_disable_profile(char *iccid) | |
| { | |
| int res = 0; | |
| int code = 0; | |
| res = disableProfile(iccid); | |
| if (res == 0) { | |
| sc_cfg_set("zpbic_pb", "");//wait sim ready | |
| sc_cfg_set("lpa_last_res", "success"); | |
| lpa_close_logical_channel(0); | |
| sleep(2); | |
| } | |
| else if (res == 2) { | |
| sc_cfg_set("lpa_last_res", "success"); | |
| } | |
| else { | |
| sc_cfg_set("lpa_last_res", "fail"); | |
| } | |
| code = lpa_exe_updata(); | |
| if (code != 0) { | |
| printf("lpa_disable_profile updata fail\n"); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| int lpa_delete_profile(char *iccid) | |
| { | |
| int res = 0; | |
| int code = 0; | |
| res = deleteProfile(iccid); | |
| if (res == 0) { | |
| sc_cfg_set("lpa_last_res", "success"); | |
| sleep(2); | |
| } | |
| else if (res == 1) { | |
| sc_cfg_set("lpa_last_res", "success"); | |
| } | |
| else { | |
| sc_cfg_set("lpa_last_res", "fail"); | |
| } | |
| code = lpa_exe_updata(); | |
| if (code != 0) { | |
| printf("lpa_disable_profile updata fail\n"); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| int lpa_memory_reset(void) | |
| { | |
| int res = 0; | |
| int state = 0; | |
| int code = 0; | |
| state = lpa_get_cur_iccid_state(); | |
| res = memoryReset(); | |
| if (res == 0) { | |
| if(state == 1) { | |
| sc_cfg_set("zpbic_pb", "");//wait sim ready | |
| lpa_close_logical_channel(0); | |
| printf("lpa zpbic_pb reset\n"); | |
| } | |
| sc_cfg_set("lpa_last_res", "success"); | |
| sleep(2);//wait sim ready | |
| } | |
| else if (res == 1) { | |
| sc_cfg_set("lpa_last_res", "success"); | |
| } | |
| else { | |
| sc_cfg_set("lpa_last_res", "fail"); | |
| } | |
| code = lpa_exe_updata(); | |
| if (code != 0) { | |
| printf("lpa_disable_profile updata fail\n"); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| int lpa_open_logical_channel(void) | |
| { | |
| char *apdu = NULL; | |
| int chan = 0; | |
| if (g_open_channel_flag == 0) { | |
| apdu = OpenLogicalChannel(); | |
| if (apdu == NULL) | |
| return -1; | |
| errno = 0; | |
| chan = strtol(apdu, NULL, 16); | |
| if (errno == ERANGE)// kw ERRNO.NOT_CHECKED | |
| { | |
| printf("strtol errno %d: %s\n", errno, strerror(errno)); | |
| } | |
| free(apdu); | |
| if (chan < 0 || chan > 3) | |
| return -1; | |
| g_open_channel_flag = 1; | |
| g_chan_id = chan; | |
| } | |
| return 0; | |
| } | |
| //flag = 0, when refresh not need close | |
| int lpa_close_logical_channel(int flag) | |
| { | |
| char *apdu = NULL; | |
| int res = 0; | |
| if (flag == 1 && g_open_channel_flag == 1) { | |
| res = CloseLogicalChannel(g_chan_id); | |
| printf("lpa_close_logical_channel:%d, res:%d\n", g_chan_id, res); | |
| } | |
| g_chan_id = 0; | |
| g_open_channel_flag = 0; | |
| return res; | |
| } | |