FreeCalypso > hg > themwi-system-sw
comparison sip-in/invite_resp.c @ 145:4b685a5d9bd4
sip-in code: split invite.c into 3 separate C modules
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 08 Oct 2022 19:31:05 -0800 |
parents | sip-in/invite.c@c93c339271a7 |
children |
comparison
equal
deleted
inserted
replaced
144:4e16aeafbfbf | 145:4b685a5d9bd4 |
---|---|
1 /* | |
2 * Here we implement SIP INVITE response generation. | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <sys/socket.h> | |
7 #include <sys/time.h> | |
8 #include <netinet/in.h> | |
9 #include <arpa/inet.h> | |
10 #include <stdio.h> | |
11 #include <stdint.h> | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 #include <strings.h> | |
15 #include <syslog.h> | |
16 #include "../include/gsm48_const.h" | |
17 #include "../libsip/sdp.h" | |
18 #include "../libsip/out_msg.h" | |
19 #include "call.h" | |
20 | |
21 extern struct in_addr sip_bind_ip; | |
22 extern unsigned sip_bind_port; | |
23 extern unsigned sip_linger_error; | |
24 | |
25 fill_invite_resp_from_call(msg, call) | |
26 struct sip_msg_out *msg; | |
27 struct call *call; | |
28 { | |
29 char cseq_str[32]; | |
30 int rc; | |
31 | |
32 rc = out_msg_add_header(msg, "From", call->invite_from); | |
33 if (rc < 0) | |
34 return rc; | |
35 rc = out_msg_add_header(msg, "To", call->invite_to); | |
36 if (rc < 0) | |
37 return rc; | |
38 rc = out_msg_add_header(msg, "Call-ID", call->sip_call_id); | |
39 if (rc < 0) | |
40 return rc; | |
41 sprintf(cseq_str, "%u INVITE", call->invite_cseq); | |
42 rc = out_msg_add_header(msg, "CSeq", cseq_str); | |
43 if (rc < 0) | |
44 return rc; | |
45 return out_msg_add_header(msg, "Via", call->invite_via); | |
46 } | |
47 | |
48 fill_invite_200_resp(msg, call) | |
49 struct sip_msg_out *msg; | |
50 struct call *call; | |
51 { | |
52 char contact_str[80]; | |
53 struct sdp_gen sdp; | |
54 int rc; | |
55 | |
56 start_response_out_msg(msg, "200 CONNECT"); | |
57 rc = fill_invite_resp_from_call(msg, call); | |
58 if (rc < 0) | |
59 return rc; | |
60 sprintf(contact_str, "<sip:%s:%u;transport=udp>", | |
61 inet_ntoa(sip_bind_ip), sip_bind_port); | |
62 rc = out_msg_add_header(msg, "Contact", contact_str); | |
63 if (rc < 0) | |
64 return rc; | |
65 rc = out_msg_add_header(msg, "Content-Type", "application/sdp"); | |
66 if (rc < 0) | |
67 return rc; | |
68 bzero(&sdp, sizeof sdp); | |
69 sdp.conn_ip = call->pstn_rtp_local.sin_addr; | |
70 sdp.conn_port = ntohs(call->pstn_rtp_local.sin_port); | |
71 sdp.codec_mask = call->use_pcma ? SDP_CODEC_MASK_PCMA | |
72 : SDP_CODEC_MASK_PCMU; | |
73 sdp.session_id = (sdp.conn_port << 16) | call->sdp_addend; | |
74 sdp.owner_ip = sip_bind_ip; | |
75 return out_msg_finish_sdp(msg, &sdp); | |
76 } | |
77 | |
78 void | |
79 signal_invite_ringing(call) | |
80 struct call *call; | |
81 { | |
82 struct sip_msg_out resp; | |
83 int rc; | |
84 | |
85 start_response_out_msg(&resp, "180 Ringing"); | |
86 rc = fill_invite_resp_from_call(&resp, call); | |
87 if (rc < 0) { | |
88 msg_size_err: syslog(LOG_ERR, "INVITE 180 response length exceeded"); | |
89 call->sip_state = SIP_STATE_MSG_SIZE_ERR; | |
90 call->overall_state = OVERALL_STATE_TEARDOWN; | |
91 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
92 GSM48_CC_CAUSE_INTERWORKING); | |
93 disconnect_tmgw(call); | |
94 sip_mark_end_time(call, sip_linger_error); | |
95 return; | |
96 } | |
97 if (call->use_100rel) { | |
98 rc = out_msg_add_header(&resp, "Require", "100rel"); | |
99 if (rc < 0) | |
100 goto msg_size_err; | |
101 rc = out_msg_add_header(&resp, "RSeq", "1"); | |
102 if (rc < 0) | |
103 goto msg_size_err; | |
104 } | |
105 out_msg_finish(&resp); | |
106 sip_tx_packet(&resp, &call->udp_sin); | |
107 if (call->use_100rel) { | |
108 call->sip_state = SIP_STATE_RINGING_REL; | |
109 call->sip_tx_count = 1; | |
110 } else | |
111 call->sip_state = SIP_STATE_RINGING; | |
112 } | |
113 | |
114 void | |
115 signal_invite_200(call) | |
116 struct call *call; | |
117 { | |
118 struct sip_msg_out resp; | |
119 int rc; | |
120 | |
121 rc = fill_invite_200_resp(&resp, call); | |
122 if (rc < 0) { | |
123 syslog(LOG_ERR, "INVITE 200 response length exceeded"); | |
124 call->sip_state = SIP_STATE_MSG_SIZE_ERR; | |
125 call->overall_state = OVERALL_STATE_TEARDOWN; | |
126 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU, | |
127 GSM48_CC_CAUSE_INTERWORKING); | |
128 disconnect_tmgw(call); | |
129 sip_mark_end_time(call, sip_linger_error); | |
130 return; | |
131 } | |
132 sip_tx_packet(&resp, &call->udp_sin); | |
133 call->sip_state = SIP_STATE_INVITE_200; | |
134 call->sip_tx_count = 1; | |
135 } | |
136 | |
137 void | |
138 signal_invite_error(call) | |
139 struct call *call; | |
140 { | |
141 struct sip_msg_out resp; | |
142 int rc; | |
143 | |
144 start_response_out_msg(&resp, call->invite_fail); | |
145 rc = fill_invite_resp_from_call(&resp, call); | |
146 if (rc < 0) { | |
147 syslog(LOG_ERR, "INVITE late error response length exceeded"); | |
148 call->sip_state = SIP_STATE_MSG_SIZE_ERR; | |
149 sip_mark_end_time(call, sip_linger_error); | |
150 transition_dead_sip(call); | |
151 return; | |
152 } | |
153 out_msg_finish(&resp); | |
154 sip_tx_packet(&resp, &call->udp_sin); | |
155 call->sip_state = SIP_STATE_INVITE_ERR; | |
156 call->sip_tx_count = 1; | |
157 } |