blob: da2f16fba724bcbb1ea038d4a41ef13bc55c7837 [file] [log] [blame]
/***************************************************************/
//
//²Î¼û 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;
}