Dialog内answer的创建和发送,在接收到dialog内部的request时,需要发送response
eXosip_call_build_answer的处理流程:
a) 根据transaction id查询得到 call、dialog、transaction的结构。因为是接收到一个请求,所以在处理请求的时候已经创建了新的transaction,所以查询在正常情况下不会失败。
b) 如果是INVITE的请求,则调用_eXosip_answer_invite_123456xx进行response的message的构建,根据传入的最后一个参数0标识只构建message不发送该message。
c) 如果不是INVITE,则直接调用eXosip_build_response_default生成一个通用的应答message,如果回复的应答状态为(100, 399],则最终本端和对端会建立dialog,则调用函数complete_answer_that_establish_a_dialog从request中获取部分信息
eXosip_call_send_answer的流程:
a) 参数的合法性检查,如果回应的status不在[100,699]之间,或者transaction id <0,则返回错误提示。
b) 根据transaction id查询得到call、dialog、transaction的结构,如果没有找到,则返回错误。
c) 检查该transaction的合法性,如果其状态已经结束,则返回错误。
d) 如果answer还没有创建,并且是INVITE的应答,且应答status为2xx应答,则返回错误。
e) 如果要发送的answer还没有创建,且是INVITE的应答,则调用_eXosip_answer_invite_123456xx创建并发送应答。如果不是INVITE的应答,则返回错误。
f) 如果是INVITE的应答,且应答的status为2xx,并且dialog已经创建,则保存该2xx的应答到dialog中,并且置dialog的状态为confirmed,在未收到ACK的情况下,该2xx应答会被重新发送。
g) 所有合法性检查通过,则生成一个transaction上的event事件,并且添加到transaction的event链表上。
生动理解
技术概念
生活类比(快递场景)
一句话解释
Dialog
快递订单
一次完整收发快递的业务流程
Transaction
运输单
单个包裹的运输环节(发/送/签收)
Request(如INVITE)
寄件请求
发起寄快递的指令
Response(如2xx)
签收反馈
告诉对方“快递收到/处理结果”
eXosip_call_build_answer → “打包快递(准备应答)” 你要给朋友寄快递(处理 Request),需要先打包好包裹(构建 Response),流程像这样: 以下是符合要求的Markdown表格:
技术步骤
生活类比(寄快递)
查询 call/dialog/transaction
查订单:确认有快递订单(Dialog)、运输单(Transaction)没搞错
处理 INVITE 请求
寄"重要文件"(INVITE是关键请求):用特殊箱子打包(_eXosip_answer_invite_xxx),先不放快递站
处理非 INVITE 请求
寄"普通小物件":用通用箱子打包(eXosip_build_response_default);如果是"要建长期合作"的单(状态(100,399]),还得额外填合作信息
eXosip_call_send_answer → “发快递 + 跟踪流程” 打包好后,要把快递发出去,还要跟踪物流 / 处理异常,对应流程: 以下是按照要求生成的Markdown表格,严格遵循格式规范:
技术步骤
生活类比(寄快递)
参数检查
检查填写的“快递单号(transaction id)”“货物状态(status)”是否合法
查询结构
确认要发的快递订单确实存在(call/dialog/transaction未丢失)
检查事务状态
检查运输单是否已被签收(事务未结束),否则不能重发
拦截非法2xx应答
重要文件(INVITE)若标记“已签收(2xx)”但未打包,直接报错
发送应答
重要文件未打包需先打包再发;普通件未打包则报错
维护Dialog状态
重要文件显示“已签收(2xx)”时标记订单为“已确认”;未收到签收反馈需重发
生成事件
同步物流信息至快递系统,通知状态变更以便查询更新
一句话:先按请求类型打包好应答(build_answer); 再校验、发送,还会盯着物流(会话状态),没确认收到就重发(send_answer)
code
# include <stdio.h>
# include <stdlib.h>
# include <eXosip2/eXosip.h>
void handle_invite ( eXosip_t * excontext, eXosip_event_t * je) {
int ret;
osip_message_t * answer = NULL ;
printf ( "收到INVITE请求 from: %s\n" ,
je-> reque