1 /*
2 	belle-sip - SIP (RFC3261) library.
3     Copyright (C) 2010  Belledonne Communications SARL
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 /**
20  * INVITE server transaction implementation.
21 **/
22 
23 #include "belle_sip_internal.h"
24 
ist_on_terminate(belle_sip_ist_t * obj)25 static void ist_on_terminate(belle_sip_ist_t *obj){
26 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
27 	/*timer pointers are set to NULL because they can be released later*/
28 	if (obj->timer_G){
29 		belle_sip_transaction_stop_timer(base,obj->timer_G);
30 		belle_sip_object_unref(obj->timer_G);
31 		obj->timer_G=NULL;
32 	}
33 	if (obj->timer_H){
34 		belle_sip_transaction_stop_timer(base,obj->timer_H);
35 		belle_sip_object_unref(obj->timer_H);
36 		obj->timer_H=NULL;
37 	}
38 	if (obj->timer_I){
39 		belle_sip_transaction_stop_timer(base,obj->timer_I);
40 		belle_sip_object_unref(obj->timer_I);
41 		obj->timer_I=NULL;
42 	}
43 	if (obj->timer_L){
44 		belle_sip_transaction_stop_timer(base,obj->timer_L);
45 		belle_sip_object_unref(obj->timer_L);
46 		obj->timer_L=NULL;
47 	}
48 }
49 
ist_destroy(belle_sip_ist_t * obj)50 static void ist_destroy(belle_sip_ist_t *obj){
51 	ist_on_terminate(obj);
52 }
53 
54 /* Timer G: INVITE response retransmit interval */
ist_on_timer_G(belle_sip_ist_t * obj)55 static int ist_on_timer_G(belle_sip_ist_t *obj){
56 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
57 	if (base->state==BELLE_SIP_TRANSACTION_COMPLETED){
58 		const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base);
59 		int interval=belle_sip_source_get_timeout(obj->timer_G);
60 
61 		belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->last_response);
62 		belle_sip_source_set_timeout(obj->timer_G,MIN(2*interval,cfg->T2));
63 		return BELLE_SIP_CONTINUE;
64 	}
65 	return BELLE_SIP_STOP;
66 }
67 
68 /* Timer H: Wait time for ACK receipt */
ist_on_timer_H(belle_sip_ist_t * obj)69 static int ist_on_timer_H(belle_sip_ist_t *obj){
70 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
71 	if (base->state==BELLE_SIP_TRANSACTION_COMPLETED){
72 		belle_sip_transaction_terminate(base);
73 		/*FIXME: no ACK was received, should report the failure */
74 	}
75 	return BELLE_SIP_STOP;
76 }
77 
78 /* Timer I: Wait time for ACK retransmits */
ist_on_timer_I(belle_sip_ist_t * obj)79 static int ist_on_timer_I(belle_sip_ist_t *obj){
80 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
81 	belle_sip_transaction_terminate(base);
82 	return BELLE_SIP_STOP;
83 }
84 
85 /* Timer L: Wait time for accepted INVITE request retransmits */
ist_on_timer_L(belle_sip_ist_t * obj)86 static int ist_on_timer_L(belle_sip_ist_t *obj){
87 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
88 	belle_sip_transaction_terminate(base);
89 	return BELLE_SIP_STOP;
90 }
91 
belle_sip_ist_process_ack(belle_sip_ist_t * obj,belle_sip_message_t * ack)92 int belle_sip_ist_process_ack(belle_sip_ist_t *obj, belle_sip_message_t *ack){
93 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
94 	int ret=-1;
95 	switch(base->state){
96 		case BELLE_SIP_TRANSACTION_COMPLETED:
97 			/*clear timer G*/
98 			if (obj->timer_G){
99 				belle_sip_transaction_stop_timer(base,obj->timer_G);
100 				belle_sip_object_unref(obj->timer_G);
101 				obj->timer_G=NULL;
102 			}
103 			belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_CONFIRMED);
104 			if (!belle_sip_channel_is_reliable(base->channel)){
105 				const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base);
106 				obj->timer_I=belle_sip_timeout_source_new((belle_sip_source_func_t)ist_on_timer_I,obj,cfg->T4);
107 				belle_sip_transaction_start_timer(base,obj->timer_I);
108 			}else ist_on_timer_I(obj);
109 		break;
110 		case BELLE_SIP_TRANSACTION_ACCEPTED:
111 			ret=0; /*let the ACK be reported to TU */
112 		break;
113 		default:
114 		break;
115 	}
116 	return ret;
117 }
118 
ist_send_new_response(belle_sip_ist_t * obj,belle_sip_response_t * resp)119 static int ist_send_new_response(belle_sip_ist_t *obj, belle_sip_response_t *resp){
120 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
121 	int code=belle_sip_response_get_status_code(resp);
122 	int ret=-1;
123 	switch(base->state){
124 		case BELLE_SIP_TRANSACTION_PROCEEDING:
125 			{
126 				const belle_sip_timer_config_t *cfg=belle_sip_transaction_get_timer_config(base);
127 				ret=0;
128 				belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)resp);
129 				if (code>=200 && code<300){
130 					belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_ACCEPTED);
131 					obj->timer_L=belle_sip_timeout_source_new((belle_sip_source_func_t)ist_on_timer_L,obj,64*cfg->T1);
132 					belle_sip_transaction_start_timer(base,obj->timer_L);
133 				}else if (code>=300){
134 					belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_COMPLETED);
135 					if (!belle_sip_channel_is_reliable(base->channel)){
136 						obj->timer_G=belle_sip_timeout_source_new((belle_sip_source_func_t)ist_on_timer_G,obj,cfg->T1);
137 						belle_sip_transaction_start_timer(base,obj->timer_G);
138 					}
139 					obj->timer_H=belle_sip_timeout_source_new((belle_sip_source_func_t)ist_on_timer_H,obj,64*cfg->T1);
140 					belle_sip_transaction_start_timer(base,obj->timer_H);
141 				}
142 			}
143 		break;
144 		case BELLE_SIP_TRANSACTION_ACCEPTED:
145 			if (code>=200 && code<300){
146 				ret=0; /*let the response go to transport layer*/
147 			}
148 		default:
149 		break;
150 	}
151 	return ret;
152 }
153 
ist_on_request_retransmission(belle_sip_nist_t * obj)154 static void ist_on_request_retransmission(belle_sip_nist_t *obj){
155 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
156 	switch(base->state){
157 		case BELLE_SIP_TRANSACTION_PROCEEDING:
158 		case BELLE_SIP_TRANSACTION_COMPLETED:
159 			belle_sip_channel_queue_message(base->channel,(belle_sip_message_t*)base->last_response);
160 		break;
161 		default:
162 		break;
163 	}
164 }
165 
166 
167 BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_ist_t);
168 
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_ist_t)169 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_ist_t)
170 	{
171 		{
172 			{
173 				BELLE_SIP_VPTR_INIT(belle_sip_ist_t,belle_sip_server_transaction_t,TRUE),
174 				(belle_sip_object_destroy_t)ist_destroy,
175 				NULL,
176 				NULL,
177 				BELLE_SIP_DEFAULT_BUFSIZE_HINT
178 			},
179 			(void (*)(belle_sip_transaction_t *))ist_on_terminate
180 		},
181 		(int (*)(belle_sip_server_transaction_t*, belle_sip_response_t *))ist_send_new_response,
182 		(void (*)(belle_sip_server_transaction_t*))ist_on_request_retransmission,
183 	}
184 BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
185 
186 
belle_sip_ist_new(belle_sip_provider_t * prov,belle_sip_request_t * req)187 belle_sip_ist_t *belle_sip_ist_new(belle_sip_provider_t *prov, belle_sip_request_t *req){
188 	belle_sip_ist_t *obj=belle_sip_object_new(belle_sip_ist_t);
189 	belle_sip_transaction_t *base=(belle_sip_transaction_t*)obj;
190 
191 	belle_sip_server_transaction_init((belle_sip_server_transaction_t*)obj,prov,req);
192 	belle_sip_transaction_set_state(base,BELLE_SIP_TRANSACTION_PROCEEDING);
193 	return obj;
194 }
195