annotate sip-in/prack.c @ 158:51cf5ea7f320

sip-out: map INVITE errors to GSM cause values
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 12 Oct 2022 08:45:39 -0800
parents c1c94b7fc2e2
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
108
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * Here we implement our handling of SIP PRACK, expected from callers
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 * when we send them a reliable 180 Ringing response.
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4 */
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <sys/types.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <sys/socket.h>
109
9b87894704eb sip-in: first step toward final call clearing
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
8 #include <sys/time.h>
108
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <netinet/in.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <ctype.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdio.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <stdint.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <stdlib.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include <string.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include <strings.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include <syslog.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 #include "../include/gsm48_const.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 #include "../libsip/parse.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 #include "../libsip/uas_basic.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 #include "../libsip/out_msg.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21 #include "call.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 extern char *get_single_header();
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 extern struct call *find_call_by_sip_id();
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25
109
9b87894704eb sip-in: first step toward final call clearing
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
26 extern unsigned sip_linger_error;
9b87894704eb sip-in: first step toward final call clearing
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
27
108
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 void
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 handle_sip_prack(req, ess, sin)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 struct sip_pkt_rx *req;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 struct uas_parse_hdrs *ess;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 struct sockaddr_in *sin;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 struct call *call;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 struct sip_msg_out resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 char *rack, *orig_method, *cp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 unsigned rseq, orig_num;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 int rc;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 call = find_call_by_sip_id(ess->call_id);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 if (!call) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 start_response_out_msg(&resp, "481 Call-ID not found");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 error_resp: rc = add_resp_basic_headers(&resp, ess, req->req_method);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 if (rc < 0)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 out_msg_finish(&resp);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 sip_tx_packet(&resp, sin);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 rack = get_single_header(req, "RAck", (char *) 0, (int *) 0);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 if (!rack) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 start_response_out_msg(&resp, "400 Missing RAck header");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 if (!isdigit(*rack)) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 malformed: start_response_out_msg(&resp, "400 Malformed RAck header");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 rseq = strtoul(rack, &cp, 10);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 if (!isspace(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 while (isspace(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 cp++;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 if (!isdigit(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 orig_num = strtoul(cp, &cp, 10);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 if (!isspace(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 while (isspace(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 cp++;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 if (!isupper(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 orig_method = cp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 while (isalnum(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 cp++;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 if (*cp)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 if (rseq != 1 || orig_num != call->invite_cseq ||
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 strcmp(orig_method, "INVITE")) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 start_response_out_msg(&resp,
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 "481 RAck fails to match our 100rel response");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 switch (call->sip_state) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 case SIP_STATE_RINGING_REL:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 call->sip_state = SIP_STATE_RINGING;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 start_response_out_msg(&resp, "200 OK");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 rc = add_resp_basic_headers(&resp, ess, req->req_method);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 if (rc < 0) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 syslog(LOG_ERR, "PRACK 200 response length exceeded");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 call->sip_state = SIP_STATE_MSG_SIZE_ERR;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 call->overall_state = OVERALL_STATE_TEARDOWN;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 disconnect_mncc(call, GSM48_CAUSE_LOC_PRN_S_LU,
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 GSM48_CC_CAUSE_INTERWORKING);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 disconnect_tmgw(call);
109
9b87894704eb sip-in: first step toward final call clearing
Mychaela Falconia <falcon@freecalypso.org>
parents: 108
diff changeset
96 sip_mark_end_time(call, sip_linger_error);
108
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 out_msg_finish(&resp);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 sip_tx_packet(&resp, sin);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 case SIP_STATE_RINGING:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 case SIP_STATE_INVITE_200:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 start_response_out_msg(&resp, "200 OK");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 rc = add_resp_basic_headers(&resp, ess, req->req_method);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 if (rc < 0)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
108 out_msg_finish(&resp);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 sip_tx_packet(&resp, sin);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 case SIP_STATE_INVITE_PROC:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 case SIP_STATE_CONNECTED:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 case SIP_STATE_BYE_SENT:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 case SIP_STATE_INVITE_ERR:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 case SIP_STATE_ENDED:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 start_response_out_msg(&resp,
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 "481 No outstanding 100rel response");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
118 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
119 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
120 }