思路:
要获得cell id,可以通过发送 MSG_ID_MMI_EM_UPDATE_REQ来获得
网络回来的消息为MSE_ID_MMI_EM_UPDATE_RSP,MSG_ID_MMI_EM_STATUS_ID.
可以自行实现这两个消息的处理函数
处理的函数 mmi_em_update_rsp_hdlr 处理请求是否成功。如果不影响原来的工程模式处理可以使用EnginerrModeStartRes
mmi_em_status_ind 处理返回来的所有信息。
要想停止 MSG_ID_MMI_EM_STATUS_IND消息,可以在次发送MSG_ID_MMI_EM_UPDATE_REQ,并将update_req->info_request全部置为EM_OFF.
基站定位:
cell_id unique identifier of the cell (cid for gsm ,bid for cdma)
location_area_code location area code (lac for gsm ,nid for cdma) 位置区号
mobile_country_code mobile country code (mcc for gsm and cdma) 移动国家码
mobile_network_code mobile network code (mnc for gsm,sid for cdma) 移动网络码
age the number of milliseconds since this cell was primary,if age is 0,the cell_id represents a current measurement
signal_strength radio signal strength mearsured in dbm
timing_advance represents the distance from the cell tower.each unit is roughly 550 meters
///其他需要调用基站定位数据地方,可以通过注册一个回调函数来得到相应的基站信息
例如:
1.cagps_reg_valid_cb(cagps_greg_send_agps);
cagps_open();
2.cagps_unreg_valid_cb(cagps_gred_send_agps);
cagps_close();
typedef struct
{
WORD cell_id;
WORD location_area_code;
WORD mobile_country_code;
WORD mobile_network_code;
WORD age;
S16 signal_strength;
WORD timing_advance;
}AGPSDataStruct;
typedef enum
{
AI_NULL = 0x00;
AI_LAI = 0x01;
AI_MR = 0x02;
AI_ALL = 0x03
}AGPS_ITEM;
///基站定位数据回调
typedef void (*cagps_set_agpsdata_cb)(const AGPSDataStruct *p_agpsdata);
typedef struct
{
BOOL bt_open;
AGPSDataStruct agpsdata;
AGPS_ITEM ai_item;
cagps_set_agpsdata_cb set_agpsdata_cb[MAX_GPSM_MODULE_SIZE];
}AGPSParserStruct;
static AGPSParserStruct gAGPSParser;
///启动基站定位的时候需要对其初始化
///1.初始化参数的值,都设置为0.
///2.设置ai_item的参数为AI_NULL表示为接收到基站的信息 AI_LAI AI_MR 表示接收到了LAI MR参数
///3.设置消息映射函数。
void cagps_init(void)
{
meset(&gAGPSParser,0,sizeof(AGPRSParserStruct));
gAGPSParser.ai_item = AI_NULL;
cagps_setevent_handler();
}
///设置消息映射函数,当请求基站定位的时候会参数两个消息MSG_ID_MMI_EM_UPDATE_RSP和MSG_ID_MMI_EM_STATUS_IND
///MSG_ID_MMI_EM_UPDATE_RSP 看是否请求成功。
///MSG_ID_MMI_EM_STATUS_IND 对得到的数据进行处理。
///[注]此处用的是mmi_frm_set_protocol_event_handler();
void cagps_setevent_handler();
{
//SetProtocolEventHandler();
mmi_frm_set_protocol_event_handler(cagps_update_rsp_hdlr,MSG_ID_MMI_EM_UPDATE_RSP,MMI_TRUE);
mmi_frm_set_protocol_event_handler(cagps_status_ind_hdlr,MSG_ID_MMI_EM_STATUS_IND,MMI_TRUE);
}
///对MSG_ID_MMI_EM_UPDATE_RSP的处理
static void cagps_update_rsp_hdlr(void *inMsg)
{
/*mmi_em_update_rsp_struct *rsp_p = (mmi_em_update_rsp_struct *)inMsg;
if(rsp_p == NULL)
{
}
if(rsp_p->result)
{
}
else
{
}*/
}
///对MSG_ID_MMI_EM_STATUS_IND的处理
/*typedef struct
{
LOCAL_PARA_HDR
kal_uint8 mod_id;
kal_uint32 em_info;
peer_buff_struct* info;
} mmi_em_status_ind_struct;
typedef struct
{
kal_uint8 mcc[3]; //MCC
kal_uint8 mnc[3]; //MNC
kal_uint8 lac[2]; //LAC
kal_uint16 cell_id; //cell ID
kal_uint8 nc_info_index; // index in rlc array to acquire the corresponding arfcn, bsic, rxlevel...
} rr_em_lai_info_struct;
*/
static void cagps_status_ind_hdlr(void *info)
{
mmi_em_status_ind_struct *msg = (mmi_em_status_ind_struct *)info;
if(msg == NULL)
{
}
/// 处理lai
if(msg->em_info == RR_EM_LAI_INFO)
{
rr_em_lai_info_struct *data_ptr;
U16 mm_pdu_len;
data_ptr = (rr_em_lai_info_struct *)get_pdu_ptr(msg->info,&mm_pdu_len);
cagps_parse_lai_info(data_ptr);
}
///处理 MR
if(msg->em_info == RR_EM_MEASUREMENT_REPORT_INFO)
{
rr_em_measurement_report_info_struct *data_ptr;
U16 mm_pdu_len;
data_ptr = (rr_em_measurement_report_info_struct *)get_pdu_ptr(msg->info,&mm_pud_len);
cagps_parse_mr_info(data_ptr);
}
free_peer_buff(msg->info);
}
///解析得到的LAI数据
static void cagps_parse_lai_info(const rr_em_lai_info_struct *data_ptr)
{
AGPSDataStruct *p_ckAGPSData = &gAGPSParser.agpsdata;
p_ckAGPSData->cell_id = data_ptr->cell_id;
if(data_ptr->cell_id == 0)
{
return;
}
///lac
memcpy(&p_ckAGPSData->location_area_code,data_ptr->lac,sizeof(WORD));
p_ckAGPSData->location_area_code = cmo_short_reverse((short)p_ckAGPSData->location_area_code);
///mcc
p_ckAGPSData->mobile_country_code = data_ptr->mcc[0]*100 + data_ptr->mcc[1]*10 + data_ptr->mcc[2];
///mnc
if(data_ptr->mnc[2] != 0x0f)
{
p_ckAGPSData->mobile_network_code = data_ptr->mnc[0]*100 + data_ptr->mnc[1]*10 + data_ptr->mnc[2];
}
else
{
p_ckAGPSData->mobile_network_code = data_ptr->mnc[0]*10 + data_ptr->mnc[1];
}
gAGPSParser.ai_item | = AI_LAI;
if(gAGPSParser.ai_item == AI_ALL)
{
cagps_excute_valid_cb(&gAGPSParser.agpsdata);
cagps_reset();
}
}
///解析MR数据
static void cagps_parse_mr_info(const rr_em_measurement_report_info_struct *data_ptr)
{
AGPSDataStruct *p_ckAGPSData = &gAGPSParser.agpsdata;
///ta
if(data_ptr->timing_advance != 0xff)
{
p_ckAGPSData->timing_advance = data_ptr->timing_advance * 550;
}
///RSSI
p_ckAGPSData->signal_strength = data_ptr->serv_rla_in_quarter_dbm * 4;
gAGPSParser.ai_item | = AI_MR;
if(gAGPSParser.ai_item == AI_ALL)
{
cagps_excute_valid_cb(&gAGPSParser.agpsdat);
agps_reset();
}
}
///重置基站定位
static void cagps_reset(void)
{
gAGPSParser.ai_item = AI_NULL;
}
///short类型转换
short cmo_short_reverse(short sh)
{
char *p0 = (char *)&sh;
short ret = 0;
char *p1 = (char *)&ret;
p1[0] = p0[0];
p1[1] = p0[1];
return ret;
}
///注册回调函数
REG_TYPE cagps_reg_valid_cb(cagps_set_agpsdata_cb fun_ptr)
{
U8 i = 0;
cagps_set_agpsdata_cb *parser_data_cb_list = gAGPSParer.set_agpsdata_cb;
ASSERT(fun_ptr != NULL);
while(parser_data_cb_list[i] != fun_ptr)
{
if(parser_data_cb_list[i] == fun_ptr)
{
return RT_HAS_DONE;
}
i++;
if(i >= 6)
{
return RT_FAILED;
}
}
parser_data_cb_list[i] = fun_ptr;
return RT_SUCCESSED;
}
///取消注册回调函数
BOOL cagps_unreg_valid(cagps_set_agpsdata_cb fun_ptr)
{
U8 i = 0;
cagps_set_agpsdata_cb *parser_data_cb_list = gAGPSParser.set_agpsdata_cb;
ASSERT(fun_ptr != NULL);
while(i < 6)
{
if(parser_data_cb_list[i] == fun_ptr)
{
parser_data_cb_list[i] = NULL;
return TRUE;
}
i++;
}
return FALSE;
}
///执行回调函数
static void cagps_excute_valid(const AGPSDataStruct *p_agpsdata)
{
U8 i = 0;
cagps_set_agpsdata_cb *parser_data_cb_list = gAGPSParser.set_agpsdata_cb;
while(i < 6)
{
if(parser_data_cb_list[i] != NULL)
{
(*parser_data_cb_list[i])(p_agpsdata);
}
i++;
}
}
///打开基站定位。发送消息MSG_ID_MMI_EM_UPDATE_REQ
BOOL cagps_open(void)
{
if(!gAGPSParser.bt_open)
{
gAGPSParser.bt_open = TRUE;
share_SendEMUpdateReq(TRUE);
}
return gAGPSParser.bt_open;
}
///关闭基站定位
void cagps_close(void)
{
if(gAGPSParser.bt_open)
{
share_SendEMUpdateReq(FALSE);
gAGPSParser.bt_open = FALSE;
cagps_restet();
}
}
///向系统发送MSG_ID_MMI_EM_UPDATE_REQ的消息处理
/*
typedef struct
{
LOCAL_PARA_HDR
kal_uint8 info_request[EM_INFO_REQ_NUM];
} mmi_em_update_req_struct;
*/
void share_SendEMUpdataReq(BOOL bState)
{
S32 i;
MYQUEUE Message;
mmi_em_update_req_struct *update_req;
Message.oslMsgId = MSG_ID_MMI_EM_UPDATE_REQ;
update_req = OslConstructDataPtr(sizeof(mmi_em_update_req_struct));
for(i = 0; i < EM_INFO_REQ_NUM; i++)
{
update_req->info_requsest[i] = EM_OFF;
}
if(bState)
{
update_req->info_request[RR_EM_LAI_INFO] = EM_ON;
update_req->info_request[RR_EM_MESUREMENT_REPORT_INFO] = EM_ON;
}
Message.oslDataPtr = (oslParaType *)updata_req;
Message.oslPeerBuffPtr = NULL;
Message.oslSrcID = MOD_MMI;
Message.oslDestId = MOD_L4C;
}
///外部得到基站信息
AGPSDataStruct *cagps_get_data(void)
{
WORD wCID = gAGPSParser.agpsdata.cell_id;
if(wCID == 0)
{
}
return &gAGPSParser.agpsdata;
}