背景:
公司开发的产品因为硬件不给力导致有些机器在刚开机(重新冷启动)之后,明显在空旷的地方都提示很长时间搜不到星的问题。
由于产品开发周期的问题,只能使用其它补救方案,目前由ublox模组厂家提供解决方案,开机阶段定位搜星不到时增加AGPS定位功能。
方法如下:
在GPS的Hardware层添加以下代码:
增加AGPS功能:
t7\android\hardware\aw\gps\gps.c
//static GpsState _gps_state[1];
//static GpsState *gps_state = _gps_state;
//static int sleep_lock = 1; //Changed by Tommy 0;
//static int lastcmd = 0;
//static int bGetFormalNMEA = 1;
//static int started = 0;
//static int continue_thread = 1;
//static int bOrionShutdown = 0;
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define CAS_AGPS_SERVER "www.gnss-aide.com" //杭州中科微电子的GPS服务器,使用中科微的模块
#define CAS_AGPS_PORT_NO 2621 //端口
#define USER_NAME "freetrial" //用户名
#define PASS_WORD "123456" //密码
#define LOCATION_LAT "persist.sys.lat" //位置经纬度信息
#define LOCATION_LON "persist.sys.lon"
#define LAT_DEF "22.595395"
#define LON_DEF "114.005019" //默认是小数点后6位
#define STEP_0_UNKNOWN 0
#define STEP_1_GETHOST 1
#define STEP_2_CONNECT 2
#define STEP_3_SENDNET 3
#define STEP_4_CANREAD 4
static uint8_t agps_step = STEP_1_GETHOST; //自定义状态
int sockfd = -1;
struct sockaddr_in serv_addr;
#define AGPS_READ_MAX 1024
#define AGPS_BUF_MAX 5120
static pthread_t agps_thread_id;
void disconnectAGPS(void)
{
DFR("agps_step=%d", agps_step);
if(sockfd > 0)close(sockfd);
sockfd = -1;
agps_step = STEP_0_UNKNOWN;
//pthread_exit(agps_thread_id);
}
void connectAGPS(int uartFd)
{
DFR("agps_step=%d", agps_step);
switch(agps_step){
case STEP_1_GETHOST:
if(agps_step == STEP_1_GETHOST){ //获取主机名称和端口号
struct hostent *server = gethostbyname(CAS_AGPS_SERVER);
if(server != NULL){
DFR("Copy agps server information to socket address struct");
memset((char *) &serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, server->h_length);
serv_addr.sin_port = htons(CAS_AGPS_PORT_NO);
agps_step = STEP_2_CONNECT;
} else {
DFR("ERROR, no such host.");
agps_step = STEP_1_GETHOST;
}
}
break;
case STEP_2_CONNECT: //第二步,创建套接字接口
if(sockfd < 0){
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
DFR("ERROR, opening socket. %s", strerror(errno));
}
}else{
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0){
DFR("ERROR, cannot connect to server. %s", strerror(errno));
} else {
agps_step = STEP_3_SENDNET;
DFR("connect to server.");
}
}
break;
case STEP_3_SENDNET: //从套接字接口获取AGPS定位信息
if(agps_step == STEP_3_SENDNET){
char *pStr;
int writeNum = 0;
char message[128];
char lat_buf[92]={0};
char lon_buf[92]={0};
//正常时高德地图发来的数据LOCATION_LAT有时有小数点后9位的情况,需要将小数点后强制截取成6位,否则会引起异常
property_get(LOCATION_LAT, lat_buf, LAT_DEF);
writeNum = strlen(lat_buf);
if(writeNum > 9){
memset(lat_buf+9, 0, writeNum-9);
DFR("lat_buf=%s, writeNum=%d", lat_buf, writeNum);
}
pStr = strchr(lat_buf, '.'); //有时AGPS信息并不是小数点后4位,强制截取小数点后4位
if(pStr == NULL){
memset(lat_buf, 0, writeNum);
memcpy(lat_buf, LAT_DEF, sizeof(LAT_DEF));
}
//正常时高德地图发来的数据LOCATION_LON有时有小数点后9位的情况,需要将小数点后强制截取成6位,否则会引起异常
property_get(LOCATION_LON, lon_buf, LON_DEF);
writeNum = strlen(lon_buf);
if(writeNum > 10){
memset(lon_buf+10, 0, writeNum-10);
DFR("lon_buf=%s, writeNum=%d", lon_buf, writeNum);
}
pStr = strchr(lon_buf, '.'); //有时AGPS信息并不是小数点后4位,强制截取小数点后4位
if(pStr == NULL){
memset(lon_buf, 0, writeNum);
memcpy(lon_buf, LON_DEF, sizeof(LON_DEF));
}
//经纬度信息组合成一个字符串
sprintf(message, "user=%s;pwd=%s;lat=%s;lon=%s;", USER_NAME, PASS_WORD, lat_buf, lon_buf);
DFR("Build agps Message: %s", message);
//写入套接字接口
writeNum = write(sockfd, message, strlen(message));
if(writeNum > 0){
agps_step = STEP_4_CANREAD;
return;
}
DFR("ERROR, writing to socket.");
}
break;
case STEP_4_CANREAD: //再次从套接字接口获取定位信息
if(agps_step == STEP_4_CANREAD){
char read_buffer[AGPS_READ_MAX]={0};
int agps_buffer_length = 0;
int readNum, counter;
char agps_buffer[AGPS_BUF_MAX]={0};
char *pCur = agps_buffer;
for(counter=0; counter<5; counter++){
memset(read_buffer, 0, AGPS_READ_MAX);
//从服务器的套接字接口获取
readNum = read(sockfd, read_buffer, AGPS_READ_MAX);
if(readNum < 0){
DFR("ERROR, reading from socket.");
break;
}else if(readNum == 0 ){
DFR("All agps data are received. Total bytes: %d", agps_buffer_length);
break;
} else {
if(agps_buffer_length + readNum > AGPS_BUF_MAX){
DFR("agps_buffer=%d is too small, agps_buffer_length=%d, readNum=%d", AGPS_BUF_MAX, agps_buffer_length, readNum);
readNum = AGPS_BUF_MAX - agps_buffer_length;
}
memcpy(pCur, read_buffer, readNum);
pCur += readNum;
agps_buffer_length += readNum;
DFR("Received %d bytes from agps server.", readNum);
}
}
if(agps_buffer_length != 0 && uartFd > 0){
//最后写入GPS模组中
readNum = write(uartFd, agps_buffer, agps_buffer_length);
DFR("Now, can send these data to gnss module through tty. %d", readNum);
disconnectAGPS();
}
}
break;
}
}
static void gps_agps_thread(void *arg) //启动一个线程
{
GpsState *state = (GpsState *)arg;
while(continue_thread){
if(started == 1){
if(agps_step == STEP_0_UNKNOWN)break;
connectAGPS(state->fd);
}
sleep(1);
}
DFR("agps thread exit, agps_step=%d", agps_step);
}
....................................
static void gps_state_thread(void *arg)
{
GpsState *state = (GpsState*)arg;
int gps_fd = state->fd;
int control_fd = state->control[1];
epoll_ctrlfd = epoll_create(1);
epoll_nmeafd = epoll_create(1);
epoll_register(epoll_ctrlfd, control_fd);
DFR("gps thread running, continue_thread=%d", continue_thread);
state->tmr_thread = state->callbacks.create_thread_cb("athr_gps_tmr", gps_timer_thread, state);
if(!state->tmr_thread){
DFR("could not create gps timer thread: %s", strerror(errno));
started = 0;
state->init = STATE_INIT;
goto Exit;
}
state->nmea_thread = state->callbacks.create_thread_cb("athr_nmea_thr", gps_nmea_thread, state);
if(!state->nmea_thread){
DFR("could not create gps nmea thread: %s", strerror(errno));
started = 0;
state->init = STATE_INIT;
goto Exit;
}
started = 0;
state->init = STATE_INIT;
//启动AGPS线程
agps_thread_id = state->callbacks.create_thread_cb("athr_agps_thr", gps_agps_thread, state);
if(!agps_thread_id){
DFR("create agps thread error");
}
//////////////////
for(;;){
来源:CSDN
作者:jinron10
链接:https://blog.csdn.net/jinron10/article/details/103477367