annotate sip-in/cancel.c @ 95:f280328e7e2e

themwi-mgw: initial implementation of PSTN to GSM forwarding
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 25 Sep 2022 19:17:44 -0800
parents b0df2b200d77
children 0d6435808bcd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
79
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
1 /*
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
2 * Here we implement our handling of SIP CANCEL method.
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
3 */
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
4
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
5 #include <sys/types.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
6 #include <sys/socket.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
7 #include <netinet/in.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
8 #include <stdio.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
9 #include <stdint.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
10 #include <stdlib.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
11 #include <string.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
12 #include <strings.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
13 #include <syslog.h>
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
14 #include "../include/gsm48_const.h"
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
15 #include "../libsip/parse.h"
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
16 #include "../libsip/uas_basic.h"
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
17 #include "../libsip/out_msg.h"
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
18 #include "call.h"
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
19
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
20 extern struct call *find_call_by_sip_id();
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
21
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
22 static void
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
23 cancel_200_response(req, ess, sin, call)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
24 struct sip_pkt_rx *req;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
25 struct uas_parse_hdrs *ess;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
26 struct sockaddr_in *sin;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
27 struct call *call;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
28 {
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
29 struct sip_msg_out resp;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
30 char cseq_str[32];
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
31 int rc;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
32
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
33 start_response_out_msg(&resp, "200 OK");
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
34 rc = out_msg_add_header(&resp, "From", call->invite_from);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
35 if (rc < 0) {
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
36 msg_size_err: syslog(LOG_ERR, "CANCEL 200 response length exceeded");
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
37 return;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
38 }
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
39 rc = out_msg_add_header(&resp, "To", call->invite_to);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
40 if (rc < 0)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
41 goto msg_size_err;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
42 rc = out_msg_add_header(&resp, "Call-ID", call->sip_call_id);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
43 if (rc < 0)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
44 goto msg_size_err;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
45 sprintf(cseq_str, "%u CANCEL", call->invite_cseq);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
46 rc = out_msg_add_header(&resp, "CSeq", cseq_str);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
47 if (rc < 0)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
48 goto msg_size_err;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
49 rc = out_msg_add_header(&resp, "Via", ess->via);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
50 if (rc < 0)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
51 goto msg_size_err;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
52 out_msg_finish(&resp);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
53 sip_tx_packet(&resp, sin);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
54 }
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
55
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
56 static void
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
57 cancel_481_response(req, ess, sin)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
58 struct sip_pkt_rx *req;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
59 struct uas_parse_hdrs *ess;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
60 struct sockaddr_in *sin;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
61 {
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
62 struct sip_msg_out resp;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
63 int rc;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
64
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
65 start_response_out_msg(&resp, "481 Call-ID/CSeq not found");
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
66 rc = add_resp_basic_headers(&resp, ess, req->req_method);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
67 if (rc < 0)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
68 return;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
69 out_msg_finish(&resp);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
70 sip_tx_packet(&resp, sin);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
71 }
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
72
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
73 void
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
74 handle_sip_cancel(req, ess, sin)
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
75 struct sip_pkt_rx *req;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
76 struct uas_parse_hdrs *ess;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
77 struct sockaddr_in *sin;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
78 {
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
79 struct call *call;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
80
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
81 call = find_call_by_sip_id(ess->call_id);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
82 if (!call) {
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
83 cancel_481_response(req, ess, sin);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
84 return;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
85 }
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
86 /* weed out wrong CSeq */
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
87 if (ess->cseq_num != call->invite_cseq) {
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
88 cancel_481_response(req, ess, sin);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
89 return;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
90 }
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
91 /* it is for us - act on it */
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
92 switch (call->sip_state) {
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
93 case SIP_STATE_INVITE_PROC:
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
94 case SIP_STATE_RINGING:
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
95 case SIP_STATE_RINGING_PRACK:
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
96 call->overall_state = OVERALL_STATE_TEARDOWN;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
97 disconnect_mncc(call, GSM48_CAUSE_LOC_NET_BEYOND,
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
98 GSM48_CC_CAUSE_NORM_CALL_CLEAR);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
99 disconnect_tmgw(call);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
100 strcpy(call->invite_fail, "487 Call attempt terminated");
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
101 signal_invite_error(call);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
102 break;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
103 case SIP_STATE_MSG_SIZE_ERR:
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
104 return;
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
105 }
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
106 cancel_200_response(req, ess, sin, call);
b0df2b200d77 sip-in: implement SIP CANCEL
Mychaela Falconia <falcon@freecalypso.org>
parents:
diff changeset
107 }