Minor fix for GSM HR codec negotiation: Add missing 'break'.
[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 // use holdMPTY to transfer call
18 #define TRANSFER_HACK
19
20 #define PAYLOAD_TYPE_GSM 3
21
22 /*
23  * DTMF stuff
24  */
25 unsigned char dtmf_samples[16][8000];
26 static int dtmf_x[4] = { 1209, 1336, 1477, 1633 };
27 static int dtmf_y[4] = { 697, 770, 852, 941 };
28
29 void generate_dtmf(void)
30 {
31         double fx, fy, sample;
32         int i, x, y;
33         unsigned char *law;
34
35         for (y = 0; y < 4; y++) {
36                 fy = 2 * 3.1415927 * ((double)dtmf_y[y]) / 8000.0;
37                 for (x = 0; x < 4; x++) {
38                         fx = 2 * 3.1415927 * ((double)dtmf_x[x]) / 8000.0;
39                         law = dtmf_samples[y << 2 | x];
40                         for (i = 0; i < 8000; i++) {
41                                 sample = sin(fy * ((double)i)) * 0.251 * 32767.0; /* -6 dB */
42                                 sample += sin(fx * ((double)i)) * 0.158 * 32767.0; /* -8 dB */
43                                 *law++ = audio_s16_to_law[(int)sample & 0xffff];
44                         }
45                 }
46         }
47 }
48
49
50 /*
51  * constructor
52  */
53 Pgsm_bs::Pgsm_bs(int type, char *portname, struct port_settings *settings, struct interface *interface) : Pgsm(type, portname, settings, interface)
54 {
55         p_g_lcr_gsm = gsm_bs;
56         p_g_dtmf = NULL;
57         p_g_dtmf_index = 0;
58
59         PDEBUG(DEBUG_GSM, "Created new GSMBSPort(%s).\n", portname);
60 }
61
62 /*
63  * destructor
64  */
65 Pgsm_bs::~Pgsm_bs()
66 {
67         PDEBUG(DEBUG_GSM, "Destroyed GSM BS process(%s).\n", p_name);
68 }
69
70 static const char *media_type2name(unsigned char media_type) {
71         switch (media_type) {
72         case MEDIA_TYPE_ULAW:
73                 return "PCMU";
74         case MEDIA_TYPE_ALAW:
75                 return "PCMA";
76         case MEDIA_TYPE_GSM:
77                 return "GSM";
78         case MEDIA_TYPE_GSM_HR:
79                 return "GSM-HR";
80         case MEDIA_TYPE_GSM_EFR:
81                 return "GSM-EFR";
82         case MEDIA_TYPE_AMR:
83                 return "AMR";
84         }
85
86         return "UKN";
87 }
88
89 /* PROCEEDING INDICATION (from MS) */
90 void Pgsm_bs::call_conf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
91 {
92         int media_types[8];
93         unsigned char payload_types[8];
94         int payloads = 0;
95
96         gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
97         if (mncc->fields & MNCC_F_CAUSE) {
98                 add_trace("cause", "coding", "%d", mncc->cause.coding);
99                 add_trace("cause", "location", "%", mncc->cause.location);
100                 add_trace("cause", "value", "%", mncc->cause.value);
101         }
102         end_trace();
103
104         SCPY(p_g_imsi, mncc->imsi);
105
106         new_state(PORT_STATE_OUT_PROCEEDING);
107
108         /* get list of offered payload types */
109         select_payload_type(mncc, payload_types, media_types, &payloads, sizeof(payload_types));
110         /* if no given payload type is supported, we must release */
111         if (!payloads) {
112                 mncc = create_mncc(MNCC_REL_REQ, callref);
113                 gsm_trace_header(p_interface_name, this, MNCC_REL_REQ, DIRECTION_OUT);
114                 mncc->fields |= MNCC_F_CAUSE;
115                 mncc->cause.coding = 3;
116                 mncc->cause.location = 1;
117                 mncc->cause.value = 65;
118                 add_trace("cause", "coding", "%d", mncc->cause.coding);
119                 add_trace("cause", "location", "%d", mncc->cause.location);
120                 add_trace("cause", "value", "%d", mncc->cause.value);
121                 add_trace("reason", NULL, "Given lchan not supported");
122                 end_trace();
123                 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
124                 new_state(PORT_STATE_RELEASE);
125                 trigger_work(&p_g_delete);
126                 return;
127         }
128
129         /* select first payload type that matches the rtp list */
130         if (p_g_rtp_bridge) {
131                 int i, j;
132
133                 for (i = 0; i < p_g_rtp_payloads; i++) {
134                         for (j = 0; j < payloads; j++) {
135                                 if (p_g_rtp_media_types[i] == media_types[j])
136                                         break;
137                         }
138                         if (j < payloads)
139                                 break;
140                 }
141                 if (i == p_g_rtp_payloads) {
142                         struct lcr_msg *message;
143
144                         /* payload offered by remote RTP is not supported */
145                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
146                         message->param.disconnectinfo.cause = 65;
147                         message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
148                         message_put(message);
149                         /* send release */
150                         mncc = create_mncc(MNCC_REL_REQ, p_g_callref);
151                         gsm_trace_header(p_interface_name, this, MNCC_REL_REQ, DIRECTION_OUT);
152                         mncc->fields |= MNCC_F_CAUSE;
153                         mncc->cause.coding = 3;
154                         mncc->cause.location = LOCATION_PRIVATE_LOCAL;
155                         mncc->cause.value = 65;
156                         add_trace("cause", "coding", "%d", mncc->cause.coding);
157                         add_trace("cause", "location", "%d", mncc->cause.location);
158                         add_trace("cause", "value", "%d", mncc->cause.value);
159                         add_trace("reason", NULL, "None of the payload types are supported by MS");
160                         end_trace();
161                         send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
162                         new_state(PORT_STATE_RELEASE);
163                         trigger_work(&p_g_delete);
164
165                         return;
166                 }
167                 modify_lchan(p_g_rtp_media_types[i]);
168                 /* use the payload type from received rtp list, not from locally generated payload types */
169                 p_g_payload_type = p_g_rtp_payload_types[i];
170         } else {
171                 /* modify to first given payload */
172                 modify_lchan(media_types[0]);
173                 p_g_payload_type = payload_types[0];
174         }
175 }
176
177 /* DTMF INDICATION */
178 void Pgsm_bs::start_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
179 {
180         struct gsm_mncc *resp;
181
182         gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
183         add_trace("keypad", NULL, "%c", mncc->keypad);
184         end_trace();
185         SPRINT(p_dialinginfo.id, "%c", mncc->keypad);
186         p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
187
188         /* send resp */
189         gsm_trace_header(p_interface_name, this, MNCC_START_DTMF_RSP, DIRECTION_OUT);
190         add_trace("keypad", NULL, "%c", mncc->keypad);
191         end_trace();
192         resp = create_mncc(MNCC_START_DTMF_RSP, p_g_callref);
193         resp->fields |= MNCC_F_KEYPAD;
194         resp->keypad = mncc->keypad;
195         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
196
197         if (p_g_rtp_bridge) {
198                 /* if two members are bridged */
199                 if (p_bridge && p_bridge->first && p_bridge->first->next && !p_bridge->first->next->next) {
200                         class Port *remote = NULL;
201
202                         /* select other member */
203                         if (p_bridge->first->port == this)
204                                 remote = p_bridge->first->next->port;
205                         if (p_bridge->first->next->port == this)
206                                 remote = p_bridge->first->port;
207
208                         if (remote) {
209                                 struct lcr_msg *message;
210
211                                 /* send dtmf information, because we bridge RTP directly */
212                                 message = message_create(0, remote->p_serial, EPOINT_TO_PORT, MESSAGE_DTMF);
213                                 message->param.dtmf = mncc->keypad;
214                                 message_put(message);
215                         }
216                 }
217         } else {
218                 /* generate DTMF tones, since we do audio forwarding inside LCR */
219                 switch (mncc->keypad) {
220                         case '1': p_g_dtmf = dtmf_samples[0]; break;
221                         case '2': p_g_dtmf = dtmf_samples[1]; break;
222                         case '3': p_g_dtmf = dtmf_samples[2]; break;
223                         case 'a':
224                         case 'A': p_g_dtmf = dtmf_samples[3]; break;
225                         case '4': p_g_dtmf = dtmf_samples[4]; break;
226                         case '5': p_g_dtmf = dtmf_samples[5]; break;
227                         case '6': p_g_dtmf = dtmf_samples[6]; break;
228                         case 'b':
229                         case 'B': p_g_dtmf = dtmf_samples[7]; break;
230                         case '7': p_g_dtmf = dtmf_samples[8]; break;
231                         case '8': p_g_dtmf = dtmf_samples[9]; break;
232                         case '9': p_g_dtmf = dtmf_samples[10]; break;
233                         case 'c':
234                         case 'C': p_g_dtmf = dtmf_samples[11]; break;
235                         case '*': p_g_dtmf = dtmf_samples[12]; break;
236                         case '0': p_g_dtmf = dtmf_samples[13]; break;
237                         case '#': p_g_dtmf = dtmf_samples[14]; break;
238                         case 'd':
239                         case 'D': p_g_dtmf = dtmf_samples[15]; break;
240                 }
241                 p_g_dtmf_index = 0;
242         }
243 }
244 void Pgsm_bs::stop_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
245 {
246         struct gsm_mncc *resp;
247
248         gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
249         add_trace("keypad", NULL, "%c", mncc->keypad);
250         end_trace();
251
252         /* send resp */
253         gsm_trace_header(p_interface_name, this, MNCC_STOP_DTMF_RSP, DIRECTION_OUT);
254         add_trace("keypad", NULL, "%c", mncc->keypad);
255         end_trace();
256         resp = create_mncc(MNCC_STOP_DTMF_RSP, p_g_callref);
257         resp->keypad = mncc->keypad;
258         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
259         
260         /* stop DTMF */
261         p_g_dtmf = NULL;
262 }
263
264 /* HOLD INDICATION */
265 void Pgsm_bs::hold_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
266 {
267         struct lcr_msg *message;
268         struct gsm_mncc *resp, *frame;
269
270         gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
271         end_trace();
272
273         /* notify the hold of call */
274         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
275         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_HOLD;
276         message->param.notifyinfo.local = 1; /* call is held by supplementary service */
277         message_put(message);
278
279         p_hold = 1;
280
281         /* acknowledge hold */
282         gsm_trace_header(p_interface_name, this, MNCC_HOLD_CNF, DIRECTION_OUT);
283         end_trace();
284         resp = create_mncc(MNCC_HOLD_CNF, p_g_callref);
285         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
286
287         /* disable audio */
288         if (p_g_tch_connected) { /* it should be true */
289                 gsm_trace_header(p_interface_name, this, MNCC_FRAME_DROP, DIRECTION_OUT);
290                 end_trace();
291                 frame = create_mncc(MNCC_FRAME_DROP, p_g_callref);
292                 send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
293                 p_g_tch_connected = 0;
294         }
295 }
296
297
298 /* RETRIEVE INDICATION */
299 void Pgsm_bs::retr_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
300 {
301         struct lcr_msg *message;
302         struct gsm_mncc *resp, *frame;
303
304         gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
305         end_trace();
306
307         /* notify the retrieve of call */
308         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_NOTIFY);
309         message->param.notifyinfo.notify = INFO_NOTIFY_REMOTE_RETRIEVAL;
310         message->param.notifyinfo.local = 1; /* call is retrieved by supplementary service */
311         message_put(message);
312
313         p_hold = 0;
314
315         /* acknowledge retr */
316         gsm_trace_header(p_interface_name, this, MNCC_RETRIEVE_CNF, DIRECTION_OUT);
317         end_trace();
318         resp = create_mncc(MNCC_RETRIEVE_CNF, p_g_callref);
319         send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
320
321         /* enable audio */
322         if (!p_g_tch_connected) { /* it should be true */
323                 gsm_trace_header(p_interface_name, this, MNCC_FRAME_RECV, DIRECTION_OUT);
324                 end_trace();
325                 frame = create_mncc(MNCC_FRAME_RECV, p_g_callref);
326                 send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
327                 p_g_tch_connected = 1;
328         }
329 }
330
331 /*
332  * select payload type by given list or GSM V1 FR 
333  * return the payload type or 0 if not given 
334  */
335
336 void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_types, int *media_types, int *payloads, int max_payloads)
337 {
338         int media_type;
339         unsigned char payload_type;
340         void *encoder, *decoder;
341
342         *payloads = 0;
343
344         gsm_trace_header(p_interface_name, this, 1 /* codec negotioation */, DIRECTION_NONE);
345         if ((mncc->fields & MNCC_F_BEARER_CAP)) {
346                 /* select preferred payload type from list */
347                 int i;
348                 unsigned char dynamic_type = 96;
349
350                 add_trace("bearer", "capa", "given by MS");
351                 for (i = 0; mncc->bearer_cap.speech_ver[i] >= 0; i++) {
352                         /* select payload type we support */
353                         switch (mncc->bearer_cap.speech_ver[i]) {
354                         case 0:
355                                 add_trace("speech", "version", "Full Rate given");
356                                 media_type = MEDIA_TYPE_GSM;
357                                 payload_type = PAYLOAD_TYPE_GSM;
358                                 encoder = p_g_fr_encoder;
359                                 decoder = p_g_fr_decoder;
360                                 break;
361                         case 2:
362                                 add_trace("speech", "version", "EFR given");
363                                 media_type = MEDIA_TYPE_GSM_EFR;
364                                 payload_type = dynamic_type++;
365                                 encoder = p_g_amr_encoder;
366                                 decoder = p_g_amr_decoder;
367                                 break;
368                         case 4:
369                                 add_trace("speech", "version", "AMR given");
370                                 media_type = MEDIA_TYPE_AMR;
371                                 payload_type = dynamic_type++;
372                                 encoder = p_g_amr_encoder;
373                                 decoder = p_g_amr_decoder;
374                                 break;
375                         case 1:
376                                 add_trace("speech", "version", "Half Rate given");
377                                 media_type = MEDIA_TYPE_GSM_HR;
378                                 payload_type = dynamic_type++;
379                                 encoder = p_g_hr_encoder;
380                                 decoder = p_g_hr_decoder;
381                                 break;
382                         case 5:
383                                 add_trace("speech", "version", "AMR Half Rate given");
384                                 media_type = MEDIA_TYPE_AMR;
385                                 payload_type = dynamic_type++;
386                                 encoder = p_g_amr_encoder;
387                                 decoder = p_g_amr_decoder;
388                                 break;
389                         default:
390                                 add_trace("speech", "version", "%d given", mncc->bearer_cap.speech_ver[i]);
391                                 media_type = 0;
392                                 payload_type = 0;
393                         }
394                         /* wen don't support it, so we check the next */
395                         if (!media_type) {
396                                 add_trace("speech", "ignored", "Not supported by LCR");
397                                 continue;
398                         }
399                         if (!p_g_rtp_bridge) {
400                                 if (!encoder || !decoder) {
401                                         add_trace("speech", "ignored", "Codec not supported");
402                                         continue;
403                                 }
404                         }
405                         if (*payloads <= max_payloads) {
406                                 media_types[*payloads] = media_type;
407                                 payload_types[*payloads] = payload_type;
408                                 (*payloads)++;
409                         }
410                 }
411         } else {
412                 add_trace("bearer", "capa", "not given by MS");
413                 add_trace("speech", "version", "Full Rate given");
414                 media_types[0] = MEDIA_TYPE_GSM;
415                 payload_types[0] = PAYLOAD_TYPE_GSM;
416                 *payloads = 1;
417         }
418         if (!(*payloads))
419                 add_trace("error", "", "All given payload types unsupported");
420         end_trace();
421 }
422
423 void gsm_trace_facility(unsigned char *fac_ie, unsigned char fac_len)
424 {
425         char debug[GSM_MAX_FACILITY * 3 + 1];
426         int i;
427
428         i = 0;
429         while(i < fac_len) {
430                 UPRINT(debug+(i*3), " %02x", fac_ie[i]);
431                 i++;
432         }
433         debug[i*3] = '\0';
434         add_trace("facility", NULL, "%s", debug[0]?debug+1:"<none>");
435 }
436
437 /* encode facility IE */
438 void Pgsm_bs::enc_ie_facility(struct gsm_mncc *mncc, int operation_code, int error_code, unsigned char invoke_id)
439 {
440         unsigned char *fac_ie, fac_len;
441
442         fac_ie = (unsigned char *)mncc->facility.info;
443
444         mncc->fields |= MNCC_F_FACILITY;
445         if (operation_code >= 0) {
446                 fac_len = 8;
447                 fac_ie[0] = 0xa2;
448                 fac_ie[1] = 6;
449                 fac_ie[2] = 0x02; /* invoke ID */
450                 fac_ie[3] = 1;
451                 fac_ie[4] = invoke_id;
452                 fac_ie[5] = 0x02; /* Operation Code */
453                 fac_ie[6] = 1;
454                 fac_ie[7] = 124; /* buildMPTY */
455                 fac_ie[7] = operation_code;
456         }
457         if (error_code >= 0) {
458                 fac_len = 8;
459                 fac_ie[0] = 0xa3;
460                 fac_ie[1] = 6;
461                 fac_ie[2] = 0x02; /* invoke ID */
462                 fac_ie[3] = 1;
463                 fac_ie[4] = invoke_id;
464                 fac_ie[5] = 0x02; /* Error Code */
465                 fac_ie[6] = 1;
466                 fac_ie[7] = error_code;
467         }
468         mncc->facility.len = fac_len;
469 }
470
471 /* send facility request */
472 void Pgsm_bs::facility_req(int operation_code, int error_code, unsigned char invoke_id)
473 {
474         struct gsm_mncc *mncc;
475
476         gsm_trace_header(p_interface_name, this, MNCC_FACILITY_REQ, DIRECTION_OUT);
477         mncc = create_mncc(MNCC_FACILITY_REQ, p_g_callref);
478
479         enc_ie_facility(mncc, operation_code, error_code, invoke_id);
480
481         gsm_trace_facility((unsigned char *)mncc->facility.info, mncc->facility.len);
482         end_trace();
483         send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
484 }
485
486 /* FACILITY INDICATION */
487 void Pgsm_bs::facility_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
488 {
489         unsigned char *fac_ie, fac_len;
490         unsigned char comp_type, comp_len, *comp_val;
491         unsigned char invoke = 0, invoke_id = 0;
492         unsigned char operation = 0, operation_code = 0;
493         struct lcr_msg *message;
494         int i;
495
496         if (mncc->fields & MNCC_F_FACILITY) {
497                 fac_ie = (unsigned char *)mncc->facility.info;
498                 fac_len = mncc->facility.len;
499
500                 gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
501                 gsm_trace_facility(fac_ie, fac_len);
502                 end_trace();
503         } else
504                 return;
505
506         /* facility */
507         if (fac_len<=2)
508                 return;
509         /* component tag */
510         if (fac_ie[1] > fac_len - 2) {
511                 PDEBUG(DEBUG_GSM, "Component Tag in facility message greater than message length\n");
512                 return;
513         }
514         comp_type = fac_ie[0];
515         comp_len = fac_ie[1];
516         comp_val = fac_ie + 2;
517         PDEBUG(DEBUG_GSM, "Component Tag type 0x%02x\n", comp_type);
518         /* tags inside component */
519         for (i = 0; i != comp_len;) {
520                 if (comp_val[1 + i] > comp_len - i - 2) {
521                         PDEBUG(DEBUG_GSM, "Tag inside Component TAG greater than Component length\n");
522                         break;
523                 }
524                 PDEBUG(DEBUG_GSM, "Tag inside Component Tag (type 0x%02x)\n", comp_val[0 + i]);
525                 if (comp_val[0 + i] == 0x02 && ! invoke) { /* Invoke ID Tag */
526                         if (comp_val[1 + i] != 1) {
527                                 PDEBUG(DEBUG_GSM, "Invoke ID Tag has invalid length\n");
528                                 break;
529                         }
530                         invoke = 1;
531                         invoke_id = comp_val[2 + i];
532                         PDEBUG(DEBUG_GSM, "Invoke ID Tag inside Component TAG with ID=%d\n", invoke_id);
533                 } else if (comp_val[0 + i] == 0x02 && !operation) { /* Operation Code Tag */
534                         if (comp_val[1 + i] != 1) {
535                                 PDEBUG(DEBUG_GSM, "Operation Code Tag has invalid length\n");
536                                 break;
537                         }
538                         operation = 1;
539                         operation_code = comp_val[2 + i];
540                         PDEBUG(DEBUG_GSM, "Operation Code Tag inside Component TAG with Code=%d\n", operation_code);
541                 } else
542                         PDEBUG(DEBUG_GSM, "Unknown Tag (0x%02x) inside Component TAG, ignoring\n", comp_val[0 + i]);
543
544                 i += comp_val[1 + i] + 2;
545         }
546
547         /* check component type */
548         switch (comp_type) {
549         case 0xa1: /* Invoke */
550                 if (!invoke) {
551                         PDEBUG(DEBUG_GSM, "error: Invoke without Invoke ID\n");
552                         break;
553                 }
554                 if (!operation) {
555                         PDEBUG(DEBUG_GSM, "error: Invoke without Operation Tag\n");
556                         break;
557                 }
558                 switch(operation_code) {
559                 case 124: /* buildMTPY */
560                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
561                         message->param.threepty.begin = 1;
562                         message->param.threepty.invoke = 1;
563                         message->param.threepty.invoke_id = invoke_id;
564                         message_put(message);
565                         return;
566
567                 case 121: /* splitMTPY */
568                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
569                         message->param.threepty.end = 1;
570                         message->param.threepty.invoke = 1;
571                         message->param.threepty.invoke_id = invoke_id;
572                         message_put(message);
573                         return;
574
575                 case 122: /* holdMTPY */
576 #ifdef TRANSFER_HACK
577                         facility_req(-1, 122, invoke_id); /* rejected by network */
578
579                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TRANSFER);
580                         message->param.transfer.invoke = 1;
581                         message->param.transfer.invoke_id = invoke_id;
582                         message_put(message);
583 #else
584                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
585                         message->param.threepty.hold = 1;
586                         message->param.threepty.invoke = 1;
587                         message->param.threepty.invoke_id = invoke_id;
588                         message_put(message);
589 #endif
590                         return;
591
592                 case 123: /* retrieveMTPY */
593 #ifdef TRANSFER_HACK
594                         facility_req(-1, 122, invoke_id); /* rejected by network */
595
596                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TRANSFER);
597                         message->param.transfer.invoke = 1;
598                         message->param.transfer.invoke_id = invoke_id;
599                         message_put(message);
600 #else
601                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_3PTY);
602                         message->param.threepty.retrieve = 1;
603                         message->param.threepty.invoke = 1;
604                         message->param.threepty.invoke_id = invoke_id;
605                         message_put(message);
606 #endif
607                         return;
608
609                 case 126: /* explicitCT */
610                         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TRANSFER);
611                         message->param.transfer.invoke = 1;
612                         message->param.transfer.invoke_id = invoke_id;
613                         message_put(message);
614                         return;
615                 default:
616                         PDEBUG(DEBUG_GSM, "error: Unsupported Operation\n");
617                         facility_req(-1, 122, invoke_id); /* rejected by network */
618                         return;
619                 }
620                 break;
621         }
622 }
623
624
625 /* MESSAGE_3PTY */
626 void Pgsm_bs::message_3pty(unsigned int epoint_id, int message_id, union parameter *param)
627 {
628         if (param->threepty.result) {
629                 if (param->threepty.begin)
630                         facility_req(124, -1, param->threepty.invoke_id); /* buildMPTY */
631                 if (param->threepty.end)
632                         facility_req(121, -1, param->threepty.invoke_id); /* splitMPTY */
633         }
634         if (param->threepty.error) {
635                 facility_req(-1, 122, param->threepty.invoke_id); /* rejected by network */
636         }
637 }
638
639 void Pgsm_bs::enc_ie_facility_ect(struct gsm_mncc *mncc, struct param_transfer *transfer)
640 {
641         if (transfer->result) {
642                 enc_ie_facility(mncc, 126, -1, transfer->invoke_id); /* explicitCT */
643         }
644         if (transfer->error) {
645                 enc_ie_facility(mncc, -1, 122, transfer->invoke_id); /* rejected by network */
646         }
647 }
648
649 /* MESSAGE_TRANSFER */
650 void Pgsm_bs::message_transfer(unsigned int epoint_id, int message_id, union parameter *param)
651 {
652 #ifdef TRANSFER_HACK
653         struct gsm_mncc *mncc;
654
655         /* sending facility */
656         gsm_trace_header(p_interface_name, this, MNCC_FACILITY_REQ, DIRECTION_OUT);
657         mncc = create_mncc(MNCC_FACILITY_REQ, p_g_callref);
658         enc_ie_facility_ect(mncc, &param->transfer);
659         gsm_trace_facility((unsigned char *)mncc->facility.info, mncc->facility.len);
660         end_trace();
661         send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
662 #endif
663 }
664
665 /*
666  * handles all indications
667  */
668 /* SETUP INDICATION */
669 void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
670 {
671         class Endpoint *epoint;
672         struct lcr_msg *message;
673         struct gsm_mncc *proceeding, *frame;
674         struct interface *interface;
675         int media_types[8];
676         unsigned char payload_types[8];
677         int payloads = 0;
678
679         interface = getinterfacebyname(p_interface_name);
680         if (!interface) {
681                 PERROR("Cannot find interface %s.\n", p_interface_name);
682                 return;
683         }
684
685         /* process given callref */
686         gsm_trace_header(p_interface_name, this, 0, DIRECTION_IN);
687         add_trace("callref", "new", "0x%x", callref);
688         if (p_g_callref) {
689                 /* release in case the ID is already in use */
690                 add_trace("error", NULL, "callref already in use");
691                 end_trace();
692                 mncc = create_mncc(MNCC_REJ_REQ, callref);
693                 gsm_trace_header(p_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT);
694                 mncc->fields |= MNCC_F_CAUSE;
695                 mncc->cause.coding = 3;
696                 mncc->cause.location = 1;
697                 mncc->cause.value = 47;
698                 add_trace("cause", "coding", "%d", mncc->cause.coding);
699                 add_trace("cause", "location", "%d", mncc->cause.location);
700                 add_trace("cause", "value", "%d", mncc->cause.value);
701                 add_trace("reason", NULL, "callref already in use");
702                 end_trace();
703                 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
704                 new_state(PORT_STATE_RELEASE);
705                 trigger_work(&p_g_delete);
706                 return;
707         }
708         p_g_callref = callref;
709         end_trace();
710
711         SCPY(p_g_imsi, mncc->imsi);
712
713         /* caller info */
714         if (mncc->clir.inv)
715                 p_callerinfo.present = INFO_PRESENT_RESTRICTED;
716         else
717                 p_callerinfo.present = INFO_PRESENT_ALLOWED;
718         if (mncc->calling.number[0])
719                 SCPY(p_callerinfo.id, mncc->calling.number);
720         else
721                 p_callerinfo.present = INFO_PRESENT_NOTAVAIL;
722         SCPY(p_callerinfo.imsi, mncc->imsi);
723         p_callerinfo.screen = INFO_SCREEN_NETWORK;
724         p_callerinfo.ntype = INFO_NTYPE_UNKNOWN;
725         SCPY(p_callerinfo.interface, p_interface_name);
726
727         /* dialing information */
728         SCAT(p_dialinginfo.id, mncc->called.number);
729         switch (mncc->called.type) {
730                 case 0x1:
731                 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
732                 break;
733                 case 0x2:
734                 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
735                 break;
736                 case 0x4:
737                 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
738                 break;
739                 default:
740                 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
741                 break;
742         }
743         if (mncc->emergency) {
744                 SCPY(p_dialinginfo.id, "emergency");
745         }
746         p_dialinginfo.sending_complete = 1;
747
748         /* bearer capability */
749         p_capainfo.bearer_capa = INFO_BC_SPEECH;
750         p_capainfo.bearer_info1 = (options.law=='a')?3:2;
751         p_capainfo.bearer_mode = INFO_BMODE_CIRCUIT;
752         p_capainfo.source_mode = B_MODE_TRANSPARENT;
753         p_g_mode = p_capainfo.source_mode;
754
755         /* get list of offered payload types */
756         select_payload_type(mncc, payload_types, media_types, &payloads, sizeof(payload_types));
757         /* if no given payload type is supported, we must release */
758         if (!payloads) {
759                 mncc = create_mncc(MNCC_REJ_REQ, callref);
760                 gsm_trace_header(p_interface_name, this, MNCC_REJ_REQ, DIRECTION_OUT);
761                 mncc->fields |= MNCC_F_CAUSE;
762                 mncc->cause.coding = 3;
763                 mncc->cause.location = 1;
764                 mncc->cause.value = 65;
765                 add_trace("cause", "coding", "%d", mncc->cause.coding);
766                 add_trace("cause", "location", "%d", mncc->cause.location);
767                 add_trace("cause", "value", "%d", mncc->cause.value);
768                 add_trace("reason", NULL, "Given lchan not supported");
769                 end_trace();
770                 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
771                 new_state(PORT_STATE_RELEASE);
772                 trigger_work(&p_g_delete);
773                 return;
774         }
775 #if 0
776         /* if no given payload type is supported, we reject the call */
777         if (!payloads) {
778         }
779 #endif
780
781         /* useruser */
782
783         /* what infos did we got ... */
784         gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
785         if (p_callerinfo.id[0])
786                 add_trace("calling", "number", "%s", p_callerinfo.id);
787         else
788                 SPRINT(p_callerinfo.id, "imsi-%s", p_callerinfo.imsi);
789         add_trace("calling", "imsi", "%s", p_callerinfo.imsi);
790         add_trace("dialing", "number", "%s", p_dialinginfo.id);
791         end_trace();
792
793         /* create endpoint */
794         if (p_epointlist)
795                 FATAL("Incoming call but already got an endpoint.\n");
796         if (!(epoint = new Endpoint(p_serial, 0)))
797                 FATAL("No memory for Endpoint instance\n");
798         epoint->ep_app = new_endpointapp(epoint, 0, interface->app); //incoming
799         epointlist_new(epoint->ep_serial);
800
801         /* modify lchan in case of no rtp bridge */
802         if (!p_g_rtp_bridge)
803                 modify_lchan(media_types[0]);
804
805         /* send call proceeding */
806         gsm_trace_header(p_interface_name, this, MNCC_CALL_PROC_REQ, DIRECTION_OUT);
807         proceeding = create_mncc(MNCC_CALL_PROC_REQ, p_g_callref);
808         if (p_g_tones) {
809                 proceeding->fields |= MNCC_F_PROGRESS;
810                 proceeding->progress.coding = 3; /* GSM */
811                 proceeding->progress.location = 1;
812                 proceeding->progress.descr = 8;
813                 add_trace("progress", "coding", "%d", proceeding->progress.coding);
814                 add_trace("progress", "location", "%d", proceeding->progress.location);
815                 add_trace("progress", "descr", "%d", proceeding->progress.descr);
816         }
817         end_trace();
818         send_and_free_mncc(p_g_lcr_gsm, proceeding->msg_type, proceeding);
819
820         new_state(PORT_STATE_IN_PROCEEDING);
821
822         if (p_g_tones && !p_g_tch_connected) { /* only if ... */
823                 gsm_trace_header(p_interface_name, this, MNCC_FRAME_RECV, DIRECTION_OUT);
824                 end_trace();
825                 frame = create_mncc(MNCC_FRAME_RECV, p_g_callref);
826                 send_and_free_mncc(p_g_lcr_gsm, frame->msg_type, frame);
827                 p_g_tch_connected = 1;
828         }
829
830         /* send setup message to endpoit */
831         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
832         message->param.setup.port_type = p_type;
833 //      message->param.setup.dtmf = 0;
834         memcpy(&message->param.setup.dialinginfo, &p_dialinginfo, sizeof(struct dialing_info));
835         memcpy(&message->param.setup.callerinfo, &p_callerinfo, sizeof(struct caller_info));
836         memcpy(&message->param.setup.capainfo, &p_capainfo, sizeof(struct capa_info));
837         SCPY((char *)message->param.setup.useruser.data, (char *)mncc->useruser.info);
838         message->param.setup.useruser.len = strlen(mncc->useruser.info);
839         message->param.setup.useruser.protocol = mncc->useruser.proto;
840         if (p_g_rtp_bridge) {
841                 struct gsm_mncc_rtp *rtp;
842                 int i;
843
844                 PDEBUG(DEBUG_GSM, "Request RTP peer info, before forwarding setup\n");
845                 p_g_setup_pending = message;
846                 rtp = (struct gsm_mncc_rtp *) create_mncc(MNCC_RTP_CREATE, p_g_callref);
847                 send_and_free_mncc(p_g_lcr_gsm, rtp->msg_type, rtp);
848
849                 for (i = 0; i < (int)sizeof(message->param.setup.rtpinfo.payload_types) && i < payloads; i++) {
850                         message->param.setup.rtpinfo.media_types[i] = media_types[i];
851                         message->param.setup.rtpinfo.payload_types[i] = payload_types[i];
852                         message->param.setup.rtpinfo.payloads++;
853                 }
854
855         } else
856                 message_put(message);
857
858 }
859
860 /*
861  * BSC sends message to port
862  */
863 int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg)
864 {
865         struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
866         unsigned int callref = mncc->callref;
867         class Port *port;
868         class Pgsm_bs *pgsm_bs = NULL;
869         char name[64];
870 //      struct mISDNport *mISDNport;
871
872         /* Special messages */
873         switch(msg_type) {
874         }
875
876         /* find callref */
877         callref = mncc->callref;
878         port = port_first;
879         while(port) {
880                 if ((port->p_type & PORT_CLASS_GSM_MASK) == PORT_CLASS_GSM_BS) {
881                         pgsm_bs = (class Pgsm_bs *)port;
882                         if (pgsm_bs->p_g_callref == callref) {
883                                 break;
884                         }
885                 }
886                 port = port->next;
887         }
888
889         if (msg_type == GSM_TCHF_FRAME
890          || msg_type == GSM_TCHF_FRAME_EFR
891          || msg_type == GSM_TCHH_FRAME
892          || msg_type == GSM_TCH_FRAME_AMR
893          || msg_type == GSM_BAD_FRAME) {
894                 if (port) {
895                         /* inject DTMF, if enabled */
896                         if (pgsm_bs->p_g_dtmf) {
897                                 unsigned char data[160];
898                                 int i;
899
900                                 for (i = 0; i < 160; i++) {
901                                         data[i] = pgsm_bs->p_g_dtmf[pgsm_bs->p_g_dtmf_index++];
902                                         if (pgsm_bs->p_g_dtmf_index == 8000)
903                                                 pgsm_bs->p_g_dtmf_index = 0;
904                                 }
905                                 /* send */
906                                 pgsm_bs->bridge_tx(data, 160);
907                         } else
908                                 pgsm_bs->frame_receive(arg);
909                         /* if we do not bridge we need to inject audio, if available */
910                         if (!pgsm_bs->p_bridge || pgsm_bs->p_tone_name[0]) {
911                                 unsigned char data[160];
912                                 int i;
913
914                                 i = pgsm_bs->read_audio(data, 160);
915                                 if (i)
916                                         pgsm_bs->audio_send(data, i);
917                         }
918                 }
919                 return 0;
920         }
921
922         if (!port) {
923                 struct interface *interface;
924
925                 if (msg_type != MNCC_SETUP_IND)
926                         return(0);
927
928                 interface = getinterfacebyname(lcr_gsm->interface_name);
929                 if (!interface) {
930                         struct gsm_mncc *rej;
931
932                         rej = create_mncc(MNCC_REJ_REQ, callref);
933                         rej->fields |= MNCC_F_CAUSE;
934                         rej->cause.coding = 3;
935                         rej->cause.location = 1;
936                         rej->cause.value = 27;
937                         gsm_trace_header(NULL, NULL, MNCC_REJ_REQ, DIRECTION_OUT);
938                         add_trace("cause", "coding", "%d", rej->cause.coding);
939                         add_trace("cause", "location", "%d", rej->cause.location);
940                         add_trace("cause", "value", "%d", rej->cause.value);
941                         add_trace("reason", NULL, "interface %s not found", lcr_gsm->interface_name);
942                         end_trace();
943                         send_and_free_mncc(lcr_gsm, rej->msg_type, rej);
944                         return 0;
945                 }
946                 /* creating port object, transparent until setup with hdlc */
947                 SPRINT(name, "%s-%d-in", interface->name, 0);
948                 if (!(pgsm_bs = new Pgsm_bs(PORT_TYPE_GSM_BS_IN, name, NULL, interface)))
949                         FATAL("Cannot create Port instance.\n");
950         }
951
952         switch(msg_type) {
953                 case MNCC_SETUP_IND:
954                 pgsm_bs->setup_ind(msg_type, callref, mncc);
955                 break;
956
957                 case MNCC_RTP_CREATE:
958                 pgsm_bs->rtp_create_ind(msg_type, callref, mncc);
959                 break;
960
961                 case MNCC_RTP_CONNECT:
962                 pgsm_bs->rtp_connect_ind(msg_type, callref, mncc);
963                 break;
964
965                 case MNCC_START_DTMF_IND:
966                 pgsm_bs->start_dtmf_ind(msg_type, callref, mncc);
967                 break;
968
969                 case MNCC_STOP_DTMF_IND:
970                 pgsm_bs->stop_dtmf_ind(msg_type, callref, mncc);
971                 break;
972
973                 case MNCC_CALL_CONF_IND:
974                 pgsm_bs->call_conf_ind(msg_type, callref, mncc);
975                 break;
976
977                 case MNCC_ALERT_IND:
978                 pgsm_bs->alert_ind(msg_type, callref, mncc);
979                 break;
980
981                 case MNCC_SETUP_CNF:
982                 pgsm_bs->setup_cnf(msg_type, callref, mncc);
983                 break;
984
985                 case MNCC_SETUP_COMPL_IND:
986                 pgsm_bs->setup_compl_ind(msg_type, callref, mncc);
987                 break;
988
989                 case MNCC_DISC_IND:
990                 pgsm_bs->disc_ind(msg_type, callref, mncc);
991                 break;
992
993                 case MNCC_REL_IND:
994                 case MNCC_REL_CNF:
995                 case MNCC_REJ_IND:
996                 pgsm_bs->rel_ind(msg_type, callref, mncc);
997                 break;
998
999                 case MNCC_NOTIFY_IND:
1000                 pgsm_bs->notify_ind(msg_type, callref, mncc);
1001                 break;
1002
1003                 case MNCC_HOLD_IND:
1004                 pgsm_bs->hold_ind(msg_type, callref, mncc);
1005                 break;
1006
1007                 case MNCC_RETRIEVE_IND:
1008                 pgsm_bs->retr_ind(msg_type, callref, mncc);
1009                 break;
1010
1011                 case MNCC_FACILITY_IND:
1012                 pgsm_bs->facility_ind(msg_type, callref, mncc);
1013                 break;
1014
1015                 default:
1016                 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);
1017         }
1018         return(0);
1019 }
1020
1021 /* MESSAGE_SETUP */
1022 void Pgsm_bs::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
1023 {
1024         struct lcr_msg *message;
1025         struct epoint_list *epointlist;
1026         struct gsm_mncc *mncc;
1027         struct interface *interface;
1028         int page_with_tchh = 0;
1029
1030         interface = getinterfacebyname(p_interface_name);
1031         if (!interface) {
1032                 PERROR("Cannot find interface %s.\n", p_interface_name);
1033                 return;
1034         }
1035
1036         /* copy setup infos to port */
1037         memcpy(&p_callerinfo, &param->setup.callerinfo, sizeof(p_callerinfo));
1038         memcpy(&p_dialinginfo, &param->setup.dialinginfo, sizeof(p_dialinginfo));
1039         memcpy(&p_capainfo, &param->setup.capainfo, sizeof(p_capainfo));
1040         memcpy(&p_redirinfo, &param->setup.redirinfo, sizeof(p_redirinfo));
1041
1042         /* no GSM MNCC connection */
1043         if (p_g_lcr_gsm->mncc_lfd.fd < 0) {
1044                 gsm_trace_header(p_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1045                 add_trace("failure", NULL, "No MNCC connection.");
1046                 end_trace();
1047                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1048                 message->param.disconnectinfo.cause = 41; // temp. failure.
1049                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1050                 message_put(message);
1051                 new_state(PORT_STATE_RELEASE);
1052                 trigger_work(&p_g_delete);
1053                 return;
1054         }
1055
1056         /* no number */
1057         if (!p_dialinginfo.id[0]) {
1058                 gsm_trace_header(p_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1059                 add_trace("failure", NULL, "No dialed subscriber given.");
1060                 end_trace();
1061                 message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1062                 message->param.disconnectinfo.cause = 28;
1063                 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1064                 message_put(message);
1065                 new_state(PORT_STATE_RELEASE);
1066                 trigger_work(&p_g_delete);
1067                 return;
1068         }
1069
1070         /* unsupported codec for RTP bridge */
1071         if (param->setup.rtpinfo.port) {
1072                 int i;
1073
1074                 p_g_rtp_payloads = 0;
1075                 gsm_trace_header(p_interface_name, this, 1 /* codec negotioation */, DIRECTION_NONE);
1076                 for (i = 0; i < param->setup.rtpinfo.payloads; i++) {
1077                         switch (param->setup.rtpinfo.media_types[i]) {
1078                         case MEDIA_TYPE_AMR:
1079                         case MEDIA_TYPE_GSM_HR:
1080                                 /* because offered codecs are compatible with half rate, we can page with tchh */
1081                                 page_with_tchh = 1;
1082                                 // Fall through!
1083                         case MEDIA_TYPE_GSM:
1084                         case MEDIA_TYPE_GSM_EFR:
1085                                 add_trace("rtp", "payload", "%s:%d supported", media_type2name(param->setup.rtpinfo.media_types[i]), param->setup.rtpinfo.payload_types[i]);
1086                                 if (p_g_rtp_payloads < (int)sizeof(p_g_rtp_payload_types)) {
1087                                         p_g_rtp_media_types[p_g_rtp_payloads] = param->setup.rtpinfo.media_types[i];
1088                                         p_g_rtp_payload_types[p_g_rtp_payloads] = param->setup.rtpinfo.payload_types[i];
1089                                         p_g_rtp_payloads++;
1090                                 }
1091                                 break;
1092                         default:
1093                                 add_trace("rtp", "payload", "%s:%d unsupported", media_type2name(param->setup.rtpinfo.media_types[i]), param->setup.rtpinfo.payload_types[i]);
1094                         }
1095                 }
1096                 end_trace();
1097                 if (!p_g_rtp_payloads) {
1098                         gsm_trace_header(p_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1099                         add_trace("failure", NULL, "No payload given that is supported by GSM");
1100                         end_trace();
1101                         message = message_create(p_serial, epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
1102                         message->param.disconnectinfo.cause = 65;
1103                         message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
1104                         message_put(message);
1105                         new_state(PORT_STATE_RELEASE);
1106                         trigger_work(&p_g_delete);
1107                         return;
1108                 }
1109         } else {
1110                 /* since we support half rate compatible codecss, we can page with tchh */
1111                 if (p_g_hr_encoder || p_g_amr_encoder)
1112                         page_with_tchh = 1;
1113         }
1114
1115 //              SCPY(&p_m_tones_dir, param->setup.ext.tones_dir);
1116         /* screen outgoing caller id */
1117         do_screen(1, p_callerinfo.id, sizeof(p_callerinfo.id), &p_callerinfo.ntype, &p_callerinfo.present, p_interface_name);
1118
1119         /* attach only if not already */
1120         epointlist = p_epointlist;
1121         while(epointlist) {
1122                 if (epointlist->epoint_id == epoint_id)
1123                         break;
1124                 epointlist = epointlist->next;
1125         }
1126         if (!epointlist)
1127                 epointlist_new(epoint_id);
1128
1129         /* creating l3id */
1130         gsm_trace_header(p_interface_name, this, 0, DIRECTION_OUT);
1131         p_g_callref = new_callref++;
1132         add_trace("callref", "new", "0x%x", p_g_callref);
1133         end_trace();
1134
1135         gsm_trace_header(p_interface_name, this, MNCC_SETUP_REQ, DIRECTION_OUT);
1136         mncc = create_mncc(MNCC_SETUP_REQ, p_g_callref);
1137         /* caller information */
1138         mncc->fields |= MNCC_F_CALLING;
1139         mncc->calling.plan = 1;
1140         switch (p_callerinfo.ntype) {
1141                 case INFO_NTYPE_UNKNOWN:
1142                 mncc->calling.type = 0x0;
1143                 break;
1144                 case INFO_NTYPE_INTERNATIONAL:
1145                 mncc->calling.type = 0x1;
1146                 break;
1147                 case INFO_NTYPE_NATIONAL:
1148                 mncc->calling.type = 0x2;
1149                 break;
1150                 case INFO_NTYPE_SUBSCRIBER:
1151                 mncc->calling.type = 0x4;
1152                 break;
1153                 default: /* INFO_NTYPE_NOTPRESENT */
1154                 mncc->fields &= ~MNCC_F_CALLING;
1155                 break;
1156         }
1157         switch (p_callerinfo.screen) {
1158                 case INFO_SCREEN_USER:
1159                 mncc->calling.screen = 0;
1160                 break;
1161                 default: /* INFO_SCREEN_NETWORK */
1162                 mncc->calling.screen = 3;
1163                 break;
1164         }
1165         switch (p_callerinfo.present) {
1166                 case INFO_PRESENT_ALLOWED:
1167                 mncc->calling.present = 0;
1168                 break;
1169                 case INFO_PRESENT_RESTRICTED:
1170                 mncc->calling.present = 1;
1171                 break;
1172                 default: /* INFO_PRESENT_NOTAVAIL */
1173                 mncc->calling.present = 2;
1174                 break;
1175         }
1176         if (mncc->fields & MNCC_F_CALLING) {
1177                 SCPY(mncc->calling.number, p_callerinfo.id);
1178                 add_trace("calling", "type", "%d", mncc->calling.type);
1179                 add_trace("calling", "plan", "%d", mncc->calling.plan);
1180                 add_trace("calling", "present", "%d", mncc->calling.present);
1181                 add_trace("calling", "screen", "%d", mncc->calling.screen);
1182                 add_trace("calling", "number", "%s", mncc->calling.number);
1183         }
1184         /* dialing information */
1185         mncc->fields |= MNCC_F_CALLED;
1186         if (!strncmp(p_dialinginfo.id, "imsi-", 5)) {
1187                 SCPY(mncc->imsi, p_dialinginfo.id+5);
1188                 add_trace("dialing", "imsi", "%s", mncc->imsi);
1189         } else {
1190                 SCPY(mncc->called.number, p_dialinginfo.id);
1191                 add_trace("dialing", "number", "%s", mncc->called.number);
1192         }
1193         
1194         /* sending user-user */
1195
1196         /* redirecting number */
1197         mncc->fields |= MNCC_F_REDIRECTING;
1198         mncc->redirecting.plan = 1;
1199         switch (p_redirinfo.ntype) {
1200                 case INFO_NTYPE_UNKNOWN:
1201                 mncc->redirecting.type = 0x0;
1202                 break;
1203                 case INFO_NTYPE_INTERNATIONAL:
1204                 mncc->redirecting.type = 0x1;
1205                 break;
1206                 case INFO_NTYPE_NATIONAL:
1207                 mncc->redirecting.type = 0x2;
1208                 break;
1209                 case INFO_NTYPE_SUBSCRIBER:
1210                 mncc->redirecting.type = 0x4;
1211                 break;
1212                 default: /* INFO_NTYPE_NOTPRESENT */
1213                 mncc->fields &= ~MNCC_F_REDIRECTING;
1214                 break;
1215         }
1216         switch (p_redirinfo.screen) {
1217                 case INFO_SCREEN_USER:
1218                 mncc->redirecting.screen = 0;
1219                 break;
1220                 default: /* INFO_SCREE_NETWORK */
1221                 mncc->redirecting.screen = 3;
1222                 break;
1223         }
1224         switch (p_redirinfo.present) {
1225                 case INFO_PRESENT_ALLOWED:
1226                 mncc->redirecting.present = 0;
1227                 break;
1228                 case INFO_PRESENT_RESTRICTED:
1229                 mncc->redirecting.present = 1;
1230                 break;
1231                 default: /* INFO_PRESENT_NOTAVAIL */
1232                 mncc->redirecting.present = 2;
1233                 break;
1234         }
1235         /* sending redirecting number only in ntmode */
1236         if (mncc->fields & MNCC_F_REDIRECTING) {
1237                 SCPY(mncc->redirecting.number, p_redirinfo.id);
1238                 add_trace("redir", "type", "%d", mncc->redirecting.type);
1239                 add_trace("redir", "plan", "%d", mncc->redirecting.plan);
1240                 add_trace("redir", "present", "%d", mncc->redirecting.present);
1241                 add_trace("redir", "screen", "%d", mncc->redirecting.screen);
1242                 add_trace("redir", "number", "%s", mncc->redirecting.number);
1243         }
1244
1245         /* if we support any half rate codec we page the mobile with TCH/H
1246          * support indication. the mobile will reply paging with a channel
1247          * request that indicates half rate support. if no SDCCH and TCH/F
1248          * channel is available, BSC can assign a TCH/H channel, because it
1249          * knows that the phone supports it. */
1250         if (page_with_tchh) {
1251                 add_trace("lchan", "type", "TCH/H or TCH/F");
1252                 mncc->lchan_type = GSM_LCHAN_TCH_H;
1253         } else {
1254                 add_trace("lchan", "type", "TCH/F");
1255                 mncc->lchan_type = GSM_LCHAN_TCH_F;
1256         }
1257
1258         end_trace();
1259         send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
1260
1261         new_state(PORT_STATE_OUT_SETUP);
1262
1263         message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1264         message_put(message);
1265
1266         /* RTP bridge */
1267         if (param->setup.rtpinfo.port) {
1268                 p_g_rtp_bridge = 1;
1269                 p_g_rtp_ip_remote = param->setup.rtpinfo.ip;
1270                 p_g_rtp_port_remote = param->setup.rtpinfo.port;
1271         } else
1272                 p_g_rtp_bridge = 0;
1273 }
1274
1275 /*
1276  * endpoint sends messages to the port
1277  */
1278 int Pgsm_bs::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1279 {
1280         if (Pgsm::message_epoint(epoint_id, message_id, param))
1281                 return(1);
1282
1283         switch(message_id) {
1284                 case MESSAGE_SETUP: /* dial-out command received from epoint */
1285                 if (p_state!=PORT_STATE_IDLE)
1286                         break;
1287                 message_setup(epoint_id, message_id, param);
1288                 break;
1289
1290                 case MESSAGE_3PTY:
1291                 message_3pty(epoint_id, message_id, param);
1292                 break;
1293
1294                 case MESSAGE_TRANSFER:
1295                 message_transfer(epoint_id, message_id, param);
1296                 break;
1297
1298                 default:
1299                 PDEBUG(DEBUG_GSM, "Pgsm_bs(%s) gsm port with (caller id %s) received unhandled nessage: %d\n", p_name, p_callerinfo.id, message_id);
1300         }
1301
1302         return(1);
1303 }
1304
1305 int gsm_bs_exit(int rc)
1306 {
1307         /* free gsm instance */
1308         if (gsm_bs) {
1309                 if (gsm_bs->mncc_lfd.fd > -1) {
1310                         close(gsm_bs->mncc_lfd.fd);
1311                         unregister_fd(&gsm_bs->mncc_lfd);
1312                 }
1313
1314                 del_timer(&gsm_bs->socket_retry);
1315                 free(gsm_bs);
1316                 gsm_bs = NULL;
1317         }
1318
1319
1320         return(rc);
1321 }
1322
1323 int gsm_bs_init(struct interface *interface)
1324 {
1325         /* create gsm instance */
1326         gsm_bs = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
1327
1328         SCPY(gsm_bs->interface_name, interface->name);
1329         gsm_bs->type = LCR_GSM_TYPE_NETWORK;
1330         gsm_bs->sun.sun_family = AF_UNIX;
1331         SCPY(gsm_bs->sun.sun_path, "/tmp/bsc_mncc");
1332
1333         memset(&gsm_bs->socket_retry, 0, sizeof(gsm_bs->socket_retry));
1334         add_timer(&gsm_bs->socket_retry, mncc_socket_retry_cb, gsm_bs, 0);
1335
1336         /* do the initial connect */
1337         mncc_socket_retry_cb(&gsm_bs->socket_retry, gsm_bs, 0);
1338
1339         generate_dtmf();
1340
1341         return 0;
1342 }