好的,我们继续启程,向3GPP TS 29.515规范中技术密度最高、内容最丰富的第六章腹地进发。在上一篇文章中,我们已经为Ngmlc_Location API搭建了坚实的骨架,理解了它的URI结构、通信协议和核心交互机制。现在,是时候为这个骨架注入灵魂了——我们将逐一解剖API交互中的“血液”,即承载所有信息的数据模型(Data Models)。

由于6.1.5节内容浩瀚,我们将分篇章进行精讲。本文作为第六章的第二部分,将聚焦于API的“请求篇”,深入剖析当应用向GMLC发起定位或取消定位时,其请求体(Request Body)中到底包含了哪些信息,以及每个字段的精确含义和用法。

深度解析 3GPP TS 29.515:第六章 (Part 2) - 核心数据模型之“请求篇” (InputData & CancelLocData)

本文技术原理深度参考了3GPP TS 29.515 V18.8.0 (2025-03) Release 18规范中,关于**第六章“API定义”**的核心内容,重点剖析6.1.5.2节中用于发起ProvideLocationCancelLocation操作的核心数据类型:InputDataCancelLocData。本文旨在让开发者彻底掌握如何构建一个功能强大、参数精确的5G定位服务API请求。

故事新阶段:从“知道做什么”到“知道怎么说”

应急调度员小李的技术团队士气高昂。通过对前序章节的学习,他们已经知道了GMLC的API地址、通信协议(HTTP/2)、数据格式(JSON)以及安全机制(OAuth2.0)。他们甚至有了一本“API速查手册”(Table 6.1.3.1-1),清晰地指明了“追踪救护车”需要调用/provide-location端点。

现在,首席架构师向团队提出了一个终极问题:“我们要发送给/provide-location的那个HTTP POST请求,它的JSON消息体(Body)应该长什么样?要追踪‘生命卫士-01’,需要填supi还是gpsi?如何指定精度必须达到5米?又如何告诉GMLC把结果每10秒推送给我们一次?

这些问题的答案,就隐藏在6.1.5节“Data Model”之中。这一节是整个规范中代码相关性最强、细节最繁复的部分,它定义了API交互中所有数据载体(Payload)的结构。今天,我们就将化身“JSON工匠”,精雕细琢ProvideLocationCancelLocation这两个核心操作的请求体。

1. 6.1.5 Data Model (数据模型):API的“通用语”

在进入具体的数据类型之前,规范首先通过两个总览表,为我们描绘了Ngmlc_Location API数据世界的版图。

1.1 本规范定义的数据类型 (Ngmlc_Location specific Data Types)

Table 6.1.5.1-1列出了所有由TS 29.515规范原生定义的数据类型。这个表格就像是本规范数据模型的“目录”。

  • InputData:用于ProvideLocation操作的输入参数,是我们今天的重点。
  • LocationData:包含定位结果的核心数据,我们将在下一篇文章“响应篇”中详述。
  • CancelLocData:用于CancelLocation操作的输入参数,也是今天的重点。
  • EventNotifyData:用于EventNotify通知的数据。
  • …等等。

1.2 重用的数据类型 (Ngmlc_Location re-used Data Types)

Table 6.1.5.1-2则列出了从其他3GPP规范(如TS 29.571通用数据类型、TS 29.572 LMF接口数据类型)中**“引用”或“重用”**的数据类型。这体现了3GPP规范设计的模块化和标准化思想,避免重复造轮子。

  • Gpsi, Supi, Uri (from TS 29.571)
  • LocationQoS, CivicAddress, GeographicArea (from TS 29.572)

这意味着,当我们稍后在InputData中看到locationQoS这个字段时,要理解其详细结构,就需要去查阅TS 29.572规范。

2. 6.1.5.2.2 Type: InputData (输入数据) - 构建ProvideLocation的请求

InputDataProvideLocation操作的请求体,是整个定位服务的“指令书”。它的设计目标是让消费者能够以最大的灵活性和精确性,向GMLC下达各种复杂的定位任务。

原文引用 (Table 6.1.5.2.2-1: Definition of type InputData):

(规范此处为一个巨大的表格,定义了InputData的所有属性)

我们将1:1重绘这个核心表格,并将其参数按逻辑功能进行分组,结合小李的应急场景进行“逐行注释”式深度解读。

表 6.1.5.2.2-1: InputData类型定义 (Definition of type InputData) (注:为便于阅读,下表对原表进行了重新分组和排序,但保留了所有核心字段)

