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 }