blob: 0ce669ed1d2695f788aa250fdacd66ce1e992bac [file] [log] [blame]
/*=============================================================================
# FileName: lynq_sim.cpp
# Desc: about SIM API
# Author: mobiletek
# Version: V1.0
# LastChange: 2021-12-29
# History:
=============================================================================*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <binder/Parcel.h>
#include <log/log.h>
#include <cutils/jstring.h>
#include <pthread.h>
#include <vendor-ril/telephony/ril.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h> /*add for get recvfrom errorid on 20220921*/
#include <sys/stat.h>
#include <fcntl.h>
#include "lynq_sim.h"
#define MAX_BUF 20
#define MAX_NUM 80
#define LYNQ_REQUEST_SET_DEFAULT_SIM_ALL 8008
#define LYNQ_REQUEST_CHANGE_SCREEN_STATE 8014 /*add for two sim suspend on 20220919*/
#define LYNQ_REQUEST_CHANGE_RADIO 8015
#define MAX_LEN 1024*8
#define MAX_NUM 10
#define LOG_TAG "LYNQ_SIM"
#define FLAG_TESS 0
using ::android::Parcel;
#define DEST_PORT 8088
#define DSET_IP_ADDRESS "127.0.0.1"
typedef struct{
int uToken;
int request;
int paramLen;
char param[MAX_LEN];
}lynq_client_t;
/* socket文件描述符 */
int len_addr_serv;
struct sockaddr_in addr_serv;
static int sock_fd = 0;
int Global_uToken = 0;
static int default_cnt = 20;
static pthread_mutex_t g_lynq_sim_sendto_mutex;
/**
* @brief mark call initialization state
* 0: deinit state
* 1: init state
*/
int g_lynq_sim_init_flag = 0;
/**
* @brief lynq_req_sim_io need to send request
*/
char data_buf[32] = {0};
char pin2_buf[32] = {0};
char aidPtr_buf[32] = {0};
/**
* @brief lynq_shutdown need
*/
char options_buf[32] = {0};
char time_buf[32] = {0};
char message_buf[32] = {0};
typedef struct{
int resp_type;
int token;
int request;
int slot_id;
int error;
}lynq_resp_t;
#define RESULT_OK (0)
#define RESULT_ERROR (-1)
typedef enum{
/*base abnormal*/
LYNQ_E_PARAMETER_ANONALY=7000,
LYNQ_E_SEND_REQUEST_FAIL=7001,
LYNQ_E_GET_HEAD_ERROR=7002,
LYNQ_E_INNER_ERROR=7100,
LYNQ_E_MALLOC_ERROR=7101,
/**/
LYNQ_E_CARDSTATE_ERROR=8000,
/* The voice service state is out of service*/
LYNQ_E_STATE_OUT_OF_SERVICE=8001,
/* The voice service state is EMERGENCY_ONLY*/
LYNQ_E_STATE_EMERGENCY_ONLY=8002,
/* The radio power is power off*/
LYNQ_E_STATE_POWER_OFF=8003,
LYNQ_E_TIME_OUT=8004,
/*create or open sms DB fail */
LYNQ_E_SMS_DB_FAIL=8005,
/*Failed to execute sql statement*/
LYNQ_E_SMS_SQL_FAIL = 8006,
LYNQ_E_SMS_NOT_FIND = 8007,
/* The logic conflict*/
LYNQ_E_CONFLICT=9000,
/*Null anomaly*/
LYNQ_E_NULL_ANONALY=9001,
/*Invalid id anomaly*/
LYNQ_E_INVALID_ID_ANONALY=9002,
#ifdef ECALL_SUPPORT
LYNQ_E_ECALL_BEING_RUNNING =9003,
LYNQ_E_ECALL_MSD_LENGTH_ERROR =9004,
LYNQ_E_ECALL_DAILING_NO_ANSWER =9005,
#endif
}LYNQ_E;
/**@brief print solicied response msg's head information
* @param head [IN]: head information
* @return none
*/
void PrintHeader(lynq_resp_t& head)
{
RLOGD("resp_type=%d,token=%d,request=%d,slot_id=%d,error_code=%d",head.resp_type,head.token,head.request,head.slot_id,head.error);
}
int GetHeader(Parcel* &p, lynq_resp_t& head, int request_id)
{
RLOGD("get header");
if(p->dataAvail() > 0)
{
p->readInt32(&(head.resp_type));
p->readInt32(&(head.token));
p->readInt32(&(head.request));
RLOGD("%s %d", __FUNCTION__, head.request);
p->readInt32(&(head.slot_id));
p->readInt32(&(head.error));
PrintHeader(head);
return head.error;
}
else
{
return RESULT_ERROR;
}
}
int get_utoken()
{
return (Global_uToken++)%10000;/*0-10000*/
}
int lynq_send_common_request(Parcel* p, int request_id, int argc, int cnt, int sim_count, const char* format,...)
{
lynq_client_t client;
int ret;
int send_num;
int recv_num;
char res_data[MAX_LEN] = {0};
client.uToken = get_utoken();
if(request_id == RIL_REQUEST_SCREEN_STATE)
{
client.request = LYNQ_REQUEST_CHANGE_SCREEN_STATE;
}
else if(request_id == RIL_REQUEST_RADIO_POWER)
{
client.request = LYNQ_REQUEST_CHANGE_RADIO;
}
else
{
client.request = request_id;
}
client.paramLen = argc;
bzero(client.param,MAX_LEN);
if(argc!=0)
{
va_list args;
va_start(args, format);
vsnprintf(client.param, MAX_LEN, format, args);
va_end(args);
}
RLOGD("uToken=%d,request=%d,paralen=%d,param=%s",client.uToken,client.request,client.paramLen,client.param);
pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
send_num = sendto(sock_fd,&client,sizeof(client),0,(struct sockaddr *)&addr_serv,len_addr_serv);
if(send_num <= 0)
{
RLOGD("send request fail, send num is %d", send_num);
pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
return LYNQ_E_SEND_REQUEST_FAIL;
}
lynq_resp_t head;
head.request = -1;
for(int i = 0; i < cnt; i++)
{
head.resp_type = -1;
head.token = -1;
head.request = -1;
head.slot_id = -1;
head.error = -1;
recv_num = recvfrom(sock_fd,res_data,sizeof(char)*MAX_LEN, 0, (struct sockaddr *)&addr_serv,(socklen_t*)&len_addr_serv);
if(recv_num <= 0)
{
RLOGD("recv request fail, recv num is %d", recv_num);
pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
return recv_num;
}
p->setData((uint8_t *)res_data,sizeof(char)*recv_num);
p->setDataPosition(0);
ret=GetHeader(p,head,request_id);
if(ret!=0)
{
RLOGD("%s %d get head error %d",__FUNCTION__,client.uToken,ret);
if (head.token != client.uToken)
{
RLOGD("head.token is %d != client.uToken is %d", head.token, client.uToken);
ret = RESULT_ERROR;
continue;
}
pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
return ret;
}
if (head.token != client.uToken)
{
RLOGD("head.token is %d != client.uToken is %d", head.token, client.uToken);
ret = RESULT_ERROR;
continue;
}
if(request_id == head.request)
{
sim_count--;
if(sim_count <= 0)
break;
else
continue;
}
}
pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
return ret;
}
int lynq_sim_init(int utoken){
RLOGE("%s start, parameter is %d", __func__,utoken);
if(g_lynq_sim_init_flag == 1)
{
RLOGD("lynq_sim_init failed");
return -1;
}
g_lynq_sim_init_flag = 1;
if(utoken < 0){
return -1;
}
Global_uToken = utoken;
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == sock_fd)
{
return sock_fd;
}
struct sockaddr_in liblynq_data_socket;
bzero(&liblynq_data_socket, sizeof(liblynq_data_socket));
//set this lib socket config
liblynq_data_socket.sin_family = AF_INET;
liblynq_data_socket.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
int ret = bind(sock_fd, (struct sockaddr *)&liblynq_data_socket, sizeof(liblynq_data_socket));
if (-1 == ret)
{
RLOGE("liblynq_data_socket bind fail,errno:%d",errno);
return -1;
}
struct timeval timeOut;
timeOut.tv_sec = 60;
timeOut.tv_usec = 0;
if (setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &timeOut, sizeof(timeOut)) < 0)
{
RLOGD("time out setting failed\n");
return -1;
}
/* 设置address */
memset(&addr_serv, 0, sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
addr_serv.sin_port = htons(DEST_PORT);
len_addr_serv = sizeof(addr_serv);
/*test*/
RLOGE("%s end suc", __func__);
return 0;
}
int lynq_sim_deinit(void){
RLOGE("%s start", __func__);
if(g_lynq_sim_init_flag == 0)
{
RLOGD("lynq_sim_deinit failed");
return -1;
}
g_lynq_sim_init_flag = 0;
close(sock_fd);
RLOGE("%s end suc", __func__);
return 0;
}
static char * lynqStrdupReadString(Parcel &p) {
size_t stringlen;
const char16_t *s16;
s16 = p.readString16Inplace(&stringlen);
return strndup16to8(s16, stringlen);
}
/*If you need to use any API under lynq_sim, you mustfirst call the lynq_sim_init() function to initialize these functions.*/
int lynq_get_sim_status(int *card_status)
{
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_GET_SIM_STATUS,0,default_cnt,1,"");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
p.readInt32(card_status);
return res;
}
int lynq_get_imsi(char buf[])
{
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_GET_IMSI,0,default_cnt,1,"");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
char * test = lynqStrdupReadString(p);
memcpy(buf, test, strlen(test));
free(test);
return res;
}
/*add by lei*/
int lynq_get_iccid(char buf[]){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_QUERY_ICCID,0,default_cnt,1,"");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
char * test = lynqStrdupReadString(p);
memcpy(buf, test, strlen(test));
free(test);
return res;
}
int lynq_enable_pin(char *pin){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_SET_FACILITY_LOCK,4,default_cnt,1,"%s %s %s %s\n", "SC", pin, "11", "1");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
int lynq_sim_power(int mode)
{
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_OEM_HOOK_RAW,1,default_cnt,1,"%s%d", "AT+ESIMPOWER=", mode);
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
int lynq_disable_pin(char *pin){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_SET_FACILITY_LOCK,4,default_cnt,1,"%s %s %s %s\n", "SC", pin, "11", "0");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
int lynq_query_pin_lock(char *pin,int buf[]){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_QUERY_FACILITY_LOCK,3,default_cnt,1,"%s %s %s\n", "SC", pin, "11");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
int num = -1;
p.readInt32(&num);
if(num > 0)
{
int *test = (int *)calloc(num, sizeof(int));
for(int i =0; i <num; i++){
p.readInt32(&test[i]);
buf[i] = test[i];
}
free(test);
}
return res;
}
int lynq_verify_pin(char *pin){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_ENTER_SIM_PIN,1,default_cnt,1,"%s\n", pin);
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
int lynq_change_pin(char *old_pin, char *new_pin){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
int res = -1;
if(old_pin == NULL || new_pin == NULL)
return res;
if(!strlen(new_pin))
return res;
if(!strlen(old_pin))
return res;
Parcel p;
res = lynq_send_common_request(&p,RIL_REQUEST_CHANGE_SIM_PIN,2,default_cnt,1,"%s %s\n", old_pin, new_pin);
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
int lynq_unlock_pin(char *puk, char *pin){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
if(puk == NULL || pin == NULL)
return -1;
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_ENTER_SIM_PUK,2,default_cnt,1,"%s %s\n", puk, pin);
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
static void delete_char(char str[],char target){
if(str == NULL){
return;
}
int i,j;
for(i=j=0;str[i]!='\0';i++){
if(str[i]!=target){
str[j++]=str[i];
}
}
str[j]='\0';
}
static int parse_param(char *cmd, char **argv, char buf[]){
if(cmd == NULL || argv == NULL || buf == NULL){
return -1;
}
if(strstr(cmd,"ERROR")){
return 3;
}
else{
int argc = 0;
char *token;
token = strtok(cmd, ",");
if(token == NULL)
{
return 9001;
}
if(strstr(token, "CNUM"))
{
char *string;
while (token != NULL)
{
if(argc == 5)
{
if(NULL == argv[1])
{
return 9002;
}
int lengh = strlen(argv[1]);
memcpy(buf, argv[1], lengh);
delete_char(buf, '"');
RLOGD("too many phone number return\n");
return 0;
}
string = token;
argv[argc++] = string;
token = strtok(NULL, ",");
}
if(NULL == argv[1])
{
return 9001;
}
int lengh = strlen(argv[1]);
memcpy(buf, argv[1], lengh);
delete_char(buf, '"');
return 0;
}
return 9001;
}
}
int lynq_query_phone_number(char buf[]){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_OEM_HOOK_RAW,1,default_cnt,1,"%s\n", "AT+CNUM");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
int num = -1;
p.readInt32(&num);
char test[128] = {0};
char *argv[5] = {0};
if(num != -1)
{
p.read(test, num);
num = parse_param(test, argv, buf);
return num;
}
return res;
}
int lynq_get_imei(char buf[])
{
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_DEVICE_IDENTITY,0,default_cnt,1,"");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
int num = 0;
p.readInt32(&num);
char * test = lynqStrdupReadString(p);
memcpy(buf, test, strlen(test));
free(test);
return res;
}
int lynq_get_imei_and_sv(char imei[],char sv[])
{
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_DEVICE_IDENTITY,0,default_cnt,1,"");
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
int num = 0;
p.readInt32(&num);
if(num<2)
{
RLOGD("%s num %d error, should greater than 1",__func__,num);
return -1;
}
char *resp[2]={NULL,NULL};
int i;
for(i=0;i<2;i++)
{
resp[i]= lynqStrdupReadString(p);
if(resp[i]==NULL)
{
break;
}
}
if(i==2){
memcpy(imei, resp[0], strlen(resp[0])+1);
memcpy(sv, resp[1], strlen(resp[1])+1);
}
else
{
RLOGD("%s resp[%d] is null",__func__,i);
}
for(i=0;i<2;i++)
{
if(resp[i]!=NULL)
{
free(resp[i]);
}
}
return i==2? 0:-1;
}
static int judge(int slot){
switch(slot){
case 0:
return -1;
case 1:
return -1;
}
return 0;
}
int lynq_switch_card(int slot){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
if(!judge(slot))
return -1;
int send_num = 0;
lynq_client_t client_t;
client_t.request = LYNQ_REQUEST_SET_DEFAULT_SIM_ALL;
client_t.paramLen = 1;
client_t.uToken = get_utoken();
sprintf(client_t.param, "%d\n", slot);
pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
send_num = sendto(sock_fd, &client_t, sizeof(client_t), 0, (struct sockaddr *)&addr_serv, len_addr_serv); //because ril of id = -1
if(send_num < 0)
{
RLOGD("function %s sendto error:", __FUNCTION__);
return send_num;
}
pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
return 0;
}
/**@breif change screen state
*param num type: [IN] screen_state,0:close,1:open
*param ret type: [OUT] result,0:success,other:fail
*return int
*/
int lynq_screen(int num){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
if(!judge(num))
return -1;
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_SCREEN_STATE,1,default_cnt,2,"%d\n",num);
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
/**@breif change screen state
*param num type: [IN] screen_state,0:close,1:open
*param ret type: [OUT] result,0:success,other:fail
*return int
*/
int lynq_factory_radio_state(int num){
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
if(!judge(num))
return -1;
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_RADIO_POWER,1,default_cnt,2,"%d\n",num);
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
return res;
}
/**
* @brief Check whether the input is valid for lynq_req_sim_io api
* @param list type: [IN] list[0]:one of the commands listed for TS 27.007 +CRSM.(command)
* type: [IN] list[1]:EF id(fileid)
* type: [IN] list[2]:offset(p1)
* type: [IN] list[3]:offset(p2)
* type: [IN] list[4]:response len,sometimes needn't care(p3)
* @param path type: [IN] "pathid" from TS 27.007 +CRSM command.
type: [IN] Path is in hex asciii format eg "7f205f70"
type: [IN] Path must always be provided.
* @param data type: [IN] May be NULL
* @param pin2 type: [IN] May be NULL
* @param aidPtr type: [IN] AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
* @param sw type: [OUT]
* @param simResponse type: [OUT] response
* @return int
*/
static int judge_illegal(int list[5], char *path, char *data, char *pin2, char *aidPtr, int sw[2], char *simResponse)
{
if(list == NULL)
{
return -1;
}
if(path == NULL)
{
return -1;
}
if(sw == NULL){
return -1;
}
if(simResponse == NULL){
return -1;
}
if(data == NULL)
{
memcpy(data_buf, "null", 4);
}
else
{
bzero(data_buf,32);
memcpy(data_buf, data, strlen(data));
}
if(pin2 == NULL)
{
memcpy(pin2_buf, "null", 4);
}
else
{
bzero(pin2_buf,32);
memcpy(pin2_buf, data, strlen(data));
}
if(aidPtr == NULL)
{
memcpy(aidPtr_buf, "null", 4);
}
else
{
bzero(aidPtr_buf,32);
memcpy(aidPtr_buf, data, strlen(data));
}
return 0;
}
int lynq_req_sim_io(int list[5], char *path, char *data, char *pin2, char *aidPtr, int sw[2], char *simResponse)
{
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
if(judge_illegal(list, path, data, pin2, aidPtr, sw, simResponse))
{
return -1;
}
Parcel p;
int res = lynq_send_common_request(&p,RIL_REQUEST_SIM_IO,9,default_cnt,1,"%d %d %s %d %d %d %s %s %s\n", list[0], list[1], path, list[2], list[3], list[4], data_buf, pin2_buf, aidPtr_buf);
if(res != 0)
{
RLOGD("function %s execute error", __FUNCTION__);
return res;
}
p.readInt32(&sw[0]);
p.readInt32(&sw[1]);
char * test = lynqStrdupReadString(p);
memcpy(simResponse, test, strlen(test));
free(test);
return res;
}
static void wait_reset_mipc_response(int *response)
{
usleep(500*1000);
int outfd = open("/data/tp",O_RDONLY);
if(outfd == -1){
RLOGD("open error");
return;
}
char rst[1024];
int s;
s = read(outfd,rst,sizeof(rst));
sscanf(rst,"%d",response);
usleep(1);
close(outfd);
return;
}
int lynq_reset_modem(void)
{
if(g_lynq_sim_init_flag == 0)
{
return -1;
}
int ret = -1;
int send_num = 0;
lynq_client_t client_t;
client_t.request = RIL_REQUEST_OEM_HOOK_RAW;
client_t.paramLen = 1;
client_t.uToken = get_utoken();
sprintf(client_t.param, "%s\n", "AT+LRSTMD");
pthread_mutex_lock(&g_lynq_sim_sendto_mutex);
send_num = sendto(sock_fd, &client_t, sizeof(client_t), 0, (struct sockaddr *)&addr_serv, len_addr_serv);//because response not by ril callback
if(send_num < 0)
{
RLOGD("function %s sendto error:", __FUNCTION__);
pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
return ret;
}
wait_reset_mipc_response(&ret);
pthread_mutex_unlock(&g_lynq_sim_sendto_mutex);
RLOGD("function %s ret %d",__FUNCTION__, ret);
return ret;
}
/**
* @brief handle shutdown buf
* @param options type: [IN]My Param doc
* @param time type: [IN]My Param doc
* @param message type: [IN]My Param doc
*/
static void handle_shutdown_buf(char options[], char time[], char message[])
{
if(NULL == options)
{
bzero(options_buf, 32);
memcpy(options_buf," ", 1);
}
else
{
memcpy(options_buf,options, strlen(options));
}
if(NULL == time)
{
bzero(time_buf, 32);
memcpy(time_buf," ", 1);
}
else
{
memcpy(time_buf, time, strlen(time));
}
if(NULL == message)
{
bzero(message_buf, 32);
memcpy(message_buf," ", 1);
}
else
{
memcpy(message_buf, message, strlen(message));
}
}
int lynq_shutdown(char options[], char time[], char message[])
{
char cmd[128] = {0};
handle_shutdown_buf(options, time, message);
sprintf(cmd, "%s %s %s %s", "shutdown", options_buf, time_buf, message_buf);
system(cmd);
return 0;
}
int lynq_get_version(char buf[])
{
FILE *fp;
char buffer[128];
sprintf(buffer, "%s", "uci get lynq_uci_ro.lynq_version.LYNQ_SW_VERSION");
fp = popen(buffer, "r");
if(NULL == fp)
{
RLOGE("popen failed !");
return -1;
}
if(NULL != fgets(buffer, sizeof(buffer), fp))
{
if('\n' == buffer[strlen(buffer) - 1])
{
buffer[strlen(buffer) - 1] = '\0';
}
}
else
{
RLOGE("fgets failed !");
pclose(fp);
return -1;
}
memcpy(buf, buffer, strlen(buffer));
buf[strlen(buffer)] = '\0';
pclose(fp);
return 0;
}