属性名 (Attribute name)数据类型 (Data type)PCard.描述与深度解读
--- Group 1: 目标是谁? (Target Identification) ---
gpsiGpsiO0..1通用公共签约标识符。通常是用户的手机号码(MSISDN)。这是最常用的、对外部应用友好的标识符。场景:小李的系统使用“生命卫士-01”的gpsi来发起定位。
supiSupiO0..1签约永久标识符。通常是IMSI。这是网络内部使用的、唯一的、更安全的标识符。注意:对于单个UE定位,gpsisupiappLayerId三者至少要提供一个。
appLayerIdApplicationLayerIdO0..1应用层ID。可以是任何应用自定义的标识,如车牌号、设备序列号。这需要GMLC或上游的NEF/AF有能力将其映射为网络可识别的supigpsi
extGroupIdExternalGroupIdO0..1外部群组ID。用于标识一个预定义的UE群组,如“第一消防小队”。这个ID对外部应用有意义。
intGroupIdGroupIdO0..1内部群组ID。网络核心网内部使用的群组ID。注意:群组ID和单个UE的ID是互斥的。请求中要么是定位群组,要么是定位单个UE。
--- Group 2: 定位质量要求? (Quality of Service) ---
locationQosLocationQoSO0..1定位服务质量。这是一个结构体,包含了对定位结果的详细要求。核心子字段包括:hAccuracy (水平精度,米)、vAccuracy (垂直精度,米)、responseTime (响应时间要求,如LOW_DELAYHIGH_ACCURACY)。场景:小李需要区分救护车在立交桥上还是桥下,他会设置一个较高的vAccuracy,如3米。
--- Group 3: 如何与何时定位? (Deferred Location Control) ---
ldrTypeLdrTypeC0..1延迟定位请求类型。这是启动非立即定位的关键。C表示条件必选,即如果想发起延迟定位,此字段必须存在。枚举值包括:PERIODIC (周期性), ENTERING_INTO_AREA (进入区域), LEAVING_FROM_AREA (离开区域), MOTION (运动检测)等。
periodicEventInfoPeriodicEventInfoC0..1周期性事件信息。当ldrTypePERIODIC必须提供。包含reportingInterval (上报间隔,秒) 和 reportingAmount (总上报次数)。场景:小李设置reportingInterval: 10, reportingAmount: 360,实现未来一小时内每10秒上报一次。
areaEventInfoAreaEventInfoExtC0..1区域事件信息。当ldrType为区域相关事件时必须提供。包含areaDefinition (定义区域的形状,如圆形、多边形) 和 occurrenceInfo (是一次性还是多次触发)。
--- Group 4: 结果送到哪? (Notification Control) ---
eventNotificationUriUriO0..1事件通知URI。延迟定位的回调地址。当订阅的事件触发时,GMLC会向这个地址POST一个EventNotify通知。对于所有延迟定位请求,此字段事实상必须提供。
--- Group 5: 谁在请求? (Client Identity) ---
externalClientTypeExternalClientTypeM1外部客户端类型M表示强制必选。请求者必须声明自己的身份。枚举值如EMERGENCY_SERVICES, COMMERCIAL_LCS_CLIENT等。这直接影响GMLC的隐私和优先级策略。场景:小李的系统必须声明自己是EMERGENCY_SERVICES,才能获得最高定位优先级和隐私超越权。
externalClientIdentificationExternalClientIdentificationO0..1外部客户端标识。更具体的客户端身份信息。
afIdstringO0..1应用功能(AF)ID。标识了哪个后端应用发起了请求。
--- Group 6: 高级/特定场景参数 ---
reliableLocReqbooleanC0..1可靠定位请求。用于UAS(无人机系统)等高安全场景,值为true时表示需要一次经过完整性保护的定位。
requestedRangingSlResultarray(RangingSlResult)O1..N请求的Sidelink定位结果类型。用于V2X/Sidelink场景,指定需要获取的是绝对位置、相对位置、距离还是方向。
relatedUesarray(RelatedUe)O1..N相关的UEs。在Sidelink相对定位中,用于列出参与定位的其他UEs的信息。
mbsrPosIndbooleanC0..1MBSR定位指示true表示本次定位是为了确定移动基站中继(MBSR)的位置,以便定位其下的终端。

原文引用 (Note 3 in Table 6.1.5.2.2-1):

