Adding negotiation of speech codecs between GSM and SIP when using rtp-bridge
[lcr.git] / gsm_bs.cpp
1 /*****************************************************************************\
2 **                                                                           **
3 ** LCR                                                                       **
4 **                                                                           **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg                                              **
7 **                                                                           **
8 ** mISDN gsm (BS mode)                                                       **
9 **                                                                           **
10 \*****************************************************************************/ 
11
12 #include "main.h"
13 #include "mncc.h"
14
15 struct lcr_gsm *gsm_bs = NULL;
16
17 #define RTP_PT_GSM_FULL 3
18 #define RTP_PT_GSM_HALF 96
19 #define RTP_PT_GSM_EFR 97
20 #define RTP_PT_GSM_AMR 98
21
22 /*
23  * DTMF stuff
24  */
25 unsigned char dtmf_samples[16][8000];
26 static int dtmf_x[4] = { 1209, 1336, 1477, 1633 };
27 static int dtmf_y[4] = { 697, 770, 852, 941 };
28
29 void generate_dtmf(void)
30 {
31         double fx, fy, sample;
32         int i, x, y;
33         unsigned char *law;
34
35         for (y = 0; y < 4; y++) {
36                 fy = 2 * 3.1415927 * ((double)dtmf_y[y]) / 8000.0;
37                 for (x = 0; x < 4; x++) {
38                         fx = 2 * 3.1415927 * ((double)dtmf_x[x]) / 8000.0;
39                         law = dtmf_samples[y << 2 | x];
40                         for (i = 0; i < 8000; i++) {
41                                 sample = sin(fy * ((double)i)) * 0.251 * 32767.0; /* -6 dB */
42                                 sample += sin(fx * ((double)i)) * 0.158 * 32767.0; /* -8 dB */
43                                 *law++ = audio_s16_to_law[(int)sample & 0xffff];
44                         }
45                 }
46         }
47 }
48
49
50 /*
51  * constructor
52  */
53 Pgsm_bs::Pgsm_bs(int type, char *portname, struct port_settings *settings, struct interface *interface) : Pgsm(type, portname, settings, interface)
54 {
55         p_g_lcr_gsm = gsm_bs;
56         p_g_dtmf = NULL;
57         p_g_dtmf_index = 0;
58
59         PDEBUG(DEBUG_GSM, "Created new GSMBSPort(%s).\n", portname);
60 }
61
62 /*
63  * destructor
64  */
65 Pgsm_bs::~Pgsm_bs()
66 {
67         PDEBUG(DEBUG_GSM, "Destroyed GSM BS process(%s).\n", p_name);
68 }
69
70 /* PROCEEDING INDICATION (from MS) */
71 void Pgsm_bs::call_conf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
72 {
73         unsigned char payload_types[8];
74         int payloads = 0;
75
76         gsm_trace_header(p_g_interface_name, this, msg_type, DIRECTION_IN);
77         if (mncc->fields & MNCC_F_CAUSE) {
78                 add_trace("cause", "coding", "%d", mncc->cause.coding);
79                 add_trace("cause", "location", "%", mncc->cause.location);
80                 add_trace("cause", "value", "%", mncc->cause.value);
81         }
82         end_trace();
83
84         new_state(PORT_STATE_OUT_PROCEEDING);
85
86         /* get list of offered payload types
87          * if list ist empty, the FR V1 is selected */
88         select_payload_type(mncc, payload_types, &payloads, sizeof(payload_types));
89         /* if no given payload type is supported, we assume  */
90         if (!payloads) {
91                 payload_types[0] = RTP_PT_GSM_FULL;
92                 payloads = 1;
93         }
94
95         /* select first payload type that matches the rtp list */
96         if (p_g_rtp_bridge) {
97                 int i, j;
98
99                 for (i = 0; i < p_g_rtp_payloads; i++) {
100                         for (j = 0; j < payloads; j++) {
101                                 if (p_g_rtp_payload_types[i] == payload_types[j])
102                                         break;
103                         }
104                         if (j < payloads)
105                                 break;
106                 }
107                 if (i == p_g_rtp_payloads) {
108                         struct lcr_msg *message;
109
110                         /* payload offered by remote RTP is not supported */
111                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
112                         message->param.disconnectinfo.cause = 65;
113                         message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
114                         message_put(message);
115                         /* send release */
116                         mncc = create_mncc(MNCC_REL_REQ, p_g_callref);
117                         gsm_trace_header(p_g_interface_name, this, MNCC_REL_REQ, DIRECTION_OUT);
118                         mncc->fields |= MNCC_F_CAUSE;
119                         mncc->cause.coding = 3;
120                         mncc->cause.location = LOCATION_PRIVATE_LOCAL;
121                         mncc->cause.value = 65;
122                         add_trace("cause", "coding", "%d", mncc->cause.coding);
123                         add_trace("cause", "location", "%d", mncc->cause.location);
124                         add_trace("cause", "value", "%d", mncc->cause.value);
125                         add_trace("reason", NULL, "None of the payload types are supported by MS");
126                         end_trace();
127                         send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
128                         new_state(PORT_STATE_RELEASE);
129                         trigger_work(&p_g_delete);
130                 }
131                 modify_lchan(p_g_rtp_payload_types[i]);
132         } else {
133                 /* modify to first given payload */
134                 modify_lchan(payload_types[0]);
135         }
136 }
137
138 /* DTMF INDICATION */
139 void Pgsm_bs::start_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
140 {
141         struct gsm_mncc *resp;
142
143         gsm_trace_header(p_g_interface_name, this, msg_type, DIRECTION_IN);
144         add_trace("keypad", NULL, "%c", mncc->keypad);
145         end_trace();
146         SPRINT(p_dialinginfo.id, "%c", mncc->keypad);
147         p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
148
149         /* send resp */
150         gsm_trace_header(p_g_interface_name, this, MNCC_START_DTMF_RSP, DIRECTION_OUT);
151         add_trace("keypad", NULL, "%c", mncc->keypad);
152         end_trace();
153         resp = create_mncc(MNCC_START_DTMF_RSP, p_g_callref);
154         resp->fields |= MNCC_F_KEYPAD;
155         resp->keypad = mncc->keypad;
156         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
157
158         if (p_g_rtp_bridge) {
159                 class Port *remote = bridge_remote();
160
161                 if (remote) {
162                         struct lcr_msg *message;
163
164                         /* send dtmf information, because we bridge RTP directly */
165                         message = message_create(0, remote->p_serial, EPOINT_TO_PORT, MESSAGE_DTMF);
166                         message->param.dtmf = mncc->keypad;
167                         message_put(message);
168                 }
169         } else {
170                 /* generate DTMF tones, since we do audio forwarding inside LCR */
171                 switch (mncc->keypad) {
172                         case '1': p_g_dtmf = dtmf_samples[0]; break;
173                         case '2': p_g_dtmf = dtmf_samples[1]; break;
174                         case '3': p_g_dtmf = dtmf_samples[2]; break;
175                         case 'a':
176                         case 'A': p_g_dtmf = dtmf_samples[3]; break;
177                         case '4': p_g_dtmf = dtmf_samples[4]; break;
178                         case '5': p_g_dtmf = dtmf_samples[5]; break;
179                         case '6': p_g_dtmf = dtmf_samples[6]; break;
180                         case 'b':
181                         case 'B': p_g_dtmf = dtmf_samples[7]; break;
182                         case '7': p_g_dtmf = dtmf_samples[8]; break;
183                         case '8': p_g_dtmf = dtmf_samples[9]; break;
184                         case '9': p_g_dtmf = dtmf_samples[10]; break;
185                         case 'c':
186                         case 'C': p_g_dtmf = dtmf_samples[11]; break;
187                         case '*': p_g_dtmf = dtmf_samples[12]; break;
188                         case '0': p_g_dtmf = dtmf_samples[13]; break;
189                         case '#': p_g_dtmf = dtmf_samples[14]; break;
190                         case 'd':
191                         case 'D': p_g_dtmf = dtmf_samples[15]; break;
192                 }
193                 p_g_dtmf_index = 0;
194         }
195 }
196 void Pgsm_bs::stop_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
197 {
198         struct gsm_mncc *resp;
199
200         gsm_trace_header(p_g_interface_name, this, msg_type, DIRECTION_IN);
201         add_trace("keypad", NULL, "%c", mncc->keypad);
202         end_trace();
203
204         /* send resp */
205         gsm_trace_header(p_g_interface_name, this, MNCC_STOP_DTMF_RSP, DIRECTION_OUT);
206         add_trace("keypad", NULL, "%c", mncc->keypad);
207         end_trace();
208         resp = create_mncc(MNCC_STOP_DTMF_RSP, p_g_callref);
209         resp->keypad = mncc->keypad;
210         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
211         
212         /* stop DTMF */
213         p_g_dtmf = NULL;
214 }
215
216 /* HOLD INDICATION */
217 void Pgsm_bs::hold_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
218 {
219         struct lcr_msg *message;
220         struct gsm_mncc *resp, *frame;
221
222         gsm_trace_header(p_g_interface_name, this, msg_type, DIRECTION_IN);
223         end_trace();
224
225         /* notify the hold of call */
226         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
227         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
228         message->param.notifyinfo.local = 1; /* call is held by supplementary service */
229         message_put(message);
230
231         /* acknowledge hold */
232         gsm_trace_header(p_g_interface_name, this, MNCC_HOLD_CNF, DIRECTION_OUT);
233         end_trace();
234         resp = create_mncc(MNCC_HOLD_CNF, p_g_callref);
235         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
236
237         /* disable audio */
238         if (p_g_tch_connected) { /* it should be true */
239                 gsm_trace_header(p_g_interface_name, this, MNCC_FRAME_DROP, DIRECTION_OUT);
240                 end_trace();
241                 frame = create_mncc(MNCC_FRAME_DROP, p_g_callref);
242                 send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
243                 p_g_tch_connected = 0;
244         }
245 }
246
247
248 /* RETRIEVE INDICATION */
249 void Pgsm_bs::retr_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
250 {
251         struct lcr_msg *message;
252         struct gsm_mncc *resp, *frame;
253
254         gsm_trace_header(p_g_interface_name, this, msg_type, DIRECTION_IN);
255         end_trace();
256
257         /* notify the retrieve of call */
258         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
259         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
260         message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
261         message_put(message);
262
263         /* acknowledge retr */
264         gsm_trace_header(p_g_interface_name, this, MNCC_RETRIEVE_CNF, DIRECTION_OUT);
265         end_trace();
266         resp = create_mncc(MNCC_RETRIEVE_CNF, p_g_callref);
267         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
268
269         /* enable audio */
270         if (!p_g_tch_connected) { /* it should be true */
271                 gsm_trace_header(p_g_interface_name, this, MNCC_FRAME_RECV, DIRECTION_OUT);
272                 end_trace();
273                 frame = create_mncc(MNCC_FRAME_RECV, p_g_callref);
274                 send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
275                 p_g_tch_connected = 1;
276         }
277 }
278
279 /*
280  * select payload type by given list or GSM V1 FR 
281  * return the payload type or 0 if not given 
282  */
283
284 void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_types, int *payloads, int max_payloads)
285 {
286         unsigned char payload_type;
287
288         *payloads = 0;
289
290         gsm_trace_header(p_g_interface_name, this, 1 /* codec negotioation */, DIRECTION_NONE);
291         if ((mncc->fields & MNCC_F_BEARER_CAP)) {
292                 /* select preferred payload type from list */
293                 int i;
294
295                 add_trace("bearer", "capa", "given by MS");
296                 for (i = 0; mncc->bearer_cap.speech_ver[i] >= 0; i++) {
297                         /* select payload type we support */
298                         switch (mncc->bearer_cap.speech_ver[i]) {
299                         case 0:
300                                 add_trace("speech", "version", "Full Rate given");
301                                 payload_type = RTP_PT_GSM_FULL;
302                                 break;
303                         case 2:
304                                 add_trace("speech", "version", "EFR given");
305                                 payload_type = RTP_PT_GSM_EFR;
306                                 break;
307                         case 4:
308                                 add_trace("speech", "version", "AMR given");
309                                 payload_type = RTP_PT_GSM_AMR;
310                                 break;
311                         case 1:
312                                 add_trace("speech", "version", "Half Rate given");
313                                 payload_type = RTP_PT_GSM_HALF;
314                                 break;
315                         default:
316                                 add_trace("speech", "version", "%d given", mncc->bearer_cap.speech_ver[i]);
317                                 payload_type = 0;
318                         }
319                         /* wen don't support it, so we check the next */
320                         if (!payload_type) {
321                                 add_trace("speech", "ignored", "Not supported by LCR");
322                                 continue;
323                         }
324                         if (!p_g_rtp_bridge) {
325                                 if (payload_type != RTP_PT_GSM_FULL) {
326                                         add_trace("speech", "ignored", "Not suitable for LCR");
327                                         continue;
328                                 }
329                         }
330                         if (*payloads <= max_payloads) {
331                                 payload_types[*payloads] = payload_type;
332                                 (*payloads)++;
333                         }
334                 }
335         } else {
336                 add_trace("bearer", "capa", "not given by MS");
337                 add_trace("speech", "version", "Full Rate given");
338                 payload_types[0] = RTP_PT_GSM_FULL;
339                 *payloads = 1;
340         }
341         if (!(*payloads))
342                 add_trace("error", "", "All given payload types unsupported");
343         end_trace();
344 }
345
346 /*
347  * handles all indications
348  */
349 /* SETUP INDICATION */
350 void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
351 {
352         class Endpoint *epoint;
353         struct lcr_msg *message;
354         struct gsm_mncc *proceeding, *frame;
355         struct interface *interface;
356         unsigned char payload_types[8];
357         int payloads = 0;
358
359         interface = getinterfacebyname(p_g_interface_name);
360         if (!interface) {
361                 PERROR("Cannot find interface %s.\n", p_g_interface_name);
362                 return;
363         }
364
365         /* process given callref */
366         gsm_trace_header(p_g_interface_name, this, 0, DIRECTION_IN);
367         add_trace("callref", "new", "0x%x", callref);
368         if (p_g_callref) {
369                 /* release in case the ID is already in use */
370                 add_trace("error", NULL, "callref already in use");
371                 end_trace();
372                 mncc = create_mncc(MNCC_REJ_REQ, callref);
373                 gsm_trace_header(p_g_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT);
374                 mncc->fields |= MNCC_F_CAUSE;
375                 mncc->cause.coding = 3;
376                 mncc->cause.location = 1;
377                 mncc->cause.value = 47;
378                 add_trace("cause", "coding", "%d", mncc->cause.coding);
379                 add_trace("cause", "location", "%d", mncc->cause.location);
380                 add_trace("cause", "value", "%d", mncc->cause.value);
381                 add_trace("reason", NULL, "callref already in use");
382                 end_trace();
383                 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
384                 new_state(PORT_STATE_RELEASE);
385                 trigger_work(&p_g_delete);
386                 return;
387         }
388         p_g_callref = callref;
389         end_trace();
390
391         /* caller info */
392         if (mncc->clir.inv)
393                 p_callerinfo.present = INFO_PRESENT_RESTRICTED;
394         else
395                 p_callerinfo.present = INFO_PRESENT_ALLOWED;
396         if (mncc->calling.number[0])
397                 SCPY(p_callerinfo.id, mncc->calling.number);
398         else
399                 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
400         SCPY(p_callerinfo.imsi, mncc->imsi);
401         p_callerinfo.screen = INFO_SCREEN_NETWORK;
402         p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
403         SCPY(p_callerinfo.interface, p_g_interface_name);
404
405         /* dialing information */
406         SCAT(p_dialinginfo.id, mncc->called.number);
407         switch (mncc->called.type) {
408                 case 0x1:
409                 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
410                 break;
411                 case 0x2:
412                 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
413                 break;
414                 case 0x4:
415                 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
416                 break;
417                 default:
418                 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
419                 break;
420         }
421         if (mncc->emergency) {
422                 SCPY(p_dialinginfo.id, "emergency");
423         }
424         p_dialinginfo.sending_complete = 1;
425
426         /* bearer capability */
427         p_capainfo.bearer_capa = INFO_BC_SPEECH;
428         p_capainfo.bearer_info1 = (options.law=='a')?3:2;
429         p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
430         p_capainfo.source_mode = B_MODE_TRANSPARENT;
431         p_g_mode = p_capainfo.source_mode;
432
433         /* get list of offered payload types
434          * if list ist empty, the FR V1 is selected */
435         select_payload_type(mncc, payload_types, &payloads, sizeof(payload_types));
436         /* if no given payload type is supported, we assume  */
437         if (!payloads) {
438                 payload_types[0] = RTP_PT_GSM_FULL;
439                 payloads = 1;
440         }
441 #if 0
442         /* if no given payload type is supported, we reject the call */
443         if (!payloads) {
444                 mncc = create_mncc(MNCC_REJ_REQ, callref);
445                 gsm_trace_header(p_g_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT);
446                 mncc->fields |= MNCC_F_CAUSE;
447                 mncc->cause.coding = 3;
448                 mncc->cause.location = 1;
449                 mncc->cause.value = 65;
450                 add_trace("cause", "coding", "%d", mncc->cause.coding);
451                 add_trace("cause", "location", "%d", mncc->cause.location);
452                 add_trace("cause", "value", "%d", mncc->cause.value);
453                 add_trace("reason", NULL, "Given speech codec(s) not supported");
454                 end_trace();
455                 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
456                 new_state(PORT_STATE_RELEASE);
457                 trigger_work(&p_g_delete);
458                 return;
459         }
460 #endif
461
462         /* useruser */
463
464         /* what infos did we got ... */
465         gsm_trace_header(p_g_interface_name, this, msg_type, DIRECTION_IN);
466         if (p_callerinfo.id[0])
467                 add_trace("calling", "number", "%s", p_callerinfo.id);
468         else
469                 SPRINT(p_callerinfo.id, "imsi-%s", p_callerinfo.imsi);
470         add_trace("calling", "imsi", "%s", p_callerinfo.imsi);
471         add_trace("dialing", "number", "%s", p_dialinginfo.id);
472         end_trace();
473
474         /* create endpoint */
475         if (p_epointlist)
476                 FATAL("Incoming call but already got an endpoint.\n");
477         if (!(epoint = new Endpoint(p_serial, 0)))
478                 FATAL("No memory for Endpoint instance\n");
479         epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming
480         epointlist_new(epoint->ep_serial);
481
482         /* modify lchan in case of no rtp bridge */
483         if (!p_g_rtp_bridge)
484                 modify_lchan(payload_types[0]);
485
486         /* send call proceeding */
487         gsm_trace_header(p_g_interface_name, this, MNCC_CALL_PROC_REQ, DIRECTION_OUT);
488         proceeding = create_mncc(MNCC_CALL_PROC_REQ, p_g_callref);
489         if (p_g_tones) {
490                 proceeding->fields |= MNCC_F_PROGRESS;
491                 proceeding->progress.coding = 3; /* GSM */
492                 proceeding->progress.location = 1;
493                 proceeding->progress.descr = 8;
494                 add_trace("progress", "coding", "%d", proceeding->progress.coding);
495                 add_trace("progress", "location", "%d", proceeding->progress.location);
496                 add_trace("progress", "descr", "%d", proceeding->progress.descr);
497         }
498         end_trace();
499         send_and_free_mncc(p_g_lcr_gsm, proceeding->msg_type, proceeding);
500
501         new_state(PORT_STATE_IN_PROCEEDING);
502
503         if (p_g_tones && !p_g_tch_connected) { /* only if ... */
504                 gsm_trace_header(p_g_interface_name, this, MNCC_FRAME_RECV, DIRECTION_OUT);
505                 end_trace();
506                 frame = create_mncc(MNCC_FRAME_RECV, p_g_callref);
507                 send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
508                 p_g_tch_connected = 1;
509         }
510
511         /* send setup message to endpoit */
512         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
513         message->param.setup.port_type = p_type;
514 //      message->param.setup.dtmf = 0;
515         memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
516         memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
517         memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
518         SCPY((char *)message->param.setup.useruser.data, (char *)mncc->useruser.info);
519         message->param.setup.useruser.len = strlen(mncc->useruser.info);
520         message->param.setup.useruser.protocol = mncc->useruser.proto;
521         if (p_g_rtp_bridge) {
522                 struct gsm_mncc_rtp *rtp;
523                 int i;
524
525                 PDEBUG(DEBUG_GSM, "Request RTP peer info, before forwarding setup\n");
526                 p_g_setup_pending = message;
527                 rtp = (struct gsm_mncc_rtp *) create_mncc(MNCC_RTP_CREATE, p_g_callref);
528                 send_and_free_mncc(p_g_lcr_gsm, rtp->msg_type, rtp);
529
530                 for (i = 0; i < (int)sizeof(message->param.setup.rtpinfo.payload_types) && i < payloads; i++) {
531                         message->param.setup.rtpinfo.payload_types[i] = payload_types[i];
532                         message->param.setup.rtpinfo.payloads++;
533                 }
534
535         } else
536                 message_put(message);
537
538 }
539
540 /*
541  * BSC sends message to port
542  */
543 int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg)
544 {
545         struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
546         unsigned int callref = mncc->callref;
547         class Port *port;
548         class Pgsm_bs *pgsm_bs = NULL;
549         char name[64];
550 //      struct mISDNport *mISDNport;
551
552         /* Special messages */
553         switch(msg_type) {
554         }
555
556         /* find callref */
557         callref = mncc->callref;
558         port = port_first;
559         while(port) {
560                 if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_BS) {
561                         pgsm_bs = (class Pgsm_bs *)port;
562                         if (pgsm_bs->p_g_callref == callref) {
563                                 break;
564                         }
565                 }
566                 port = port->next;
567         }
568
569         if (msg_type == GSM_TCHF_FRAME
570          || msg_type == GSM_TCHF_BAD_FRAME) {
571                 if (port) {
572                         /* inject DTMF, if enabled */
573                         if (pgsm_bs->p_g_dtmf) {
574                                 unsigned char data[160];
575                                 int i;
576
577                                 for (i = 0; i < 160; i++) {
578                                         data[i] = pgsm_bs->p_g_dtmf[pgsm_bs->p_g_dtmf_index++];
579                                         if (pgsm_bs->p_g_dtmf_index == 8000)
580                                                 pgsm_bs->p_g_dtmf_index = 0;
581                                 }
582                                 /* send */
583                                 pgsm_bs->bridge_tx(data, 160);
584                         } else
585                                 pgsm_bs->frame_receive(arg);
586                         /* if we do not bridge we need to inject audio, if available */
587                         if (!pgsm_bs->p_bridge || pgsm_bs->p_tone_name[0]) {
588                                 unsigned char data[160];
589                                 int i;
590
591                                 i = pgsm_bs->read_audio(data, 160);
592                                 if (i)
593                                         pgsm_bs->audio_send(data, i);
594                         }
595                 }
596                 return 0;
597         }
598
599         if (!port) {
600                 struct interface *interface;
601
602                 if (msg_type != MNCC_SETUP_IND)
603                         return(0);
604
605                 interface = getinterfacebyname(lcr_gsm->interface_name);
606                 if (!interface) {
607                         struct gsm_mncc *rej;
608
609                         rej = create_mncc(MNCC_REJ_REQ, callref);
610                         rej->fields |= MNCC_F_CAUSE;
611                         rej->cause.coding = 3;
612                         rej->cause.location = 1;
613                         rej->cause.value = 27;
614                         gsm_trace_header(NULL, NULL, MNCC_REJ_REQ, DIRECTION_OUT);
615                         add_trace("cause", "coding", "%d", rej->cause.coding);
616                         add_trace("cause", "location", "%d", rej->cause.location);
617                         add_trace("cause", "value", "%d", rej->cause.value);
618                         add_trace("reason", NULL, "interface %s not found", lcr_gsm->interface_name);
619                         end_trace();
620                         send_and_free_mncc(lcr_gsm, rej->msg_type, rej);
621                         return 0;
622                 }
623                 /* creating port object, transparent until setup with hdlc */
624                 SPRINT(name, "%s-%d-in", interface->name, 0);
625                 if (!(pgsm_bs = new Pgsm_bs(PORT_TYPE_GSM_BS_IN, name, NULL, interface)))
626                         FATAL("Cannot create Port instance.\n");
627         }
628
629         switch(msg_type) {
630                 case MNCC_SETUP_IND:
631                 pgsm_bs->setup_ind(msg_type, callref, mncc);
632                 break;
633
634                 case MNCC_RTP_CREATE:
635                 pgsm_bs->rtp_create_ind(msg_type, callref, mncc);
636                 break;
637
638                 case MNCC_RTP_CONNECT:
639                 pgsm_bs->rtp_connect_ind(msg_type, callref, mncc);
640                 break;
641
642                 case MNCC_START_DTMF_IND:
643                 pgsm_bs->start_dtmf_ind(msg_type, callref, mncc);
644                 break;
645
646                 case MNCC_STOP_DTMF_IND:
647                 pgsm_bs->stop_dtmf_ind(msg_type, callref, mncc);
648                 break;
649
650                 case MNCC_CALL_CONF_IND:
651                 pgsm_bs->call_conf_ind(msg_type, callref, mncc);
652                 break;
653
654                 case MNCC_ALERT_IND:
655                 pgsm_bs->alert_ind(msg_type, callref, mncc);
656                 break;
657
658                 case MNCC_SETUP_CNF:
659                 pgsm_bs->setup_cnf(msg_type, callref, mncc);
660                 break;
661
662                 case MNCC_SETUP_COMPL_IND:
663                 pgsm_bs->setup_compl_ind(msg_type, callref, mncc);
664                 break;
665
666                 case MNCC_DISC_IND:
667                 pgsm_bs->disc_ind(msg_type, callref, mncc);
668                 break;
669
670                 case MNCC_REL_IND:
671                 case MNCC_REL_CNF:
672                 case MNCC_REJ_IND:
673                 pgsm_bs->rel_ind(msg_type, callref, mncc);
674                 break;
675
676                 case MNCC_NOTIFY_IND:
677                 pgsm_bs->notify_ind(msg_type, callref, mncc);
678                 break;
679
680                 case MNCC_HOLD_IND:
681                 pgsm_bs->hold_ind(msg_type, callref, mncc);
682                 break;
683
684                 case MNCC_RETRIEVE_IND:
685                 pgsm_bs->retr_ind(msg_type, callref, mncc);
686                 break;
687
688                 default:
689                 PDEBUG(DEBUG_GSM, "Pgsm_bs(%s) gsm port with (caller id %s) received unhandled nessage: 0x%x\n", pgsm_bs->p_name, pgsm_bs->p_callerinfo.id, msg_type);
690         }
691         return(0);
692 }
693
694 /* MESSAGE_SETUP */
695 void Pgsm_bs::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
696 {
697         struct lcr_msg *message;
698         struct epoint_list *epointlist;
699         struct gsm_mncc *mncc;
700
701         /* copy setup infos to port */
702         memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
703         memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
704         memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
705         memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
706
707         /* no GSM MNCC connection */
708         if (p_g_lcr_gsm->mncc_lfd.fd < 0) {
709                 gsm_trace_header(p_g_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
710                 add_trace("failure", NULL, "No MNCC connection.");
711                 end_trace();
712                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
713                 message->param.disconnectinfo.cause = 41; // temp. failure.
714                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
715                 message_put(message);
716                 new_state(PORT_STATE_RELEASE);
717                 trigger_work(&p_g_delete);
718                 return;
719         }
720
721         /* no number */
722         if (!p_dialinginfo.id[0]) {
723                 gsm_trace_header(p_g_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
724                 add_trace("failure", NULL, "No dialed subscriber given.");
725                 end_trace();
726                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
727                 message->param.disconnectinfo.cause = 28;
728                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
729                 message_put(message);
730                 new_state(PORT_STATE_RELEASE);
731                 trigger_work(&p_g_delete);
732                 return;
733         }
734
735         /* unsupported codec for RTP bridge */
736         if (param->setup.rtpinfo.port) {
737                 int i;
738
739                 p_g_rtp_payloads = 0;
740                 gsm_trace_header(p_g_interface_name, this, 1 /* codec negotioation */, DIRECTION_NONE);
741                 for (i = 0; i < param->setup.rtpinfo.payloads; i++) {
742                         switch (param->setup.rtpinfo.payload_types[i]) {
743                         case RTP_PT_GSM_FULL:
744                         case RTP_PT_GSM_EFR:
745                         case RTP_PT_GSM_AMR:
746                         case RTP_PT_GSM_HALF:
747                                 add_trace("rtp", "payload", "%d supported", param->setup.rtpinfo.payload_types[i]);
748                                 if (p_g_rtp_payloads < (int)sizeof(p_g_rtp_payload_types)) {
749                                         p_g_rtp_payload_types[p_g_rtp_payloads++] = param->setup.rtpinfo.payload_types[i];
750                                         p_g_rtp_payloads++;
751                                 }
752                                 break;
753                         default:
754                                 add_trace("rtp", "payload", "%d unsupported", param->setup.rtpinfo.payload_types[i]);
755                         }
756                 }
757                 end_trace();
758                 if (!p_g_rtp_payloads) {
759                         gsm_trace_header(p_g_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
760                         add_trace("failure", NULL, "No payload given that is supported by GSM");
761                         end_trace();
762                         message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
763                         message->param.disconnectinfo.cause = 65;
764                         message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
765                         message_put(message);
766                         new_state(PORT_STATE_RELEASE);
767                         trigger_work(&p_g_delete);
768                         return;
769                 }
770         }
771
772 //              SCPY(&p_m_tones_dir, param->setup.ext.tones_dir);
773         /* screen outgoing caller id */
774         do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_g_interface_name);
775
776         /* attach only if not already */
777         epointlist = p_epointlist;
778         while(epointlist) {
779                 if (epointlist->epoint_id == epoint_id)
780                         break;
781                 epointlist = epointlist->next;
782         }
783         if (!epointlist)
784                 epointlist_new(epoint_id);
785
786         /* creating l3id */
787         gsm_trace_header(p_g_interface_name, this, 0, DIRECTION_OUT);
788         p_g_callref = new_callref++;
789         add_trace("callref", "new", "0x%x", p_g_callref);
790         end_trace();
791
792         gsm_trace_header(p_g_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
793         mncc = create_mncc(MNCC_SETUP_REQ, p_g_callref);
794         /* caller information */
795         mncc->fields |= MNCC_F_CALLING;
796         mncc->calling.plan = 1;
797         switch (p_callerinfo.ntype) {
798                 case INFO_NTYPE_UNKNOWN:
799                 mncc->calling.type = 0x0;
800                 break;
801                 case INFO_NTYPE_INTERNATIONAL:
802                 mncc->calling.type = 0x1;
803                 break;
804                 case INFO_NTYPE_NATIONAL:
805                 mncc->calling.type = 0x2;
806                 break;
807                 case INFO_NTYPE_SUBSCRIBER:
808                 mncc->calling.type = 0x4;
809                 break;
810                 default: /* INFO_NTYPE_NOTPRESENT */
811                 mncc->fields &= ~MNCC_F_CALLING;
812                 break;
813         }
814         switch (p_callerinfo.screen) {
815                 case INFO_SCREEN_USER:
816                 mncc->calling.screen = 0;
817                 break;
818                 default: /* INFO_SCREEN_NETWORK */
819                 mncc->calling.screen = 3;
820                 break;
821         }
822         switch (p_callerinfo.present) {
823                 case INFO_PRESENT_ALLOWED:
824                 mncc->calling.present = 0;
825                 break;
826                 case INFO_PRESENT_RESTRICTED:
827                 mncc->calling.present = 1;
828                 break;
829                 default: /* INFO_PRESENT_NOTAVAIL */
830                 mncc->calling.present = 2;
831                 break;
832         }
833         if (mncc->fields & MNCC_F_CALLING) {
834                 SCPY(mncc->calling.number, p_callerinfo.id);
835                 add_trace("calling", "type", "%d", mncc->calling.type);
836                 add_trace("calling", "plan", "%d", mncc->calling.plan);
837                 add_trace("calling", "present", "%d", mncc->calling.present);
838                 add_trace("calling", "screen", "%d", mncc->calling.screen);
839                 add_trace("calling", "number", "%s", mncc->calling.number);
840         }
841         /* dialing information */
842         mncc->fields |= MNCC_F_CALLED;
843         if (!strncmp(p_dialinginfo.id, "imsi-", 5)) {
844                 SCPY(mncc->imsi, p_dialinginfo.id+5);
845                 add_trace("dialing", "imsi", "%s", mncc->imsi);
846         } else {
847                 SCPY(mncc->called.number, p_dialinginfo.id);
848                 add_trace("dialing", "number", "%s", mncc->called.number);
849         }
850         
851         /* sending user-user */
852
853         /* redirecting number */
854         mncc->fields |= MNCC_F_REDIRECTING;
855         mncc->redirecting.plan = 1;
856         switch (p_redirinfo.ntype) {
857                 case INFO_NTYPE_UNKNOWN:
858                 mncc->redirecting.type = 0x0;
859                 break;
860                 case INFO_NTYPE_INTERNATIONAL:
861                 mncc->redirecting.type = 0x1;
862                 break;
863                 case INFO_NTYPE_NATIONAL:
864                 mncc->redirecting.type = 0x2;
865                 break;
866                 case INFO_NTYPE_SUBSCRIBER:
867                 mncc->redirecting.type = 0x4;
868                 break;
869                 default: /* INFO_NTYPE_NOTPRESENT */
870                 mncc->fields &= ~MNCC_F_REDIRECTING;
871                 break;
872         }
873         switch (p_redirinfo.screen) {
874                 case INFO_SCREEN_USER:
875                 mncc->redirecting.screen = 0;
876                 break;
877                 default: /* INFO_SCREE_NETWORK */
878                 mncc->redirecting.screen = 3;
879                 break;
880         }
881         switch (p_redirinfo.present) {
882                 case INFO_PRESENT_ALLOWED:
883                 mncc->redirecting.present = 0;
884                 break;
885                 case INFO_PRESENT_RESTRICTED:
886                 mncc->redirecting.present = 1;
887                 break;
888                 default: /* INFO_PRESENT_NOTAVAIL */
889                 mncc->redirecting.present = 2;
890                 break;
891         }
892         /* sending redirecting number only in ntmode */
893         if (mncc->fields & MNCC_F_REDIRECTING) {
894                 SCPY(mncc->redirecting.number, p_redirinfo.id);
895                 add_trace("redir", "type", "%d", mncc->redirecting.type);
896                 add_trace("redir", "plan", "%d", mncc->redirecting.plan);
897                 add_trace("redir", "present", "%d", mncc->redirecting.present);
898                 add_trace("redir", "screen", "%d", mncc->redirecting.screen);
899                 add_trace("redir", "number", "%s", mncc->redirecting.number);
900         }
901
902         end_trace();
903         send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
904
905         new_state(PORT_STATE_OUT_SETUP);
906
907         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
908         message_put(message);
909
910         /* RTP bridge */
911         if (param->setup.rtpinfo.port) {
912                 p_g_rtp_bridge = 1;
913                 p_g_rtp_ip_remote = param->setup.rtpinfo.ip;
914                 p_g_rtp_port_remote = param->setup.rtpinfo.port;
915         } else
916                 p_g_rtp_bridge = 0;
917 }
918
919 /*
920  * endpoint sends messages to the port
921  */
922 int Pgsm_bs::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
923 {
924         if (Pgsm::message_epoint(epoint_id, message_id, param))
925                 return(1);
926
927         switch(message_id) {
928                 case MESSAGE_SETUP: /* dial-out command received from epoint */
929                 if (p_state!=PORT_STATE_IDLE)
930                         break;
931                 message_setup(epoint_id, message_id, param);
932                 break;
933
934                 default:
935                 PDEBUG(DEBUG_GSM, "Pgsm_bs(%s) gsm port with (caller id %s) received unhandled nessage: %d\n", p_name, p_callerinfo.id, message_id);
936         }
937
938         return(1);
939 }
940
941 int gsm_bs_exit(int rc)
942 {
943         /* free gsm instance */
944         if (gsm_bs) {
945                 if (gsm_bs->mncc_lfd.fd > -1) {
946                         close(gsm_bs->mncc_lfd.fd);
947                         unregister_fd(&gsm_bs->mncc_lfd);
948                 }
949
950                 del_timer(&gsm_bs->socket_retry);
951                 free(gsm_bs);
952                 gsm_bs = NULL;
953         }
954
955
956         return(rc);
957 }
958
959 int gsm_bs_init(struct interface *interface)
960 {
961         /* create gsm instance */
962         gsm_bs = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
963
964         SCPY(gsm_bs->interface_name, interface->name);
965         gsm_bs->type = LCR_GSM_TYPE_NETWORK;
966         gsm_bs->sun.sun_family = AF_UNIX;
967         SCPY(gsm_bs->sun.sun_path, "/tmp/bsc_mncc");
968
969         memset(&gsm_bs->socket_retry, 0, sizeof(gsm_bs->socket_retry));
970         add_timer(&gsm_bs->socket_retry, mncc_socket_retry_cb, gsm_bs, 0);
971
972         /* do the initial connect */
973         mncc_socket_retry_cb(&gsm_bs->socket_retry, gsm_bs, 0);
974
975         generate_dtmf();
976
977         return 0;
978 }