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