blob: b25bbb0b176b335edbccd7fe8ff17f008924a2bf [file] [log] [blame]
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <dlfcn.h>
#include <stdint.h>
#include <errno.h>
#include <stdbool.h>
#include <pthread.h>
#include "gsw_eu_ecall_interface.h"
#include "gsw_log_interface.h"
#define RIL_MAX_NUMBER_LEN 40
#define MBTK_ECALL_MSD_LEN_MAX 600
#define GSW_ECALL "[HAL][GSW_ECALL]"
typedef unsigned int uint32;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef enum {
MBTK_ECALL_URC_ID_ALACK = 0, // AL-ACK signal received (refer to : urc_data)
MBTK_ECALL_URC_ID_SYNC_LOST, // eIM lost synchronization with PSAP
// (A resynch occurs after the synchronization is lost.)
MBTK_ECALL_URC_ID_NACK, // NACK signal received
MBTK_ECALL_URC_ID_RESERVED_3,
MBTK_ECALL_URC_ID_RESERVED_4,
MBTK_ECALL_URC_ID_RESERVED_5, // 5
MBTK_ECALL_URC_ID_3GPP_FATAL, // eIM is terminated: fatal error (3GPP Abort function)
MBTK_ECALL_URC_ID_CALL_DROP, // eIM is terminated: call drop
MBTK_ECALL_URC_ID_GENERIC, // Generic error
MBTK_ECALL_URC_ID_MSD_REQ, // PSAP request MSD (Only for PULL modem)
MBTK_ECALL_URC_ID_MSD_SEND_START, // 10 : eIM starts sending MSD
MBTK_ECALL_URC_ID_INITIATION, // The eIM starts sending the Initiation signal (Only for PUSH modem).
// It also indicates that the call setup is completed.
MBTK_ECALL_URC_ID_SEND_MSD, // PUSH: SEND_MSD -> MSD_SEND_START
// PULL: SEND_MSD -> MSD_REQ -> MSD_SEND_START
MBTK_ECALL_URC_ID_SEND_MSD_FULL,// SEND MSD signal received too often, PSAP sync failure assumed
MBTK_ECALL_URC_ID_SYNCED_PSAP, // IVS eIM is synced with PSAP
MBTK_ECALL_URC_ID_SYNCED_PSAP_EIM, // 15: IVS eIM is synced with PSAP eIM
MBTK_ECALL_URC_ID_LLACK, // Link layer ACK received
MBTK_ECALL_URC_ID_HLACK, // Higher Layer ACK received (similar to AL-ACK (#0) but without data)
MBTK_ECALL_URC_ID_EIM_RESET, // The eIM transmitter idles after a full reset. The eIM transmitter is reset after sync loss
// (for example, because of the end of PSAP transmission).
MBTK_ECALL_URC_ID_EIM_IDLES, // The eIM transmitter idles after the transmission of the Initiation signal (push mode)
MBTK_ECALL_URC_ID_MSD_UPDATE, // 20 : MSD update request is received.
MBTK_ECALL_URC_ID_MSD_UPDATE_DONE, // MSD update is done.
MBTK_ECALL_URC_ID_MSD_UPDATE_ERR, // MSD update request cannot be processed.
MBTK_ECALL_URC_ID_T3_EXPIRED, // T3 expired
MBTK_ECALL_URC_ID_T5_EXPIRED, // T5 expired
MBTK_ECALL_URC_ID_T6_EXPIRED, // 25 : T6 expired
MBTK_ECALL_URC_ID_T7_EXPIRED, // T7 expired
MBTK_ECALL_URC_ID_TH_EXPIRED, // TH expired
MBTK_ECALL_URC_ID_RESERVED_28,
MBTK_ECALL_URC_ID_RESERVED_29,
MBTK_ECALL_URC_ID_RESERVED_30, // 30
MBTK_ECALL_URC_ID_IVS_EVENT_TIMEOUT,
MBTK_ECALL_URC_ID_PSAP_REQ, // Only for ERA
MBTK_ECALL_URC_ID_MSD_SEND_FAIL_FOR_NG // NG-eCall fail to transfer MSD
} mbtk_ecall_urc_id_enum;
typedef enum {
MBTK_CLCC = 1,
MBTK_CPAS,
MBTK_DISCONNECTED,
} mbtk_call_enum;
typedef enum {
MBTK_CALL_RADY, //MT allows commands from TA/TE
MBTK_CALL_UNAVAILABLE, //MT does not allow commands from TA/TE
MBTK_CALL_UNKNOWN, //MT is not guaranteed to respond to instructions
MBTK_CALL_RINGING, //MT is ready for commands from TA/TE, but the ringer is active
MBTK_CALL_PROGRESS, //MT is ready for commands from TA/TE, but a call is in progress
MBTK_CALL_ASLEEP, //MT is unable to process commands from TA/TE because it is in a low functionality state
MBTK_CALL_ACTIVE,
} mbtk_call_pas_enum;
#define MBTK_ECALL_CFG_T3 (1 << MBTK_ECALL_CFG_ITEM_T3) // ms
#define MBTK_ECALL_CFG_T5 (1 << MBTK_ECALL_CFG_ITEM_T5) // ms
#define MBTK_ECALL_CFG_T6 (1 << MBTK_ECALL_CFG_ITEM_T6) // ms
#define MBTK_ECALL_CFG_T7 (1 << MBTK_ECALL_CFG_ITEM_T7) // ms
#define MBTK_ECALL_CFG_TH (1 << MBTK_ECALL_CFG_ITEM_TH) // ms
#define MBTK_ECALL_CFG_TIMER_CALLBACK (1 << MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK) // T9
#define MBTK_ECALL_CFG_TIMER_CLEARDOWN (1 << MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN) // T2
#define MBTK_ECALL_CFG_TIMER_DEREG (1 << MBTK_ECALL_CFG_ITEM_TIMER_DEREG) // T10
#define MBTK_ECALL_CFG_TIMER_DIAL (1 << MBTK_ECALL_CFG_ITEM_TIMER_DIAL) // "dial"
#define MBTK_ECALL_CFG_TIMER_REDIAL (1 << MBTK_ECALL_CFG_ITEM_TIMER_REDIAL) // "redialtmr"
#define MBTK_ECALL_CFG_TIMER_SMS (1 << MBTK_ECALL_CFG_ITEM_TIMER_SMS) // "sms" // 10
#define MBTK_ECALL_CFG_REDIALCNT (1 << MBTK_ECALL_CFG_ITEM_REDIALCNT) // "redialcnt"
#define MBTK_ECALL_CFG_SMSPROCESS (1 << MBTK_ECALL_CFG_ITEM_SMSPROCESS) // "smsprocess"
#define MBTK_ECALL_CFG_SMSMSDCNT (1 << MBTK_ECALL_CFG_ITEM_SMSMSDCNT) // "smsmsdcnt"
typedef void (*mbtk_info_callback_func)(const void* data, int data_len);
typedef struct
{
int client_fd;
pthread_t read_thread_id;
int exit_fd[2];
bool is_waitting;
pthread_cond_t cond;
pthread_mutex_t mutex;
pthread_mutex_t send_mutex;
// Temp response data.
uint16 info_err;
uint16 data_len;
void *data;
//mbtk wyq for server_ready_status add start
char server_ready_status;
//mbtk wyq for server_ready_status add end
mbtk_info_callback_func net_state_cb;
mbtk_info_callback_func call_state_cb;
mbtk_info_callback_func sms_state_cb;
mbtk_info_callback_func radio_state_cb;
mbtk_info_callback_func sim_state_cb;
mbtk_info_callback_func pdp_state_cb;
//add signal by xr
mbtk_info_callback_func signal_state_cb;
} mbtk_info_handle_t;
typedef enum {
MBTK_ECALL_CFG_ITEM_T3 = 0, // ms
MBTK_ECALL_CFG_ITEM_T5, // ms
MBTK_ECALL_CFG_ITEM_T6, // ms
MBTK_ECALL_CFG_ITEM_T7, // ms
MBTK_ECALL_CFG_ITEM_TH, // ms
MBTK_ECALL_CFG_ITEM_TIMER_CALLBACK, // T9 // 5
MBTK_ECALL_CFG_ITEM_TIMER_CLEARDOWN, // T2
MBTK_ECALL_CFG_ITEM_TIMER_DEREG, // T10
MBTK_ECALL_CFG_ITEM_TIMER_DIAL, // "dial"
MBTK_ECALL_CFG_ITEM_TIMER_REDIAL, // "redialtmr"
MBTK_ECALL_CFG_ITEM_TIMER_SMS, // "sms" // 10
MBTK_ECALL_CFG_ITEM_REDIALCNT, // "redialcnt"
MBTK_ECALL_CFG_ITEM_SMSPROCESS, // "smsprocess"
MBTK_ECALL_CFG_ITEM_SMSMSDCNT, // "smsmsdcnt"
MBTK_ECALL_CFG_ITEM_MAX
} mbtk_ecall_cfg_item_enum;
typedef enum {
MBTK_ECALL_MSD_ITEM_VERSION = 0,
MBTK_ECALL_MSD_ITEM_MSG_ID,
MBTK_ECALL_MSD_ITEM_CONTROLTYPE,
MBTK_ECALL_MSD_ITEM_VIN,
MBTK_ECALL_MSD_ITEM_STORAGETYPE,
MBTK_ECALL_MSD_ITEM_TIMESTAMP,
MBTK_ECALL_MSD_ITEM_LOCATION,
MBTK_ECALL_MSD_ITEM_DIRECTION,
MBTK_ECALL_MSD_ITEM_LOCATIONN1,
MBTK_ECALL_MSD_ITEM_LOCATIONN2,
MBTK_ECALL_MSD_ITEM_NUMBEROFOCCUPANTS,
MBTK_ECALL_MSD_ITEM_ADDITIONALDATA,
MBTK_ECALL_MSD_ITEM_ALL_IN_ONE,
MBTK_ECALL_MSD_ITEM_ASI,
MBTK_ECALL_MSD_ITEM_VEHICLE_DIAGNOSTIC,
MBTK_ECALL_MSD_ITEM_CRASH_INFO,
MBTK_ECALL_MSD_ITEM_GNSS_TYPE
} mbtk_ecall_msd_item_enum;
typedef enum {
MBTK_ECALL_ONLY_TYPE_DISABLE = 0,
MBTK_ECALL_ONLY_TYPE_ENABLE_ECALL,
MBTK_ECALL_ONLY_TYPE_ENABLE_NG_ECALL,
MBTK_ECALL_ONLY_TYPE_ENABLE_ALL,
MBTK_ECALL_ONLY_TYPE_CONF_NUM,
MBTK_ECALL_ONLY_TYPE_NORMAL
} mbtk_ecall_only_type_enum;
typedef struct
{
mbtk_ecall_msd_item_enum item_type;
uint8 data[64];
} mbtk_ecall_msd_cfg_info_t;
typedef enum {
MBTK_ECALL_SIM_TYPE_NO_SUPPORT = 0,
MBTK_ECALL_SIM_TYPE_SUPPORT_ECALL,
MBTK_ECALL_SIM_TYPE_SUPPORT_ECALL_ONLY
} mbtk_ecall_sim_type_enum;
typedef struct {
mbtk_ecall_only_type_enum active : 8;
mbtk_ecall_sim_type_enum sim_type : 8; // Only for GET.
uint8 test_num[RIL_MAX_NUMBER_LEN];
uint8 reconfig_num[RIL_MAX_NUMBER_LEN];
} mbtk_ecall_only_info_t;
typedef enum {
MBTK_ECALL_MODE_TYPE_EU = 0,
MBTK_ECALL_MODE_TYPE_ERA
} mbtk_ecall_mode_type_enum;
typedef enum {
MBTK_ECALL_DIAL_TYPE_TEST = 0,
MBTK_ECALL_DIAL_TYPE_RECONFIG,
MBTK_ECALL_DIAL_TYPE_MANUALLY,
MBTK_ECALL_DIAL_TYPE_AUTO,
MBTK_ECALL_DIAL_TYPE_NOT_ACTIVATED,
MBTK_ECALL_DIAL_TYPE_RELEASE
} mbtk_ecall_dial_type_enum;
typedef struct {
uint32 type; // mbtk_ecall_cfg_item_enum
#if 0
uint32 timer_t3; // ms
uint32 timer_t5; // ms
uint32 timer_t6; // ms
uint32 timer_t7; // ms
uint32 timer_th; // ms
uint32 timer_callback; // s (T9)
uint32 timer_cleardown; // s (T2)
uint32 timer_dereg; // s (T10)
uint32 timer_dial; // s
uint32 timer_redialtmr; // s
uint32 timer_sms; // s
uint32 redialcnt;
uint32 smsprocess;
uint32 smsmsdcnt;
#else
uint8 data_valid[MBTK_ECALL_CFG_ITEM_MAX];
uint32 data[MBTK_ECALL_CFG_ITEM_MAX];
#endif
} mbtk_ecall_cfg_info_t;
typedef struct
{
uint8 urc_id;
uint8 urc_data[5];
} mbtk_ril_ecall_state_info_t;
typedef mbtk_info_handle_t* (*mbtk_info_handle_get)(void);
static mbtk_info_handle_get mbtk_info_handle_get_ptr = NULL;
typedef int (*mbtk_info_handle_free)(mbtk_info_handle_t** handle);
static mbtk_info_handle_free mbtk_info_handle_free_ptr = NULL;
static gsw_eu_ecall_status_cb_f gsw_eu_ecall_status_cb;
static pthread_t gsw_ecall_status_cb_thread;
static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;
static bool g_thread_running = false;
static uint32_t g_sta_cb_id = 0;
static gsw_eu_ecall_msd_trans_status_e g_msd_send_status = 0;
#define LIB_PATH "/lib/libmbtk_lib.so"
typedef int (*mbtk_ecall_msd_set)(mbtk_info_handle_t* handle, const void* msd);
static mbtk_ecall_msd_set mbtk_ecall_msd_set_ptr = NULL;
typedef int (*mbtk_ecall_push)(mbtk_info_handle_t* handle);
static mbtk_ecall_push mbtk_ecall_push_ptr = NULL;
typedef int (*mbtk_ecall_only_set)(mbtk_info_handle_t* handle, const mbtk_ecall_only_info_t* info);
static mbtk_ecall_only_set mbtk_ecall_only_set_ptr = NULL;
typedef int (*mbtk_ecall_reg_set)(mbtk_info_handle_t* handle, int reg);
static mbtk_ecall_reg_set mbtk_ecall_reg_set_ptr = NULL;
typedef int (*mbtk_ecall_dial_start)(mbtk_info_handle_t* handle, mbtk_ecall_dial_type_enum type);
static mbtk_ecall_dial_start mbtk_ecall_dial_start_ptr = NULL;
typedef int (*mbtk_ecall_mode_set)(mbtk_info_handle_t* handle, mbtk_ecall_mode_type_enum mode);
static mbtk_ecall_mode_set mbtk_ecall_mode_set_ptr = NULL;
typedef int (*mbtk_ecall_cfg_set)(mbtk_info_handle_t* handle, const mbtk_ecall_cfg_info_t *cfg);
static mbtk_ecall_cfg_set mbtk_ecall_cfg_set_ptr = NULL;
typedef int (*mbtk_ecall_cfg_get)(mbtk_info_handle_t* handle, mbtk_ecall_cfg_info_t* cfg);
static mbtk_ecall_cfg_get mbtk_ecall_cfg_get_ptr = NULL;
typedef int (*mbtk_ecall_state_change_cb_reg)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb);
static mbtk_ecall_state_change_cb_reg mbtk_ecall_state_change_cb_reg_ptr = NULL;
typedef int (*mbtk_call_state_change_cb_reg)(mbtk_info_handle_t* handle, mbtk_info_callback_func cb);
static mbtk_call_state_change_cb_reg mbtk_call_state_change_cb_reg_ptr = NULL;
static int state_t = -1;
typedef struct
{
uint8 call_wait;
uint8 dir1;
uint8 dir;
uint8 state;
uint8 mode;
uint8 mpty;
char phone_number[100];
uint8 type;
uint8 pas;
uint8 disconnected_id;
uint8 end_reason[128];
} __attribute__((packed)) mbtk_call_info_t;
//static mbtk_info_handle_t* ecall_info_handle = NULL;
static void *handle = NULL;
static int ecall_init_flag = 0;
static mbtk_info_handle_t* ecall_info_handle = NULL;
static uint8_t fail_redial = 1;
static gsw_eu_ecall_event_cb_f gsw_eu_ecall_event_cb = NULL;
static bool g_setevent_cb = false;
static void mbtk_send_singnal()
{
pthread_mutex_lock(&g_mutex);
pthread_cond_signal(&g_cond);
pthread_mutex_unlock(&g_mutex);
}
static void mbtk_wait_signal()
{
pthread_mutex_lock(&g_mutex);
pthread_cond_wait(&g_cond, &g_mutex);
pthread_mutex_unlock(&g_mutex);
}
static void mbtk_ecall_api_ptr_deinit()
{
dlclose(handle);
handle = NULL;
mbtk_info_handle_get_ptr=NULL;
mbtk_info_handle_free_ptr=NULL;
mbtk_ecall_msd_set_ptr=NULL;
mbtk_ecall_push_ptr=NULL;
mbtk_ecall_only_set_ptr=NULL;
mbtk_ecall_reg_set_ptr=NULL;
mbtk_ecall_dial_start_ptr=NULL;
mbtk_ecall_mode_set_ptr=NULL;
mbtk_ecall_cfg_set_ptr=NULL;
mbtk_ecall_cfg_get_ptr=NULL;
mbtk_ecall_state_change_cb_reg_ptr=NULL;
gsw_eu_ecall_status_cb=NULL;
gsw_eu_ecall_event_cb=NULL;
g_setevent_cb=false;
mbtk_ecall_only_set_ptr = NULL;
}
static int mbtk_ecall_api_import()
{
handle = dlopen(LIB_PATH, RTLD_NOW);
if (handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
if(mbtk_info_handle_get_ptr == NULL)
{
mbtk_info_handle_get_ptr = (mbtk_info_handle_get)dlsym(handle, "mbtk_info_handle_get");
if(mbtk_info_handle_get_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_info_handle_free_ptr == NULL)
{
mbtk_info_handle_free_ptr = (mbtk_info_handle_free)dlsym(handle, "mbtk_info_handle_free");
if(mbtk_info_handle_free_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_msd_set_ptr == NULL)
{
mbtk_ecall_msd_set_ptr = (mbtk_ecall_msd_set)dlsym(handle, "mbtk_ecall_msd_set");
if(mbtk_ecall_msd_set_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_push_ptr == NULL)
{
mbtk_ecall_push_ptr = (mbtk_ecall_push)dlsym(handle, "mbtk_ecall_push");
if(mbtk_ecall_push_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_only_set_ptr == NULL)
{
mbtk_ecall_only_set_ptr = (mbtk_ecall_only_set)dlsym(handle, "mbtk_ecall_only_set");
if(mbtk_ecall_only_set_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_reg_set_ptr == NULL)
{
mbtk_ecall_reg_set_ptr = (mbtk_ecall_reg_set)dlsym(handle, "mbtk_ecall_reg_set");
if(mbtk_ecall_reg_set_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_dial_start_ptr == NULL)
{
mbtk_ecall_dial_start_ptr = (mbtk_ecall_dial_start)dlsym(handle, "mbtk_ecall_dial_start");
if(mbtk_ecall_dial_start_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_mode_set_ptr == NULL)
{
mbtk_ecall_mode_set_ptr = (mbtk_ecall_mode_set)dlsym(handle, "mbtk_ecall_mode_set");
if(mbtk_ecall_mode_set_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_cfg_set_ptr == NULL)
{
mbtk_ecall_cfg_set_ptr = (mbtk_ecall_cfg_set)dlsym(handle, "mbtk_ecall_cfg_set");
if(mbtk_ecall_cfg_set_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_cfg_get_ptr == NULL)
{
mbtk_ecall_cfg_get_ptr = (mbtk_ecall_cfg_get)dlsym(handle, "mbtk_ecall_cfg_get");
if(mbtk_ecall_cfg_get_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_ecall_state_change_cb_reg_ptr == NULL)
{
mbtk_ecall_state_change_cb_reg_ptr = (mbtk_ecall_state_change_cb_reg)dlsym(handle, "mbtk_ecall_state_change_cb_reg");
if(mbtk_ecall_state_change_cb_reg_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
if(mbtk_call_state_change_cb_reg_ptr == NULL)
{
mbtk_call_state_change_cb_reg_ptr = (mbtk_call_state_change_cb_reg)dlsym(handle, "mbtk_call_state_change_cb_reg");
if(mbtk_call_state_change_cb_reg_ptr == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
}
return GSW_HAL_SUCCESS;
}
static void gsw_call_state_change_cb(const void *data, int data_len)
{
mbtk_call_info_t *reg = (mbtk_call_info_t *)data;
switch (reg->call_wait)
{
case MBTK_CLCC:
{
LOGD(GSW_ECALL,"RING : %d, %d, %d, %d, %d, %s, %d, %d", reg->dir1, reg->dir, reg->state, reg->mode, reg->mpty, reg->phone_number, reg->type, reg->disconnected_id);
switch(reg->state)
{
case 0:
state_t = 0;
LOGD(GSW_ECALL,"reg->state = GSW_VOICE_CALL_CONNECTED ");
break;
case 1:
//state_t = GSW_VOICE_CALL_HOLDING;
LOGD(GSW_ECALL,"reg->state = GSW_VOICE_CALL_HOLDING ");
break;
case 2:
//state_t = GSW_VOICE_CALL_DIALING;
LOGD(GSW_ECALL,"reg->state = GSW_VOICE_CALL_DIALING ");
break;
case 3:
//state_t = GSW_VOICE_CALL_ALERTING;
LOGD(GSW_ECALL,"reg->state = GSW_VOICE_CALL_ALERTING ");
break;
case 4:
//state_t = GSW_VOICE_CALL_INCOMING;
LOGD(GSW_ECALL,"reg->state = GSW_VOICE_CALL_INCOMING ");
break;
case 5:
//state_t = GSW_VOICE_CALL_WAITING;
LOGD(GSW_ECALL,"reg->state = GSW_VOICE_CALL_WAITING ");
break;
case 6:
//state_t = GSW_VOICE_CALL_END;
LOGD(GSW_ECALL,"reg->state = GSW_VOICE_CALL_END ");
break;
}
g_sta_cb_id = reg->dir1;
}
break;
default:
LOGE(GSW_ECALL,"RING : None call_wait = %d", reg->call_wait);
break;
}
}
/**
* @brief init the Europe Ecall voice
* @param [in] None
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_voice_init(void)
{
int ret =-1;
ret = mbtk_ecall_api_import();
if(ret <0)
{
return GSW_HAL_NORMAL_FAIL;
}
ecall_info_handle = mbtk_info_handle_get_ptr();
if(ecall_info_handle == NULL)
{
LOGE(GSW_ECALL,"mbtk_info_handle_get_ptr fail!!!");
return GSW_HAL_NORMAL_FAIL;
}
if(ecall_init_flag == 0)
{
ecall_init_flag = 1;
}
ret = mbtk_call_state_change_cb_reg_ptr(ecall_info_handle, gsw_call_state_change_cb);
if(ret < 0)
{
LOGE(GSW_ECALL,"mbtk_call_state_change_cb_reg_ptr failed");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief deinit the Europe Ecall voice
* @param [in] None
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_voice_deinit(void)
{
int ret = -1;
if(ecall_info_handle == NULL || ecall_init_flag ==0)
{
LOGE(GSW_ECALL,"No init can not deinit");
return GSW_HAL_NORMAL_FAIL;
}
g_thread_running = false;
mbtk_send_singnal();
if (gsw_ecall_status_cb_thread != 0)
{
pthread_cancel(gsw_ecall_status_cb_thread);
pthread_join(gsw_ecall_status_cb_thread, NULL);
gsw_ecall_status_cb_thread = 0;
}
ret = mbtk_info_handle_free_ptr(&ecall_info_handle);
if(ret < 0 )
{
LOGE(GSW_ECALL,"mbtk_info_handle_free handle faile");
}
ecall_info_handle = NULL;
ecall_init_flag = 0;
mbtk_ecall_api_ptr_deinit();
return GSW_HAL_SUCCESS;
}
/**
* @brief start a Europe Ecall
* @param [in] gsw_eu_ecall_info_t *p_info: ecall info
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_start(gsw_eu_ecall_info_t *p_info)
{
int ret = -1;
mbtk_ecall_dial_type_enum ecall_type= -1;
mbtk_ecall_only_info_t only_info;
char tmp_number[GSW_EU_ECALL_MAX_PHONE_NUMBER] = {0};
char msd_data[500] = {0};
memset(&only_info, 0, sizeof(mbtk_ecall_only_info_t));
if(ecall_init_flag !=1)
{
return GSW_HAL_NORMAL_FAIL;
}
if(p_info == NULL || p_info->msd_len > GSW_EU_ECALL_MAX_MSD )
{
return GSW_HAL_NORMAL_FAIL;
}
if(p_info->type == GSW_EU_ECALL_TYPE_TEST)
{
//AT+CECALL =0
ecall_type = MBTK_ECALL_DIAL_TYPE_TEST;
snprintf(tmp_number,sizeof(tmp_number),"%s",p_info->ecall_number);
strncpy((char *)only_info.test_num,tmp_number,RIL_MAX_NUMBER_LEN-1);
only_info.test_num[RIL_MAX_NUMBER_LEN-1]='\0';
//snprintf((char*)only_info.test_num,sizeof(only_info.test_num),"%s",p_info->ecall_number);
}
if(p_info->type == GSW_EU_ECALL_TYPE_RECONFIG )
{
//AT+CECALL =1
ecall_type = MBTK_ECALL_DIAL_TYPE_RECONFIG;
snprintf(tmp_number,sizeof(tmp_number),"%s",p_info->ecall_number);
strncpy((char *)only_info.test_num,tmp_number,RIL_MAX_NUMBER_LEN-1);
only_info.test_num[RIL_MAX_NUMBER_LEN-1]='\0';
}
if(p_info->type == GSW_EU_ECALL_TYPE_EMERGENCY )
{
if(p_info->auto_trigger)
{
//AT+CECALL =1
ecall_type = MBTK_ECALL_DIAL_TYPE_AUTO;
}
else
{
//AT+CECALL =1
ecall_type = MBTK_ECALL_DIAL_TYPE_MANUALLY;//手动
}
}
//msd
for (int i = 0; i < p_info->msd_len; i++)
{
sprintf(msd_data + (i * 2), "%02x", p_info->msd[i]);
}
//
only_info.active = MBTK_ECALL_ONLY_TYPE_DISABLE ;
ret=mbtk_ecall_only_set_ptr(ecall_info_handle,&only_info);
if (ret != 0)
{
LOGE(GSW_ECALL,"mbtk_ecall_only_set_success failed");
return GSW_HAL_NORMAL_FAIL;
}
//set msd
ret= mbtk_ecall_msd_set_ptr(ecall_info_handle,(const void*)msd_data);
if (ret != 0)
{
LOGE(GSW_ECALL,"mbtk_ecall_msd_set_ptr failed");
return GSW_HAL_NORMAL_FAIL;
}
//dial
ret= mbtk_ecall_dial_start_ptr(ecall_info_handle,ecall_type);
if (ret != 0)
{
LOGE(GSW_ECALL,"mbtk_ecall_dial_start_ptr failed");
return GSW_HAL_NORMAL_FAIL;
}
//push mst
ret= mbtk_ecall_push_ptr(ecall_info_handle);
if (ret != 0)
{
g_msd_send_status = GSW_EU_ECALL_MSD_TRANS_STATUS_FAILURE;
mbtk_send_singnal();
LOGE(GSW_ECALL,"mbtk_ecall_push_ptr failed");
return GSW_HAL_NORMAL_FAIL;
}
g_msd_send_status = GSW_EU_ECALL_MSD_TRANS_STATUS_SUCCESS;
mbtk_send_singnal();
return GSW_HAL_SUCCESS;
}
/**
* @brief hangup a Europe Ecall
* @param [in] None
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_hangup(void)
{
int32_t ret = -1;
if(ecall_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
ret = mbtk_ecall_dial_start_ptr(ecall_info_handle,MBTK_ECALL_DIAL_TYPE_RELEASE);
if(ret != 0)
{
LOGE(GSW_ECALL,"hangup ecall faile ");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
/**
* @brief using push mode send msd data
* @param [in] GSW_EU_ECALL_STATE_E state: ecall state
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_updateMsd(const uint8_t *msd, uint32_t msd_len)
{
int ret = -1;
char msd_data[500] = {0};
if(msd == NULL || msd_len == 0 ||ecall_info_handle == NULL)
{
return GSW_HAL_NO_MEMORY;
}
//msd
for (int i = 0; i < msd_len; i++)
{
sprintf(msd_data + i * 2, "%02x", *(msd + i));
}
ret = mbtk_ecall_msd_set_ptr(ecall_info_handle,(const void*)msd_data);
if (ret != 0)
{
LOGE(GSW_ECALL,"mbtk_ecall_msd_get_ptr failed");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
int32_t gsw_eu_ecall_pushMsd(gsw_eu_ecall_state_e state)
{
int ret = -1;
if(ecall_info_handle == NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
ret = mbtk_ecall_push_ptr(ecall_info_handle);
if(ret != 0)
{
g_msd_send_status = GSW_EU_ECALL_MSD_TRANS_STATUS_FAILURE;
mbtk_send_singnal();
return GSW_HAL_NORMAL_FAIL;
}
g_msd_send_status = GSW_EU_ECALL_MSD_TRANS_STATUS_SUCCESS;
mbtk_send_singnal();
return GSW_HAL_SUCCESS;
}
/**
* @brief get ecall config
* @param [in] None
* @param [out] gsw_eu_ecall_config_t *p_config: ecall config
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_getConfig(gsw_eu_ecall_config_t *p_config)
{
if(ecall_info_handle==NULL || p_config == NULL)
{
LOGE(GSW_ECALL,"mbtk_ecall_cfg_get() fail.");
return GSW_HAL_NO_MEMORY;
}
p_config->fail_redial = fail_redial;
return GSW_HAL_SUCCESS;
}
/**
* @brief set ecall config
* @param [in] int32_t item: config item
* @param [in] gsw_eu_ecall_config_t *p_config: config info
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_setConfig(int32_t item, gsw_eu_ecall_config_t *p_config)
{
if(ecall_info_handle == NULL || p_config == NULL)
{
LOGE(GSW_ECALL,"gsw_eu_ecall_setConfig no init");
return GSW_HAL_NO_MEMORY;
}
mbtk_ecall_cfg_info_t cfg_info = {0};
int ret =-1;
cfg_info.type = 0;
if(item & GSW_EU_ECALL_CONFIG_FAIL_REDIAL)
{
fail_redial = p_config->fail_redial;
if(p_config->fail_redial)
{
cfg_info.type |= MBTK_ECALL_CFG_TIMER_DIAL;
cfg_info.data[MBTK_ECALL_CFG_ITEM_TIMER_DIAL] = 60000;//timer 60s
}
else
{
cfg_info.type |= MBTK_ECALL_CFG_TIMER_DIAL;
cfg_info.data[MBTK_ECALL_CFG_ITEM_TIMER_DIAL] = 0;
}
}
ret = mbtk_ecall_cfg_set_ptr(ecall_info_handle, &cfg_info);
if (ret < 0)
{
LOGE(GSW_ECALL,"mbtk_ecall_cfg_set_ptr fail");
return GSW_HAL_NORMAL_FAIL;
}
return GSW_HAL_SUCCESS;
}
static void mbtk_ecall_state_change_cb(const void* data, int data_len)
{
static gsw_eu_ecall_event_t event;
if(data)
{
mbtk_ril_ecall_state_info_t *ecall_data = (mbtk_ril_ecall_state_info_t*)data;
switch(ecall_data->urc_id)
{
case MBTK_ECALL_URC_ID_MSD_REQ:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_MSD_REQ");
event.process = GSW_EU_ECALL_EVENT_PROCESS_IVS_START_RECEIVED_MSD;
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPDATE_PSAP_REQURE_UPDATE_MSD;
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_NONE;
event.establish = GSW_EU_ECALL_EVENT_ESTABLISH_NONE;
break;
}
case MBTK_ECALL_URC_ID_MSD_SEND_START:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_MSD_SEND_START");
event.process = GSW_EU_ECALL_EVENT_PROCESS_IVS_START_RECEIVED_MSD;
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPDATE_PSAP_REQURE_UPDATE_MSD;
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_NONE;
event.establish = GSW_EU_ECALL_EVENT_ESTABLISH_NONE;
break;
}
case MBTK_ECALL_URC_ID_NACK:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_NACK");
event.process = GSW_EU_ECALL_EVENT_PROCESS_IVS_NACK_RECEIVED;
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPADTE_NONE;
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_NONE;
event.establish = GSW_EU_ECALL_EVENT_ESTABLISH_NONE;
break;
}
case MBTK_ECALL_URC_ID_LLACK:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_LLACK");
event.process = GSW_EU_ECALL_EVENT_PROCESS_IVS_ACK_RECEIVED;
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPADTE_NONE;
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_IVS_LLACK_RECEIVED;
event.establish = GSW_EU_ECALL_EVENT_ESTABLISH_SUCCESS;
g_msd_send_status = GSW_EU_ECALL_MSD_TRANS_STATUS_SUCCESS;
mbtk_send_singnal();
break;
}
case MBTK_ECALL_URC_ID_HLACK:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_HLACK");
event.fail = GSW_EU_ECALL_EVENT_FAIL_NONE;
event.process = GSW_EU_ECALL_EVENT_PROCESS_IVS_HLACK_RECEIVED;
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPADTE_NONE;
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_NONE;
event.establish = GSW_EU_ECALL_EVENT_ESTABLISH_SUCCESS;
g_msd_send_status = GSW_EU_ECALL_MSD_TRANS_STATUS_SUCCESS;
mbtk_send_singnal();
break;
}
case MBTK_ECALL_URC_ID_ALACK:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_ALACK");
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_IVS_ALACK_RECEIVED;
}
case MBTK_ECALL_URC_ID_MSD_UPDATE_DONE:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_MSD_UPDATE_DONE");
event.process = GSW_EU_ECALL_EVENT_PROCESS_IVS_NONE;
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPADTE_NONE;
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_NONE;
event.establish = GSW_EU_ECALL_EVENT_ESTABLISH_SUCCESS;
}
case MBTK_ECALL_URC_ID_T5_EXPIRED:
case MBTK_ECALL_URC_ID_T6_EXPIRED:
case MBTK_ECALL_URC_ID_T7_EXPIRED:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_T5_EXPIRED | MBTK_ECALL_URC_ID_T5_EXPIRED | MBTK_ECALL_URC_ID_T7_EXPIRED");
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPDATE_IVS_UPDATE_MSD_TIMEOUT;
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_NONE;
event.establish = GSW_EU_ECALL_EVENT_ESTABLISH_SUCCESS;
g_msd_send_status = GSW_EU_ECALL_MSD_TRANS_STATUS_FAILURE;
mbtk_send_singnal();
break;
}
case MBTK_ECALL_URC_ID_3GPP_FATAL:
case MBTK_ECALL_URC_ID_GENERIC:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_GENERIC|MBTK_ECALL_URC_ID_3GPP_FATAL");
event.extend_state = GSW_EU_ECALL_EVENT_EXTEND_STATE_NONE;
}
case MBTK_ECALL_URC_ID_MSD_UPDATE_ERR:
{
LOGD(GSW_ECALL,"MBTK_ECALL_URC_ID_MSD_UPDATE_ERR");
event.msdupdate = GSW_EU_ECALL_EVENT_MSDUPDATE_IVS_UPDATE_MSD_TIMEOUT;
}
default:
{
LOGE(GSW_ECALL,"No process urc_id : %d", ecall_data->urc_id);
break;
}
}
}
if(gsw_eu_ecall_event_cb)
{
gsw_eu_ecall_event_cb(&event);
}
}
/**
* @brief register the ecall status callback
* @param [in] gsw_eu_ecall_status_cb_f cb:callback
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_setEventCB(gsw_eu_ecall_event_cb_f cb)
{
int ret = -1;
if(ecall_info_handle==NULL)
{
return GSW_HAL_NO_MEMORY;
}
gsw_eu_ecall_event_cb = cb;
if(!g_setevent_cb)
{
ret = mbtk_ecall_state_change_cb_reg_ptr(ecall_info_handle, mbtk_ecall_state_change_cb);
if(ret < 0)
{
LOGE(GSW_ECALL,"mbtk_ecall_state_change_cb_reg_ptr failed");
return GSW_HAL_NORMAL_FAIL;
}
g_setevent_cb = true;
}
return GSW_HAL_SUCCESS;
}
static void* ecall_msd_status_cb_thread(void* arg)
{
while(g_thread_running)
{
mbtk_wait_signal();
if(g_thread_running == false)
{
return NULL;
}
if(gsw_eu_ecall_status_cb)
{
gsw_eu_ecall_status_cb(g_sta_cb_id,g_msd_send_status);
}
}
return NULL;
}
/**
* @brief register the ecall status callback
* @param [in] gsw_eu_ecall_status_cb_f cb:callback
* @param [out] None
* @retval GSW_HAL_SUCCESS\GSW_HAL_NORMAL_FAIL
*/
int32_t gsw_eu_ecall_setStatusCB(gsw_eu_ecall_status_cb_f cb)
{
int ret = -1;
if(ecall_info_handle==NULL)
{
return GSW_HAL_NORMAL_FAIL;
}
gsw_eu_ecall_status_cb = cb;
if (!g_thread_running)
{
ret = pthread_create(&gsw_ecall_status_cb_thread, NULL, ecall_msd_status_cb_thread, NULL);
if(ret < 0)
{
LOGE(GSW_ECALL,"pthread_create failed");
g_thread_running = false;
return GSW_HAL_NORMAL_FAIL;
}
g_thread_running = true;
}
return GSW_HAL_SUCCESS;
}