设备平台invite交互过程
平台 ──INVITE(SDP)──► 设备 设备 ──200 OK(SDP)──► 平台 ← build_invite_ok_sdp,RTP/AVP 96 PS 平台 ──ACK──────────► 设备 设备 ──RTP/PS───────► 平台 ← sendonly,本地端口约 local_port+100 或 61000注册回调机制调用过程:
service::startGb28181Server(cfg) └─ gb28181::start(cfg) ├─ gb28181_sip_create(&c, on_event, on_rtp, nullptr) // 注册回调 │ └─ s->uas.oninvite = on_invite_uas │ └─ s->uas.onack = on_ack_uas ├─ gb28181_sip_start(g_ctx) │ └─ pthread_create(sip_recv_proc) // SIP 收包线程 └─ gb28181_sip_register(g_ctx)收包和分发函数调用
sip_recv_proc(s) [gb28181_sip.cpp] socket_recvfrom(s->udp, buffer, ...) http_parser_input(req_parser, ...) sip_message_load(msg, parser) sip_agent_input(s->agent, msg, s) // libsip 解析 SIP │ └──► on_invite_uas(param, req, t, dialog, id, sdp_body, bytes)整个代码函数调用流程:
【平台】 INVITE │ ▼ sip_recv_proc sip_agent_input on_invite_uas (agent消息分发) ├─ extract_invite_target_user / alloc_dialog ├─ parse_invite_sdp_* (写 dialog) └─ notify → on_event (gb28181.cpp) ├─ gb28181_sip_get_invite_reply_info ├─ build_invite_ok_sdp └─ gb28181_sip_reply_invite └─ sip_uas_reply(200, SDP) 【平台】 ACK │ ▼ sip_recv_proc sip_agent_input on_ack_uas └─ ensure_rtp_sender_started └─ (RTP 线程向 remote_rtp_ip:port 发 PS)解析sip_uas_reply函数
int sip_uas_reply(struct sip_uas_transaction_t* t, int code, const void* data, int bytes, void* param);| 参数 | 含义 |
|---|---|
| 对应的 UAS 事务(INVITE 时在 |
| SIP 状态码(200、404、486 等) |
| 响应 body(有 SDP 时就是 SDP 文本) |
| 传给发送回调的上下文(你们是 |
函数返回调用过程:
sip_uas_reply 返回 ret
→ gb28181_sip_reply_invite 返回
→ on_event 返回
→ on_invite_uas 返回 0
→ sip_uas_input 里 release 一次 transaction 引用
返回200 OK 的 message body 就是设备 SDP,例如:
设备 IP(c=IN IP4 ...)
本地 RTP 端口(m=video 61000 ...)
a=sendonly(设备向平台推流)
a=rtpmap:96 PS/90000
y= SSRC、f= 等 GB28181 字段
所以:这一步是把「设备怎么推流」告诉平台,不是发视频本身。
UAS 事务 不会立刻销毁,仍挂在 agent 上,用于:
重传 200 OK(WVP 没收到时会重发 INVITE,栈会再发 200)
等 平台回复ACK
WVP 收到 200 OK
→ 发 ACK
→ sip_recv_proc 再收包
→ sip_uas_find_acktransaction 匹配原 INVITE 事务
→ 状态 CONFIRMED
→ on_ack_uas()
rtp_send_proc 从 video FIFO 读 H264 → 封 PS → RTP 发到 WVP 的 remote_rtp_ip:remote_rtp_port。
执行
if (d && !d->rtp_running && d->remote_rtp_port > 0 && d->remote_rtp_ip[0]) { ensure_rtp_sender_started(d); // 绑 RTP 口 + pthread_create(rtp_send_proc) } notify(s, GB28181_EVENT_ACK_RECEIVED, 0, call_id);rtp_send_proc 从 video FIFO 读 H264 → 封 PS → RTP 发到 WVP 的 remote_rtp_ip:remote_rtp_port。
其中on_event 里收到 GB28181_EVENT_INVITE_RECEIVED 后:
gb28181_sip_get_invite_reply_info 解析对方 SDP(SSRC、是否带音频等)
build_invite_ok_sdp 生成本机 SDP(auth_id、本机 IP、RTP 端口)
gb28181_sip_reply_invite(..., 200, sdp) 回 200
底层 on_invite_uas 在 gb28181_sip.cpp 里接 INVITE、建 dialog、后续可走 RTP 发送逻辑