annotate sip-in/prack.c @ 108:0d6435808bcd

sip-in: implement 100rel for 180 Ringing response
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 28 Sep 2022 14:29:10 -0800
parents
children 9b87894704eb
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>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <netinet/in.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <ctype.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdio.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <stdint.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <stdlib.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <string.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include <strings.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include <syslog.h>
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include "../include/gsm48_const.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 #include "../libsip/parse.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 #include "../libsip/uas_basic.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19 #include "../libsip/out_msg.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 #include "call.h"
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 extern char *get_single_header();
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 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
24
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 void
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 handle_sip_prack(req, ess, sin)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 struct sip_pkt_rx *req;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 struct uas_parse_hdrs *ess;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 struct sockaddr_in *sin;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 struct call *call;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32 struct sip_msg_out resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 char *rack, *orig_method, *cp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 unsigned rseq, orig_num;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 int rc;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 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
38 if (!call) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 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
40 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
41 if (rc < 0)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 out_msg_finish(&resp);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 sip_tx_packet(&resp, sin);
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 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 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
48 if (!rack) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 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
50 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 if (!isdigit(*rack)) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 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
54 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 rseq = strtoul(rack, &cp, 10);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 if (!isspace(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 while (isspace(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 cp++;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 if (!isdigit(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 orig_num = strtoul(cp, &cp, 10);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64 if (!isspace(*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 while (isspace(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 cp++;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 if (!isupper(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 orig_method = cp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 while (isalnum(*cp))
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72 cp++;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 if (*cp)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 goto malformed;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 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
76 strcmp(orig_method, "INVITE")) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 start_response_out_msg(&resp,
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 "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
79 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 switch (call->sip_state) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 case SIP_STATE_RINGING_REL:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 call->sip_state = SIP_STATE_RINGING;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 start_response_out_msg(&resp, "200 OK");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 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
86 if (rc < 0) {
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 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
88 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
89 call->overall_state = OVERALL_STATE_TEARDOWN;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 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
91 GSM48_CC_CAUSE_INTERWORKING);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 disconnect_tmgw(call);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 /* TODO: transition from TEARDOWN to DEAD_SIP */
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 out_msg_finish(&resp);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 sip_tx_packet(&resp, sin);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 case SIP_STATE_RINGING:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 case SIP_STATE_INVITE_200:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 start_response_out_msg(&resp, "200 OK");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 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
103 if (rc < 0)
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 return;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 out_msg_finish(&resp);
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 sip_tx_packet(&resp, sin);
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 case SIP_STATE_INVITE_PROC:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
109 case SIP_STATE_CONNECTED:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
110 case SIP_STATE_BYE_SENT:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
111 case SIP_STATE_INVITE_ERR:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
112 case SIP_STATE_ENDED:
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
113 start_response_out_msg(&resp,
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
114 "481 No outstanding 100rel response");
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
115 goto error_resp;
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
116 }
0d6435808bcd sip-in: implement 100rel for 180 Ringing response
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
117 }