[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_user.c b/ap/lib/liblpa/lpa_user.c
new file mode 100755
index 0000000..da2f16f
--- /dev/null
+++ b/ap/lib/liblpa/lpa_user.c
@@ -0,0 +1,935 @@
+/***************************************************************/
+//
+//²Î¼û 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;
+}
+