[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;

+}

+