📄 sip_xaction_state_mc.c
字号:
sip_xaction_time_obj_t *timer_obj_K = NULL; sip_message_type_t *sip_msg_info; int prev_state; _sip_msg_t *msg = *sip_msg; boolean_t isreliable; assert(msg->sip_msg_req_res != NULL); assert(sip_trans != NULL); sip_msg_info = msg->sip_msg_req_res; isreliable = sip_is_conn_reliable(conn_obj); resp_code = sip_msg_info->sip_resp_code; (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); prev_state = sip_trans->sip_xaction_state; switch (sip_trans->sip_xaction_state) { case SIPS_CLNT_TRYING: if (SIP_PROVISIONAL_RESP(resp_code)) { sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_PROCEEDING; } else if (SIP_FINAL_RESP(resp_code)) { SIP_CANCEL_TIMER( sip_trans->sip_xaction_TE); SIP_CANCEL_TIMER( sip_trans->sip_xaction_TF); /* Start timer K for unreliable transports */ if (!isreliable) { timer_obj_K = sip_setup_timer( conn_obj, sip_trans, NULL, sip_trans->sip_xaction_TK, SIP_XACTION_TIMER_K); if (timer_obj_K == NULL) { (void) pthread_mutex_unlock(& sip_trans-> sip_xaction_mutex); return (ENOMEM); } SIP_SCHED_TIMER( sip_trans->sip_xaction_TK, timer_obj_K, sip_xaction_state_timer_fire); if (!SIP_IS_TIMER_RUNNING( sip_trans->sip_xaction_TK)) { (void) pthread_mutex_unlock( &sip_trans-> sip_xaction_mutex); free(timer_obj_K); return (ENOMEM); } sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_COMPLETED; } else { sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_TERMINATED; } } break; case SIPS_CLNT_NONINV_PROCEEDING: if (SIP_PROVISIONAL_RESP(resp_code)) { break; } else if (SIP_FINAL_RESP(resp_code)) { SIP_CANCEL_TIMER( sip_trans->sip_xaction_TE); SIP_CANCEL_TIMER( sip_trans->sip_xaction_TF); /* Start timer K for unreliable transports */ if (!isreliable) { timer_obj_K = sip_setup_timer( conn_obj, sip_trans, NULL, sip_trans->sip_xaction_TK, SIP_XACTION_TIMER_K); if (timer_obj_K == NULL) { (void) pthread_mutex_unlock(& sip_trans-> sip_xaction_mutex); return (ENOMEM); } SIP_SCHED_TIMER( sip_trans->sip_xaction_TK, timer_obj_K, sip_xaction_state_timer_fire); if (!SIP_IS_TIMER_RUNNING( sip_trans->sip_xaction_TK)) { (void) pthread_mutex_unlock( &sip_trans-> sip_xaction_mutex); free(timer_obj_K); return (ENOMEM); } sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_COMPLETED; } else { sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_TERMINATED; } } break; default: (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); return (EPROTO); } (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); if (prev_state != sip_trans->sip_xaction_state && sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); } return (0);}/* * * If there is a transport error, sending the message out, terminate the * transaction. *//* ARGSUSED */voidsip_xaction_terminate(sip_xaction_t *sip_trans, _sip_msg_t *msg, int transport){ sip_message_type_t *sip_msg_info; int state; int prev_state; sip_msg_info = msg->sip_msg_req_res; (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); if (sip_msg_info->is_request) { if (sip_trans->sip_xaction_method == INVITE) state = SIPS_CLNT_INV_TERMINATED; else state = SIPS_CLNT_NONINV_TERMINATED; } else { if (sip_trans->sip_xaction_method == INVITE) state = SIPS_SRV_INV_TERMINATED; else state = SIPS_SRV_NONINV_TERMINATED; } prev_state = sip_trans->sip_xaction_state; sip_trans->sip_xaction_state = state; (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, (sip_msg_t)msg, prev_state, sip_trans->sip_xaction_state); } sip_xaction_delete(sip_trans);}/* * --------------------------- Timer Routine --------------------------- */voidsip_xaction_state_timer_fire(void *args){ sip_xaction_time_obj_t *time_obj = (sip_xaction_time_obj_t *)args; sip_xaction_t *sip_trans = time_obj->sip_trans; _sip_msg_t *new_msg; boolean_t destroy_trans = B_FALSE; sip_conn_object_t conn_obj; int prev_state; assert(time_obj != NULL); (void) pthread_mutex_lock(&sip_trans->sip_xaction_mutex); prev_state = sip_trans->sip_xaction_state; switch (time_obj->sip_xaction_timer_type) { case SIP_XACTION_TIMER_A: if (sip_trans->sip_xaction_state != SIPS_CLNT_CALLING) break; /* Assert candidate */ if (sip_trans->sip_xaction_last_msg == NULL) break; if (sip_trans->sip_xaction_conn_obj == NULL) break; new_msg = sip_trans->sip_xaction_last_msg; conn_obj = sip_trans->sip_xaction_conn_obj; if (sip_stack_send(conn_obj, new_msg->sip_msg_buf, new_msg->sip_msg_len) != 0) { sip_del_conn_obj_cache( sip_trans->sip_xaction_conn_obj, (void *)sip_trans); sip_trans->sip_xaction_state = SIPS_CLNT_INV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } SIP_SET_TIMEOUT(sip_trans->sip_xaction_TA, 2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TA)); /* Reschedule the timer */ SIP_SCHED_TIMER(sip_trans->sip_xaction_TA, time_obj, sip_xaction_state_timer_fire); if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TA)) { sip_del_conn_obj_cache( sip_trans->sip_xaction_conn_obj, (void *)sip_trans); sip_trans->sip_xaction_state = SIPS_CLNT_INV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); return; case SIP_XACTION_TIMER_B: SIP_CANCEL_TIMER(sip_trans->sip_xaction_TA); if (sip_trans->sip_xaction_state == SIPS_CLNT_CALLING) { sip_trans->sip_xaction_state = SIPS_CLNT_INV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } break; case SIP_XACTION_TIMER_D: if (sip_trans->sip_xaction_state == SIPS_CLNT_INV_COMPLETED) { SIP_CANCEL_TIMER( sip_trans->sip_xaction_TB); sip_trans->sip_xaction_state = SIPS_CLNT_INV_TERMINATED; destroy_trans = B_TRUE; } break; case SIP_XACTION_TIMER_E: /* Assert candidate */ if (sip_trans->sip_xaction_state != SIPS_CLNT_TRYING && sip_trans->sip_xaction_state != SIPS_CLNT_NONINV_PROCEEDING) { break; } /* Assert candidate */ if (sip_trans->sip_xaction_last_msg == NULL) break; if (sip_trans->sip_xaction_conn_obj == NULL) break; conn_obj = sip_trans->sip_xaction_conn_obj; new_msg = sip_trans->sip_xaction_last_msg; if (sip_stack_send(conn_obj, new_msg->sip_msg_buf, new_msg->sip_msg_len) != 0) { sip_del_conn_obj_cache( sip_trans->sip_xaction_conn_obj, (void *)sip_trans); sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } SIP_SET_TIMEOUT(sip_trans->sip_xaction_TE, MIN(SIP_TIMER_T2, 2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TE))); /* Reschedule the timer */ SIP_SCHED_TIMER(sip_trans->sip_xaction_TE, time_obj, sip_xaction_state_timer_fire); if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TE)) { sip_del_conn_obj_cache( sip_trans->sip_xaction_conn_obj, (void *)sip_trans); sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); return; case SIP_XACTION_TIMER_F: SIP_CANCEL_TIMER(sip_trans->sip_xaction_TE); /* XXXCheck for deleting sip_xaction_last_msg */ if (sip_trans->sip_xaction_state == SIPS_CLNT_TRYING || sip_trans->sip_xaction_state == SIPS_CLNT_NONINV_PROCEEDING) { sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } break; case SIP_XACTION_TIMER_G: /* Assert candidate */ if (sip_trans->sip_xaction_last_msg == NULL) break; if (sip_trans->sip_xaction_conn_obj == NULL) break; if (sip_trans->sip_xaction_state != SIPS_SRV_INV_COMPLETED) { break; } new_msg = sip_trans->sip_xaction_last_msg; conn_obj = sip_trans->sip_xaction_conn_obj; if (sip_stack_send(conn_obj, new_msg->sip_msg_buf, new_msg->sip_msg_len) != 0) { sip_del_conn_obj_cache( sip_trans->sip_xaction_conn_obj, (void *)sip_trans); sip_trans->sip_xaction_state = SIPS_SRV_INV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } SIP_SET_TIMEOUT(sip_trans->sip_xaction_TG, MIN(SIP_TIMER_T2, 2 * SIP_GET_TIMEOUT(sip_trans->sip_xaction_TG))); SIP_SCHED_TIMER(sip_trans->sip_xaction_TG, time_obj, sip_xaction_state_timer_fire); if (!SIP_IS_TIMER_RUNNING(sip_trans->sip_xaction_TG)) { sip_del_conn_obj_cache( sip_trans->sip_xaction_conn_obj, (void *)sip_trans); sip_trans->sip_xaction_state = SIPS_SRV_INV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); return; case SIP_XACTION_TIMER_H: SIP_CANCEL_TIMER(sip_trans->sip_xaction_TG); /* XXXCheck for deleting sip_xaction_last_msg */ if (sip_trans->sip_xaction_state == SIPS_SRV_INV_COMPLETED) { sip_trans->sip_xaction_state = SIPS_SRV_INV_TERMINATED; (void) pthread_mutex_unlock( &sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL) { sip_xaction_ulp_state_cb( (sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } if (sip_xaction_ulp_trans_err != NULL) { sip_xaction_ulp_trans_err(sip_trans, 0, NULL); } sip_xaction_delete(sip_trans); free(time_obj); return; } break; case SIP_XACTION_TIMER_I: if (sip_trans->sip_xaction_state == SIPS_SRV_CONFIRMED) { SIP_CANCEL_TIMER( sip_trans->sip_xaction_TH); sip_trans->sip_xaction_state = SIPS_SRV_INV_TERMINATED; destroy_trans = B_TRUE; } break; case SIP_XACTION_TIMER_J: if (sip_trans->sip_xaction_state == SIPS_SRV_NONINV_COMPLETED) { sip_trans->sip_xaction_state = SIPS_SRV_NONINV_TERMINATED; destroy_trans = B_TRUE; } break; case SIP_XACTION_TIMER_K: if (sip_trans->sip_xaction_state == SIPS_CLNT_NONINV_COMPLETED) { SIP_CANCEL_TIMER( sip_trans->sip_xaction_TF); sip_trans->sip_xaction_state = SIPS_CLNT_NONINV_TERMINATED; destroy_trans = B_TRUE; } break; default: break; } if (destroy_trans) { (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL && prev_state != sip_trans->sip_xaction_state) { sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } sip_xaction_delete(sip_trans); free(time_obj); return; } (void) pthread_mutex_unlock(&sip_trans->sip_xaction_mutex); if (sip_xaction_ulp_state_cb != NULL && prev_state != sip_trans->sip_xaction_state) { sip_xaction_ulp_state_cb((sip_transaction_t)sip_trans, NULL, prev_state, sip_trans->sip_xaction_state); } free(time_obj);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -