1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
| /*
* Set transaction state, and inform TU about the transaction state change.
*/
static void tsx_set_state( pjsip_transaction *tsx,
pjsip_tsx_state_e state,
pjsip_event_id_e event_src_type,
void *event_src )
{
pjsip_tsx_state_e prev_state = tsx->state;
/* New state must be greater than previous state */
pj_assert(state >= tsx->state);
PJ_LOG(5, (tsx->obj_name, "State changed from %s to %s, event=%s",
state_str[tsx->state], state_str[state],
pjsip_event_str(event_src_type)));
pj_log_push_indent();
/* Change state. */
tsx->state = state;
/* Update the state handlers. */
if (tsx->role == PJSIP_ROLE_UAC) {
tsx->state_handler = tsx_state_handler_uac[state];
} else {
tsx->state_handler = tsx_state_handler_uas[state];
}
/* Before informing TU about state changed, inform TU about
* rx event.
*/
if (event_src_type==PJSIP_EVENT_RX_MSG && tsx->tsx_user) {
pjsip_rx_data *rdata = (pjsip_rx_data*) event_src;
pj_assert(rdata != NULL);
if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG &&
tsx->tsx_user->on_rx_response)
{
(*tsx->tsx_user->on_rx_response)(rdata);
}
}
/* Inform TU about state changed. */
if (tsx->tsx_user && tsx->tsx_user->on_tsx_state) {
pjsip_event e;
PJSIP_EVENT_INIT_TSX_STATE(e, tsx, event_src_type, event_src,
prev_state);
(*tsx->tsx_user->on_tsx_state)(tsx, &e);
}
/* When the transaction is terminated, release transport, and free the
* saved last transmitted message.
*/
if (state == PJSIP_TSX_STATE_TERMINATED) {
pj_time_val timeout = {0, 0};
/* If we're still waiting for a message to be sent.. */
if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
/* Disassociate ourselves from the outstanding transmit data
* so that when the send callback is called we will be able
* to ignore that (otherwise we'll get assertion, see
* http://trac.pjsip.org/repos/ticket/1033)
*/
if (tsx->pending_tx) {
tsx->pending_tx->mod_data[mod_tsx_layer.mod.id] = NULL;
tsx->pending_tx = NULL;
}
tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
}
lock_timer(tsx);
/* Cancel timeout timer. */
if (tsx->timeout_timer.id != 0) {
pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
tsx->timeout_timer.id = 0;
}
tsx->timeout_timer.id = TIMER_ACTIVE;
pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
&timeout);
unlock_timer(tsx);
} else if (state == PJSIP_TSX_STATE_DESTROYED) {
/* Unregister transaction. */
mod_tsx_layer_unregister_tsx(tsx);
/* Destroy transaction. */
tsx_destroy(tsx);
}
pj_log_pop_indent();
}
|