linphone快速挂断后的程序崩溃问题

第一种情况:

第一步:主叫拨通电话后快速挂断,此时尚未收到服务器对 INVITE 的临时响应消息,因此主叫在调用 eXosip_call_terminate 函数时并不发送 cancel 消息,则通话过程实际并没有结束。

第二步:主叫在挂断后状态进入 LinphoneCallEnd,并在 linphone_call_set_terminated 函数中将 lc->current_call 赋值为 NULL。当被叫收到服务器转发的 INVITE 请求后开始振铃,服务器将振铃消息继续转发到主叫,但是因为 linphone_call_set_state 函数一开始对 LinphoneCallEnd 状态的检查造成主叫状态不会改变。当被叫选择接听后,服务器又会将被叫接听的消息继续转发到主叫,同样,主叫状态仍然不会改变,而保持为 LinphoneCallEnd。但是通话流程并没有受到影响,在 call_accepted 函数中重新为 lc->current_call 赋值。至此,通话过程建立,因此双方仍然能正常通话。

第三步:当主叫再次呼叫,则因为在 linphone_core_invite_address_with_params 函数中检测到 lc->current_call 为非空,直接就返回了,因此并没有重新建立呼叫。如果此时主叫调用 linphone_core_terminate_call 函数来结束本次呼叫,则主叫会发送一个 BYE 消息。当主叫收到被叫对 BYE 的确认消息(EXOSIP_CALL_RELEASED)后,进入 LinphoneCallReleased 状态,并在 linphone_call_set_state 函数中将 call->op 释放掉。

第四步:当主叫第三次呼叫,因为 lc->current_call 仍然为非空,同样不会重新建立呼叫。如果此时主叫再次调用 linphone_core_terminate_call 函数来结束本次呼叫,则在调用 sal_call_terminate 函数的时候,因为 call->op 已经被释放而导致访问内存非法,程序崩溃。

 

第二种情况:

主叫拨打客服电话,快速挂断。因为客服电话是自动接听,因此服务器对 INVITE 的临时响应消息(100、180或183)和最终响应消息(200)同时到达。Linphone 对消息的接收和处理流程应该是先接收所有到达的消息放到消息队列中,然后再逐条处理,这就导致 Linphone 标记收到的最后消息为 200 OK。为了解决第一种崩溃情况,在对 INVITE 临时响应消息进行处理的时候,我增加了对当前 call 的检查,所以不会有问题,只会根据情况发送 bye 消息。但是,当处理 200 OK 的时候,因为没有对当前 call 进行检查,因此在执行 call_accepted 函数的时候,调用 eXosip_call_build_ack 之后 msg 为空,导致调用 _osip_list_set_empty 函数时崩溃。

你可能感兴趣的:(网络技术,sip)