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