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