If retrieving the location for a target UE, the UE identification (attributes gpsi and/or supi or appLayerId) shall be included, if retrieving the UE locations for a target group, the group identification (attributes extGroupId and/or intGroupId), UE identification and group identification shall be included exclusively.

这个附注(NOTE)非常关键,它强调了目标标识的互斥性:一次ProvideLocation请求,要么是针对一个或多个具体UE的,要么是针对一个群组的,不能混用。

场景代入与代码构建: 小李的技术团队现在可以精确地构建出追踪“生命卫士-01”的JSON请求体了:

// POST https://.../ngmlc-loc/v1/provide-location
{
  "gpsi": "msisdn-8613800100119", // 目标: "生命卫士-01"的手机号
  "externalClientType": "EMERGENCY_SERVICES", // 身份: 紧急服务
  "locationQos": {
    "hAccuracy": 5,           // 水平精度要求5米
    "vAccuracy": 3,           // 垂直精度要求3米,用于立交桥场景
    "responseTime": "LOW_DELAY" // 响应时间要求低延迟
  },
  "ldrType": "PERIODIC",      // 类型: 周期性定位
  "periodicEventInfo": {
    "reportingInterval": 10,  // 间隔: 10秒
    "reportingAmount": 360      // 次数: 360次 (1小时)
  },
  "eventNotificationUri": "https://emergency.city.gov/api/updates" // 结果送达地址
}
```这份`InputData`就像一份滴水不漏的“作战指令”,清晰、明确、毫无歧义。
 
## 3. 6.1.5.2.4 Type: CancelLocData (取消定位数据) - 构建`CancelLocation`的请求
 
当任务结束,需要终止持续定位时,就需要调用`CancelLocation`操作。其请求体`CancelLocData`的设计目标只有一个:**精确地告诉GMLC要取消的是哪一个定位任务**。
 
> **原文引用 (Table 6.1.5.2.4-1: Definition of type CancelLocData):**
>
> (规范此处为CancelLocData的属性定义表格)
 
我们同样1:1重绘并解读这个表格。
 
**表 6.1.5.2.4-1: `CancelLocData`类型定义 (Definition of type CancelLocData)**
 
| 属性名 (Attribute name) | 数据类型 (Data type) | P | Card. | 描述与深度解读 |
| :--- | :--- | :--- | :--- | :--- |
| `supi` | Supi | O | 0..1 | **终端标识 (SUPI)**。可选,用于校验。 |
| `gpsi` | Gpsi | O | 0..1 | **终端标识 (GPSI)**。可选,用于校验。 |
| `extGroupId` | ExternalGroupId | O | 0..1 | **群组标识 (外部)**。可选,用于校验。 |
| `intGroupId` | GroupId | O | 0..1 | **群组标识 (内部)**。可选,用于校验。 |
| **`hgmlcCallBackUri`** | Uri | M | 1 | **H-GMLC回调地址**。在漫游场景下,由H-GMLC发起的取消请求,需要提供此参数,用于V-GMLC向其返回取消结果的确认。对于非漫游场景或由V-GMLC发起的取消,此参数可能不是强制的,但规范定义为M,体现了其在漫游流程中的重要性。 |
| **`ldrReference`** | LdrReference | M | 1 | **延迟定位请求参考号**。**`M`表示强制必选,这是`CancelLocData`中最核心、最重要的字段**。它是在`ProvideLocation`发起订阅时,由GMLC返回的唯一任务ID。GMLC正是通过这个ID来精确识别并终止一个特定的延迟定位会话。 |
| `lmfIdentification` | LmfIdentification | O | 0..1 | **LMF标识**。可选,提供服务该UE的LMF的ID,可以帮助GMLC更快地将取消指令路由到正确的LMF。 |
| `amfId` | AmfId | O | 0..1 | **AMF标识**。可选,提供服务该UE的AMF的ID,同样有助于加速取消流程。 |
 
> **原文引用 (Note in Table 6.1.5.2.4-1):**
>
> If cancelling the location for a target UE, the UE identification ... shall be included, if cancelling the UE locations for a target group, the group identification ... shall be included, ... UE identification and group identification shall be included exclusively.
 
这个附注再次强调了目标标识的互斥性,与`InputData`中的逻辑一致。
 
**场景代入与代码构建**:
“生命卫士-01”的救援任务圆满结束。小李的系统需要终止对它的追踪。在发起追踪时,GMLC的`200 OK`响应中返回了一个`ldrReference`,例如`"LDR-REF-ABC-789"`。现在,系统将使用这个ID来取消任务。
 
```json
// POST https://.../ngmlc-loc/v1/cancel-location
{
  "gpsi": "msisdn-8613800100119", // 可选,用于校验
  "ldrReference": "LDR-REF-ABC-789" // 核心,强制必选的任务ID
}

