# 基站定位
***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.***
---
# 功能概述
基站定位(LBS,Location Based Service,基于位置的服务)是物联网蜂窝终端轻量化定位的核心能力,依托移动通信基站与Wi-Fi热点环境信息,无需GNSS卫星信号即可实现设备位置解算,广泛适配蜂窝模块嵌入式终端。该功能面向移动终端实时定位、基站/Wi-Fi混合融合定位、设备位置追踪、主动位置上报等物联网典型业务场景。
此功能提供标准化、高稳定、异步非阻塞的API接口,适配内存与算力受限的嵌入式物联网设备。整体通信交互遵循相关标准(如移远通信自定义协议),确保兼容性。
**典型应用场景**:
- 物联网设备的位置跟踪
- 工业、物流资产设备的实时位置管控
- 基于地理位置触发的物联网告警、联动业务
## 核心技术要素
1. **工作原理**:模块收集服务小区/邻区基站信息(Cell)和周边Wi-Fi热点信息,向LBS服务器发送定位请求。服务器计算并返回经纬度、定位精度等核心位置数据。为保障通信安全,数据交互采用XOR加密数据脱敏与Token动态鉴权双重安全机制。
2. **输入信息**:
- 基站信息:MCC、MNC、LAC、Cell ID等。
- Wi-Fi信息:MAC、RSSI等。
- 认证凭证:用户名、密码、Token和IMEI。
3. **输出信息**:
- 位置结果:经纬度、定位精度。
4. **常见结果**:
- 定位成功:返回标准化位置信息链表。
- 定位失败:常见原因包括Token失效、网络异常等。
5. **故障排查步骤**:
- 检查模块PDP上下文是否已成功激活、SIM卡注册状态是否正常。
- 验证LBS服务的Token有效性及设备IMEI授权状态。
- 尝试降级为单基站(Single Cell)模式测试基础连通性。
## 业务流程
1. **创建客户端实例**:创建LBS定位客户端ID。
2. **参数配置**:配置基站/Wi-Fi数据源、设备鉴权信息、云端服务器地址、超时时间等参数。
3. **发起异步请求**:主动向LBS服务器发起定位请求,注册结果回调函数。
4. **回调结果处理**:解析位置信息。
5. **资源自动释放**。
## 消息协议结构
LBS定位报文基于移远通信自定义应用层协议(封装在HTTP/TCP中),包括头部(Header)、认证区(Auth)、基站/Wi-Fi数据区(Cell + Wi-Fi)和响应区(Response)
```{image} images/image_VtnRb6CFSo8eKhx7QILcTcCknHg.webp
:width: 1779px
:height: 695px
:align: center
```
- **偏移量细节**:头部长度固定;认证/数据区长度动态可变;响应区包括错误码和位置链表,可精准反馈定位状态与结果数据。
```{note}
1. 默认加密方案采用XOR异或运算;
2. 所有上行请求必须携带有效的Token进行身份校验。
```
# 基站定位API
## 头文件
*qcm_lbs_app.h*
## 函数概览
| **函数** | **说明** |
| --- | --- |
| *qcm_lbs_client_new()* | 初始化LBS请求并获取客户端ID |
| *qcm_lbs_get_position()* | 基于基站或Wi-Fi信息查询设备的位置信息 |
## 函数详解
### qcm_lbs_client_new
- **功能描述**
初始化LBS请求并获取客户端ID。系统将在定位回调执行完毕后自动管理并释放该实例占用的资源。
- **函数原型**
```c
qcm_lbs_client_id qcm_lbs_client_new(void)
```
- **参数说明**
无
- **返回值说明**
客户端ID:函数执行成功
*-1*:函数执行失败
```{note}
调用此函数前,需确保设备已完成注网拨号并建立数据通道。
```
### qcm_lbs_get_position
- **功能描述**
基于基站或Wi-Fi信息查询设备的位置信息。
- **函数原型**
```c
qcm_lbs_result_code_e qcm_lbs_get_position(qcm_lbs_client_id lbs_cli_id,
char *host,
qcm_lbs_option_t *user_opts,
qcm_lbs_response_callback cb,
void *arg)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *lbs_cli_id* | 输入 | qcm_lbs_client_id | 客户端ID |
| *host* | 输入 | char * | 服务器地址 |
| *user_opts* | 输入 | *qcm_lbs_option_t \** | 定位请求中待配置的参数;详见 [*qcm_lbs_option_t*](#qcmlbsoption_t) |
| *cb* | 输入 | *qcm_lbs_response_callback* | 定位请求结果的回调函数,用于接收解析定位状态与数据;详见 [qcm_lbs_response_callback](#qcmlbsresponse_callback) |
| *arg* | 输入 | void * | 用户自定义参数,由 *qcm_lbs_response_callback()* 回调函数传回 |
- **返回值说明**
*QCM_LBS_SUCCESS*:函数执行成功
其他值(详见 [qcm_lbs_result_code_e](#qcmlbsresultcodee)):函数执行失败
```{note}
调用此函数前必须先调用 *qcm_lbs_client_new()* 获取客户端ID。
```
#### qcm_lbs_response_callback
- **功能描述**
通知LBS定位请求结果。
- **函数原型**
```c
typedef void (*qcm_lbs_response_callback)(
qcm_lbs_client_id client_id,
qcm_lbs_result_code_e result,
qosa_int32_t pos_num,
qcm_lbs_position_info_t *pos_info,
char *date,
void *arg)
```
- **参数说明**
| **参数名** | **输入/输出** | **类型** | **说明** |
| --- | --- | --- | --- |
| *client_id* | 输入 | qcm_lbs_client_id | 客户端ID |
| *result* | 输入 | *qcm_lbs_result_code_e* | 定位请求结果;详见 [*qcm_lbs_result_code_e*](#qcmlbsresultcodee) |
| *pos_num* | 输入 | qosa_int32_t | 成功定位后获取的地点信息数量 |
| *pos_info* | 输入 | *qcm_lbs_position_info_t \** | 通过定位服务获取的位置信息;详见 [*qcm_lbs_position_info_t*](#qcmlbspositioninfot) |
| *date* | 输入 | char * | 服务器返回的时间 |
| *arg* | 输入 | void * | 用户自定义参数 |
- **返回值说明**
无
## 结构体定义
### qcm_lbs_option_t
定位请求中待配置的参数结构体定义如下:
```c
typedef struct
{
qosa_uint8_t pdp_cid;
qosa_uint8_t sim_id;
qosa_int32_t req_timeout;
qcm_lbs_basic_info_t *basic_info;
qcm_lbs_auth_info_t *auth_info;
qosa_int32_t cell_num;
qcm_lbs_cell_info_t *cell_info;
qosa_int32_t wifi_num;
qcm_lbs_wifi_mac_info_t *wifi_info;
} qcm_lbs_option_t
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *pdp_cid* | qosa_uint8_t | PDP上下文ID |
| *sim_id* | qosa_uint8_t | SIM ID |
| *req_timeout* | qosa_int32_t | 定位请求的超时时间;推荐范围:10~120;单位:秒 |
| *basic_info* | *qcm_lbs_basic_info_t \** | 定位请求的基础配置参数;详见 [*qcm_lbs_basic_info_t*](#qcmlbsbasicinfot) |
| *auth_info* | *qcm_lbs_auth_info_t \** | 定位请求的鉴权信息;详见 [*qcm_lbs_auth_info_t*](#qcmlbsauthinfot) |
| *cell_num* | qosa_int32_t | 有效基站个数;取值需小于等于6 |
| *cell_info* | *qcm_lbs_cell_info_t \** | 定位请求所需的基站信息;详见 [*qcm_lbs_cell_info_t*](#qcmlbscellinfot) |
| *wifi_num* | qosa_int32_t | 有效Wi-Fi热点个数;取值需小于等于6 |
| *wifi_info* | *qcm_lbs_wifi_mac_info_t \** | 定位请求所需的Wi-Fi热点信息;详见 [*qcm_lbs_wifi_mac_info_t*](#qcmlbswifimacinfo_t) |
### qcm_lbs_basic_info_t
定位请求的基础配置参数结构体定义如下:
```c
typedef struct
{
qosa_uint8_t type;
qosa_uint8_t encrypt;
qosa_uint8_t key_index;
qosa_uint8_t pos_format;
qosa_uint8_t loc_method;
} qcm_lbs_basic_info_t
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *type* | qosa_uint8_t | 请求类型
*1*:定位查询
*2*:位置上报 |
| *encrypt* | qosa_uint8_t | 加密方案
*1*:XOR异或加密 |
| *key_index* | qosa_uint8_t | 异或加密方案中的扰码密钥编号,由本地随机生成。范围:0~7 |
| *pos_format* | qosa_uint8_t | 回应数据包类型
*1*:无需地址信息
*2*:需要地址信息 |
| *loc_method* | qosa_uint8_t | 定位类型
*1*:普通基站轮询
*4*:多基站轮询
*5*:基站 + Wi-Fi混合定位
*6*:Wi-Fi定位 |
### qcm_lbs_auth_info_t
定位请求的鉴权信息结构体定义如下:
```c
typedef struct
{
char user_name[QCM_LBS_MAX_AUTH_INFO_LENGTH];
char user_pwd[QCM_LBS_MAX_AUTH_INFO_LENGTH];
char token[QCM_LBS_MAX_TOKEN_LENGTH];
char imei[QCM_LBS_MAX_IMEI_LENGTH];
qosa_uint16_t rand;
} qcm_lbs_auth_info_t
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *user_name* | char | 用户名 |
| *user_pwd* | char | 密码 |
| *token* | char | 定位访问凭据 |
| *imei* | char | 设备IMEI |
| *rand* | qosa_uint16_t | 客户端生成的用于鉴权的随机数 |
### qcm_lbs_cell_info_t
定位请求所需的基站信息结构体定义如下:
```c
typedef struct
{
qosa_uint8_t radio;
qosa_uint16_t mcc;
qosa_uint16_t mnc;
qosa_int32_t lac_id;
qosa_int32_t cell_id;
qosa_int16_t signal;
qosa_uint16_t tac;
qosa_uint16_t bcch;
qosa_uint8_t bsic;
qosa_uint16_t uarfcndl;
qosa_uint16_t psc;
qosa_int16_t rsrq;
qosa_uint16_t pci;
qosa_uint16_t earfcn;
qosa_uint16_t reserve;
} qcm_lbs_cell_info_t
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *radio* | qosa_uint8_t | 无线接入技术类型 |
| *mcc* | qosa_uint16_t | 移动设备国家代码 |
| *mnc* | qosa_uint16_t | 移动设备网络代码 |
| *lac_id* | qosa_int32_t | 位置区码 |
| *cell_id* | qosa_int32_t | 小区ID |
| *signal* | qosa_int16_t | 信号强度;单位:dBm |
| *tac* | qosa_uint16_t | 跟踪区码 |
| *bcch* | qosa_uint16_t | 广播控制信道 |
| *bsic* | qosa_uint8_t | 基站识别码(GSM) |
| *uarfcndl* | qosa_uint16_t | 下行中心频点(WCDMA) |
| *psc* | qosa_uint16_t | 主扰码(WCDMA) |
| *rsrq* | qosa_int16_t | 参考信号接收质量(LTE Standard) |
| *pci* | qosa_uint16_t | 物理小区识别码(LTE Standard) |
| *earfcn* | qosa_uint16_t | 载波频点号(LTE Standard) |
| *reserve* | qosa_uint16_t | 预留 |
### qcm_lbs_wifi_mac_info_t
定位请求所需的Wi-Fi热点信息结构体定义如下:
```c
typedef struct
{
char wifi_mac[QCM_LBS_MAX_MAC_LENGTH];
qosa_int32_t wifi_rssi;
char wifi_ssid[QCM_LBS_MAX_SSID_LENGTH];
} qcm_lbs_wifi_mac_info_t
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *wifi_mac* | char | Wi-Fi MAC地址 |
| *wifi_rssi* | qosa_int32_t | Wi-Fi信号强度;单位:dBm |
| *wifi_ssid* | char | Wi-Fi服务集标识符 |
### qcm_lbs_position_info_t
通过定位服务获取的位置信息结构体定义如下:
```c
typedef struct
{
float longitude;
float latitude;
qosa_uint16_t accuracy;
qosa_uint8_t flag;
} qcm_lbs_position_info_t
```
| **参数** | **类型** | **说明** |
| --- | --- | --- |
| *longitude* | float | 经度 |
| *latitude* | float | 纬度 |
| *accuracy* | qosa_uint16_t | 定位精度 |
| *flag* | qosa_uint8_t | 定位数据标志
*0*:正常
*1*:无效 |
## 枚举定义
### qcm_lbs_result_code_e
定位请求结果枚举定义如下:
```c
typedef enum
{
QCM_LBS_SUCCESS = 0,
QCM_LBS_LOC_FAIL = (QOSA_COMPONENT_LBS << 16) | 10000,
QCM_LBS_IMEI_ILLEGAL = (QOSA_COMPONENT_LBS << 16) | 10001,
QCM_LBS_TOKEN_NOT_EXIST = (QOSA_COMPONENT_LBS << 16) | 10002,
QCM_LBS_TOKEN_LOC_EXCEED_MAX = (QOSA_COMPONENT_LBS << 16) | 10003,
QCM_LBS_IMEI_LOC_EXCEED_DAY_MAX = (QOSA_COMPONENT_LBS << 16) | 10004,
QCM_LBS_IMEI_LOC_VISIT_EXCEED_MAX = (QOSA_COMPONENT_LBS << 16) | 10005,
QCM_LBS_TOKEN_EXPIRED = (QOSA_COMPONENT_LBS << 16) | 10006,
QCM_LBS_IMEI_NO_AUTHORITY = (QOSA_COMPONENT_LBS << 16) | 10007,
QCM_LBS_TOKEN_LOC_VISIT_EXCEED_MAX = (QOSA_COMPONENT_LBS << 16) | 10008,
QCM_LBS_TOKEN_LOC_EXCEED_PERIOD_MAX = (QOSA_COMPONENT_LBS << 16) | 10009,
QCM_LBS_DNS_FAIL = (QOSA_COMPONENT_LBS << 16) | 10101,
QCM_LBS_MD5_FAIL = (QOSA_COMPONENT_LBS << 16) | 10102,
QCM_LBS_MEMORY_FAIL = (QOSA_COMPONENT_LBS << 16) | 10103,
QCM_LBS_NET_FAIL = (QOSA_COMPONENT_LBS << 16) | 10104,
QCM_LBS_PARAM_FORMAT_FAIL = (QOSA_COMPONENT_LBS << 16) | 10105,
QCM_LBS_TIMEOUT_FAIL = (QOSA_COMPONENT_LBS << 16) | 10106,
} qcm_lbs_result_code_e
```
| **成员** | **说明** |
| --- | --- |
| *QCM_LBS_SUCCESS* | 定位成功 |
| *QCM_LBS_LOC_FAIL* | 定位失败 |
| *QCM_LBS_IMEI_ILLEGAL* | 非法IMEI号 |
| *QCM_LBS_TOKEN_NOT_EXIST* | Token不存在 |
| *QCM_LBS_TOKEN_LOC_EXCEED_MAX* | Token的定位次数超过最大值 |
| *QCM_LBS_IMEI_LOC_EXCEED_DAY_MAX* | 设备每日定位次数超过最大值 |
| *QCM_LBS_IMEI_LOC_VISIT_EXCEED_MAX* | Token连接设备数超过最大值 |
| *QCM_LBS_TOKEN_EXPIRED* | Token已过期 |
| *QCM_LBS_IMEI_NO_AUTHORITY* | 此IMEI(设备)无法访问服务器 |
| *QCM_LBS_TOKEN_LOC_VISIT_EXCEED_MAX* | Token每日定位次数超过最大值 |
| *QCM_LBS_TOKEN_LOC_EXCEED_PERIOD_MAX* | Token周期内定位次数超过最大值 |
| *QCM_LBS_DNS_FAIL* | DNS失败 |
| *QCM_LBS_MD5_FAIL* | MD5校验失败 |
| *QCM_LBS_MEMORY_FAIL* | 内存分配失败 |
| *QCM_LBS_NET_FAIL* | 网络异常 |
| *QCM_LBS_PARAM_FORMAT_FAIL* | 参数格式错误 |
| *QCM_LBS_TIMEOUT_FAIL* | 基站定位服务超时 |
# 应用逻辑流程图
```{image} images/board_TTNrwG0ehhBsmZb1FJuciUJhnCb.jpg
:width: 820px
:height: 1768px
:align: center
```
# 示例代码
完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/network/location/lbs/lbs_demo.c
# 常见问题及排查方案
当定位请求返回异常错误码或未按预期触发回调时,请参考下表进行故障诊断与处理:
| **错误码/问题** | **可能原因** | **建议解决方案** |
| --- | --- | --- |
| *QCM_LBS_TOKEN_NOT_EXIST*(Token不存在) | Token无效或未配置 |