> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# QRTR API

> 内核端口生命周期、服务发现、消息传输和 socket 访问。

内核 API 将 QRTR 端点建模为端口。客户端创建端口，在必要时解析服务，发送和接收消息，然后关闭端口。服务器还会额外注册和注销一个服务名称。

## 端口生命周期

端口经历以下阶段：

1. **创建** —— 创建端口，并提供一个用于事件（有数据可读、写入完成、端口状态变化）通知的回调。
2. **注册（可选）** —— 如果该端口用于提供服务，注册服务名称以便客户端能够找到它。
3. **就绪** —— 发送和接收消息，或查找远端服务。
4. **注销（可选）** —— 如果该端口曾注册为服务，在服务停止时注销它。
5. **关闭** —— 关闭端口并清理资源。

## 内核空间接口

内核提供以下用于创建和管理端口的函数：

* **创建端口** —— 提供一个在事件发生时（有数据可读、写入完成、端口状态变化）被调用的回调函数。回调会收到一个私有上下文指针，以便将端口与其所属的驱动状态关联。
* **发送消息** —— 指定目的地（服务名称或端点地址）和要发送的数据。
* **接收消息** —— 等待消息到达，可选带超时。接收函数返回载荷和源地址。
* **注册服务** —— 将服务名称与该端口关联注册，供客户端查找。
* **注销服务** —— 在服务停止时注销服务名称。
* **关闭端口** —— 关闭端口并释放资源。

## 服务注册和查找

服务器将服务名称与其本地端口关联注册。当客户端拥有服务名称但没有当前端点地址时，会调用查找函数。返回的地址可能在服务重启或迁移时发生变化，因此客户端必须处理查找失败和地址过期错误。

## 用户空间 socket

用户空间应用通过面向消息的 socket 接口访问路由器。socket 生命周期遵循与内核 API 相同的模型：

1. 创建 socket
2. 绑定到本地地址或发现远端服务
3. 发送和接收消息
4. 关闭 socket

数据报边界被保留为消息边界，因此应用应按其期望接收的消息大小设置接收缓冲区大小。

## API 参考

### 端口生命周期函数

以下函数管理 QRTR 端口的生命周期：

* `qrtr_endpoint_create(const char *xprt_name, uint32_t port_id, qrtr_rx_cb rx_cb, void *priv)` —— 创建端口并注册一个回调，用于事件（有数据可读、写入完成、端口状态变化）的通知。

* `qrtr_sendto(uint32_t node_id, uint32_t port_id, const void *data, size_t len)` —— 向由节点 ID 和端口 ID 指定的目的地发送消息。

* `qrtr_send_to_service(uint32_t service_id, uint32_t instance_id, const void *data, size_t len)` —— 向由服务名称（服务 ID 和实例 ID）指定的目的地发送消息。

* `qrtr_recvfrom(uint32_t *node_id, uint32_t *port_id, void *data, size_t len, int timeout_ms)` —— 等待消息到达，可选带超时。返回载荷和源地址。

* `qrtr_publish(uint32_t service_id, uint32_t instance_id, uint32_t version)` —— 将服务名称与该端口关联注册，供客户端发现。

* `qrtr_unpublish(uint32_t service_id, uint32_t instance_id)` —— 在服务停止时注销服务名称。

* `qrtr_endpoint_release(uint32_t port_id)` —— 关闭端口并释放所有关联资源。

### 服务发现函数

* `qrtr_lookup_service(uint32_t service_id, uint32_t instance_id, uint32_t *node_id, uint32_t *port_id)` —— 通过名称向路由器查询服务。返回该服务的端点地址（节点 ID 和端口 ID）。

* `qrtr_get_service_list(uint32_t service_id, struct qrtr_service_info *services, size_t num_services, size_t *num_returned)` —— 获取与某个服务 ID 匹配的所有可用服务。

### Socket 接口函数

用户空间应用使用标准的 socket 操作：

* `socket(AF_QIPCRTR, SOCK_DGRAM, 0)` —— 创建一个用于 QRTR 通信的面向消息的 socket。

* `bind(sockfd, (struct sockaddr *)&addr, sizeof(addr))` —— 将 socket 绑定到本地地址，或按名称发现远端服务。

* `sendto(sockfd, data, len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr))` —— 向目的地发送消息。

* `recvfrom(sockfd, data, len, 0, (struct sockaddr *)&src_addr, &addr_len)` —— 从 socket 接收消息。

* `close(sockfd)` —— 关闭 socket 并释放资源。
