FreeCalypso > hg > themwi-system-sw
comparison sip-out/call_setup.c @ 154:e54b0a9e322f
beginning of themwi-sip-out
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 11 Oct 2022 23:04:01 -0800 |
parents | sip-in/call_setup.c@1bbe57df74f6 |
children | e89619893c1e |
comparison
equal
deleted
inserted
replaced
153:99fd4ae573ae | 154:e54b0a9e322f |
---|---|
1 /* | |
2 * In this module we implement our initial handling of MNCC_SETUP_IND. | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <sys/socket.h> | |
7 #include <sys/time.h> | |
8 #include <netinet/in.h> | |
9 #include <stdio.h> | |
10 #include <stdint.h> | |
11 #include <stdlib.h> | |
12 #include <string.h> | |
13 #include <strings.h> | |
14 #include <syslog.h> | |
15 #include "../include/mncc.h" | |
16 #include "../include/gsm48_const.h" | |
17 #include "../include/out_routes.h" | |
18 #include "call.h" | |
19 | |
20 extern struct call *find_call_by_mncc_callref(); | |
21 | |
22 extern int block_1900_numbers; | |
23 extern struct call *call_list; | |
24 | |
25 static void | |
26 reject_mo_call(mncc, callref, cause_loc, cause_val) | |
27 struct mncc_conn *mncc; | |
28 uint32_t callref; | |
29 { | |
30 struct gsm_mncc msg; | |
31 | |
32 bzero(&msg, sizeof(struct gsm_mncc)); | |
33 msg.msg_type = MNCC_REJ_REQ; | |
34 msg.callref = callref; | |
35 mncc_set_cause(&msg, cause_loc, cause_val); | |
36 send_mncc_to_sock(mncc, &msg, sizeof(struct gsm_mncc)); | |
37 } | |
38 | |
39 static void | |
40 send_call_proceeding(call) | |
41 struct call *call; | |
42 { | |
43 struct gsm_mncc msg; | |
44 | |
45 bzero(&msg, sizeof(struct gsm_mncc)); | |
46 msg.msg_type = MNCC_CALL_PROC_REQ; | |
47 msg.callref = call->mncc_callref; | |
48 send_mncc_to_sock(call->mncc, &msg, sizeof(struct gsm_mncc)); | |
49 } | |
50 | |
51 void | |
52 handle_setup_ind(mncc, msg, msglen) | |
53 struct mncc_conn *mncc; | |
54 struct gsm_mncc *msg; | |
55 unsigned msglen; | |
56 { | |
57 struct call *call; | |
58 struct sip_out_dest *dest; | |
59 struct special_num_route *special_rt; | |
60 char to_sip_user[MAX_SIP_USER_PART+1]; | |
61 int rc; | |
62 | |
63 if (msglen != sizeof(struct gsm_mncc)) { | |
64 syslog(LOG_CRIT, | |
65 "FATAL: Rx MNCC_SETUP_IND has wrong length"); | |
66 exit(1); | |
67 } | |
68 /* check for duplicates */ | |
69 call = find_call_by_mncc_callref(mncc, msg->callref); | |
70 if (call) { | |
71 syslog(LOG_ERR, "duplicate MNCC_SETUP_IND for callref 0x%x", | |
72 msg->callref); | |
73 /* drop it like OsmoMSC's mncc_builtin does */ | |
74 return; | |
75 } | |
76 if (!(msg->fields & MNCC_F_CALLED) || | |
77 !(msg->fields & MNCC_F_BEARER_CAP)) { | |
78 syslog(LOG_ERR, "rejecting MO call 0x%x: missing mandatory IE", | |
79 msg->callref); | |
80 reject_mo_call(mncc, msg->callref, GSM48_CAUSE_LOC_PRN_S_LU, | |
81 GSM48_CC_CAUSE_INVAL_MAND_INF); | |
82 return; | |
83 } | |
84 /* route based on destination address */ | |
85 refresh_out_routes_db(); | |
86 if (msg->called.type == GSM48_TON_INTERNATIONAL) { | |
87 rc = grok_number_string(msg->called.number, 0); | |
88 if (rc < 2 || rc > MAX_E164_NUMBER) { | |
89 inv_nr_format: reject_mo_call(mncc, msg->callref, | |
90 GSM48_CAUSE_LOC_PRN_S_LU, | |
91 GSM48_CC_CAUSE_INV_NR_FORMAT); | |
92 return; | |
93 } | |
94 if (msg->called.number[0] == '0') | |
95 goto inv_nr_format; | |
96 if (msg->called.number[0] == '1') { | |
97 if (rc != 11) | |
98 goto inv_nr_format; | |
99 if (!is_nanp_valid_prefix(msg->called.number+1)) | |
100 goto inv_nr_format; | |
101 if (msg->called.number[1] == '9' && | |
102 msg->called.number[2] == '0' && | |
103 msg->called.number[3] == '0' && | |
104 block_1900_numbers) { | |
105 call_barred: reject_mo_call(mncc, msg->callref, | |
106 GSM48_CAUSE_LOC_PRN_S_LU, | |
107 GSM48_CC_CAUSE_OP_DET_BARRING); | |
108 return; | |
109 } | |
110 } | |
111 rc = route_e164_number(msg->called.number, &dest); | |
112 if (!rc) { | |
113 no_route_to_dest: reject_mo_call(mncc, msg->callref, | |
114 GSM48_CAUSE_LOC_PRN_S_LU, | |
115 GSM48_CC_CAUSE_NO_ROUTE); | |
116 return; | |
117 } | |
118 to_sip_user[0] = '+'; | |
119 strcpy(to_sip_user+1, msg->called.number); | |
120 } else { | |
121 rc = route_special_number(msg->called.number, &dest, | |
122 &special_rt); | |
123 if (!rc) | |
124 goto no_route_to_dest; | |
125 strcpy(to_sip_user, special_rt->sip_user); | |
126 } | |
127 /* validate From number */ | |
128 if (!(msg->fields & MNCC_F_CALLING)) | |
129 goto call_barred; | |
130 if (msg->calling.type != GSM48_TON_INTERNATIONAL) | |
131 goto call_barred; | |
132 if (grok_number_string(msg->calling.number, 0) != 11 || | |
133 msg->calling.number[0] != '1') | |
134 goto call_barred; | |
135 /* speech-only restriction */ | |
136 if (msg->bearer_cap.transfer != GSM48_BCAP_ITCAP_SPEECH || | |
137 msg->bearer_cap.mode != GSM48_BCAP_TMOD_CIRCUIT) { | |
138 syslog(LOG_ERR, "rejecting MO call 0x%x: bad bearer cap", | |
139 msg->callref); | |
140 reject_mo_call(mncc, msg->callref, GSM48_CAUSE_LOC_PRN_S_LU, | |
141 GSM48_CC_CAUSE_BEARER_CA_UNAVAIL); | |
142 return; | |
143 } | |
144 /* TMGW must be up and running */ | |
145 rc = connect_tmgw_socket(); | |
146 if (rc < 0) { | |
147 reject_mo_call(mncc, msg->callref, GSM48_CAUSE_LOC_PRN_S_LU, | |
148 GSM48_CC_CAUSE_NETWORK_OOO); | |
149 return; | |
150 } | |
151 /* allocate struct call and being stateful processing */ | |
152 call = malloc(sizeof(struct call)); | |
153 if (!call) { | |
154 syslog(LOG_CRIT, "failed malloc for outbound call!"); | |
155 reject_mo_call(mncc, msg->callref, GSM48_CAUSE_LOC_PRN_S_LU, | |
156 GSM48_CC_CAUSE_RESOURCE_UNAVAIL); | |
157 return; | |
158 } | |
159 bzero(call, sizeof(struct call)); | |
160 call->mncc = mncc; | |
161 call->mncc_callref = msg->callref; | |
162 call->from_user[0] = '+'; | |
163 strcpy(call->from_user+1, msg->calling.number); | |
164 sprintf(call->to_uri, "sip:%s@%s", to_sip_user, dest->domain); | |
165 bcopy(&dest->sin, &call->udp_sin, sizeof(struct sockaddr_in)); | |
166 call->next = call_list; | |
167 call_list = call; | |
168 send_call_proceeding(call); | |
169 call->overall_state = OVERALL_STATE_GSM_RTP; | |
170 call->mncc_state = MNCC_STATE_MO_PROC; | |
171 } |