GMLC收到这个请求后,会在其会话列表中查找LDR-REF-ABC-789,找到后便终止该任务,并释放相关资源。


FAQ 环节

Q1:在InputData中,gpsisupiappLayerId都是可选的(O),但注释说至少要提供一个,这是为什么?

A1:这里的“可选”(Optional)是相对于数据模型结构而言的。在InputData这个JSON对象的定义中,这三个字段本身都不是强制必须存在的。但是,从业务逻辑上讲,一个定位请求必须要有定位目标,否则就是无效请求。因此,规范通过文字附注的方式,补充了业务层面的约束:“你必须至少告诉我一个你要定位的目标是谁”。这种做法在3GPP规范中很常见,即通过数据模型的灵活性和文字描述的业务约束相结合,来完整定义一个API的行为。

Q2:ldrReference(延迟定位请求参考号)是在哪个环节产生的,又是在哪里返回给我的应用?

A2:ldrReference是由GMLC成功受理一个延迟定位请求(LDR)时生成的。具体流程是:1) 您的应用构造一个包含ldrTypeInputData对象,调用ProvideLocation。2) GMLC收到请求,验证通过后,会为这个即将开始的长期定位任务创建一个唯一的ID,即ldrReference。3) GMLC会立即返回一个200 OK响应给您的应用,这个响应的消息体LocationDataLocationDataExt)中就会包含这个ldrReference字段。您的应用必须立刻解析并存储这个ID,因为它是后续管理(取消)和关联(接收通知)这个任务的唯一凭证。

Q3:InputData中的ldrReferenceCancelLocData中的ldrReference是同一个东西吗?为什么InputData中也有这个字段?

A3:它们指向的是同一种东西(任务ID),但使用场景不同。CancelLocData中的ldrReference输入参数,用于告诉GMLC要取消哪个任务。而InputData中也定义了ldrReference字段,但它的作用不同。根据TS 23.273的流程,在某些复杂的延迟定位场景中(如由NEF发起的群组定位),NEF可能会自己先生成一个初始的ldrReference(作为事务ID)传递给GMLC,GMLC在处理后可能会使用这个ID或生成一个新的ID。但在绝大多数情况下,InputData中的ldrReference是由消费者(如NEF)在特定流程中提供的,而任务的最终权威ID,是以GMLC在ProvideLocation响应中返回的为准。对于大多数应用开发者,可以认为ldrReference是GMLC的输出,CancelLocData的输入。

Q4:locationQos参数看起来非常强大,如果我请求一个网络无法达到的QoS(比如在室内要求1米GPS精度),会发生什么?

A4:网络会尽力而为,并如实报告结果。GMLC在收到请求后,会尝试执行定位。如果最终的定位结果无法满足您请求的locationQos,它不会直接返回失败。它仍然会返回一个200 OK的成功响应,并在响应体LocationData中包含实际达到的定位结果(例如,实际精度是20米)。但是,LocationData中会有一个名为accuracyFulfilmentIndicator的字段,其值会被设为"NOT_FULFILLED"。这等于是在告诉您:“我努力了,但没达到你要求那么高的精度,这是我能给出的最好结果,你自己判断是否可用。” 这种设计使得应用可以根据实际情况进行降级处理,而不是因为QoS不达标就完全获取不到任何位置信息。

Q5:CancelLocData中的hgmlcCallBackUri字段为什么是强制的(M)?如果我不是漫游场景,也需要填吗?

A5:这是一个很好的问题,反映了规范定义的严谨性。将hgmlcCallBackUri定义为强制(Mandatory),主要是为了确保在最复杂的漫游场景下协议的完备性。在H-GMLC发起取消,通过V-GMLC执行的流程中,V-GMLC必须知道如何将取消操作的结果回调给H-GMLC。然而,在实际的非漫游场景下,或者由消费者直接向服务GMLC发起取消时,这个字段的业务逻辑意义不大。实际的API实现中,GMLC可能会根据请求的来源和上下文,对这个字段的强制性进行灵活处理。对于应用开发者来说,最佳实践是遵循规范,如果字段被定义为M,就应该提供。但在与运营商对接时,可以就具体场景下该字段如何填写进行沟通确认。