1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN gsm (BS mode) **
10 \*****************************************************************************/
15 struct lcr_gsm *gsm_bs = NULL;
17 // use holdMPTY to transfer call
20 #define PAYLOAD_TYPE_GSM 3
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 };
29 void generate_dtmf(void)
31 double fx, fy, sample;
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];
53 Pgsm_bs::Pgsm_bs(int type, char *portname, struct port_settings *settings, struct interface *interface) : Pgsm(type, portname, settings, interface)
59 PDEBUG(DEBUG_GSM, "Created new GSMBSPort(%s).\n", portname);
67 PDEBUG(DEBUG_GSM, "Destroyed GSM BS process(%s).\n", p_name);
70 static const char *media_type2name(unsigned char media_type) {
78 case MEDIA_TYPE_GSM_HR:
80 case MEDIA_TYPE_GSM_EFR:
89 /* PROCEEDING INDICATION (from MS) */
90 void Pgsm_bs::call_conf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
93 unsigned char payload_types[8];
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);
104 SCPY(p_g_imsi, mncc->imsi);
106 new_state(PORT_STATE_OUT_PROCEEDING);
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 */
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");
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);
129 /* select first payload type that matches the rtp list */
130 if (p_g_rtp_bridge) {
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])
141 if (i == p_g_rtp_payloads) {
142 struct lcr_msg *message;
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);
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");
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);
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];
171 /* modify to first given payload */
172 modify_lchan(media_types[0]);
173 p_g_payload_type = payload_types[0];
177 /* DTMF INDICATION */
178 void Pgsm_bs::start_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
180 struct gsm_mncc *resp;
182 gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
183 add_trace("keypad", NULL, "%c", mncc->keypad);
185 SPRINT(p_dialinginfo.id, "%c", mncc->keypad);
186 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
189 gsm_trace_header(p_interface_name, this, MNCC_START_DTMF_RSP, DIRECTION_OUT);
190 add_trace("keypad", NULL, "%c", mncc->keypad);
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);
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;
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;
209 struct lcr_msg *message;
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);
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;
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;
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;
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;
239 case 'D': p_g_dtmf = dtmf_samples[15]; break;
244 void Pgsm_bs::stop_dtmf_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
246 struct gsm_mncc *resp;
248 gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
249 add_trace("keypad", NULL, "%c", mncc->keypad);
253 gsm_trace_header(p_interface_name, this, MNCC_STOP_DTMF_RSP, DIRECTION_OUT);
254 add_trace("keypad", NULL, "%c", mncc->keypad);
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);
264 /* HOLD INDICATION */
265 void Pgsm_bs::hold_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
267 struct lcr_msg *message;
268 struct gsm_mncc *resp, *frame;
270 gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
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);
281 /* acknowledge hold */
282 gsm_trace_header(p_interface_name, this, MNCC_HOLD_CNF, DIRECTION_OUT);
284 resp = create_mncc(MNCC_HOLD_CNF, p_g_callref);
285 send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
288 if (p_g_tch_connected) { /* it should be true */
289 gsm_trace_header(p_interface_name, this, MNCC_FRAME_DROP, DIRECTION_OUT);
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;
298 /* RETRIEVE INDICATION */
299 void Pgsm_bs::retr_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
301 struct lcr_msg *message;
302 struct gsm_mncc *resp, *frame;
304 gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
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);
315 /* acknowledge retr */
316 gsm_trace_header(p_interface_name, this, MNCC_RETRIEVE_CNF, DIRECTION_OUT);
318 resp = create_mncc(MNCC_RETRIEVE_CNF, p_g_callref);
319 send_and_free_mncc(p_g_lcr_gsm, resp->msg_type, resp);
322 if (!p_g_tch_connected) { /* it should be true */
323 gsm_trace_header(p_interface_name, this, MNCC_FRAME_RECV, DIRECTION_OUT);
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;
332 * select payload type by given list or GSM V1 FR
333 * return the payload type or 0 if not given
336 void Pgsm_bs::select_payload_type(struct gsm_mncc *mncc, unsigned char *payload_types, int *media_types, int *payloads, int max_payloads)
339 unsigned char payload_type;
340 void *encoder, *decoder;
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 */
348 unsigned char dynamic_type = 96;
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]) {
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;
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;
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;
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;
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;
390 add_trace("speech", "version", "%d given", mncc->bearer_cap.speech_ver[i]);
394 /* wen don't support it, so we check the next */
396 add_trace("speech", "ignored", "Not supported by LCR");
399 if (!p_g_rtp_bridge) {
400 if (!encoder || !decoder) {
401 add_trace("speech", "ignored", "Codec not supported");
405 if (*payloads <= max_payloads) {
406 media_types[*payloads] = media_type;
407 payload_types[*payloads] = payload_type;
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;
419 add_trace("error", "", "All given payload types unsupported");
423 void gsm_trace_facility(unsigned char *fac_ie, unsigned char fac_len)
425 char debug[GSM_MAX_FACILITY * 3 + 1];
430 UPRINT(debug+(i*3), " %02x", fac_ie[i]);
434 add_trace("facility", NULL, "%s", debug[0]?debug+1:"<none>");
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)
440 unsigned char *fac_ie, fac_len;
442 fac_ie = (unsigned char *)mncc->facility.info;
444 mncc->fields |= MNCC_F_FACILITY;
445 if (operation_code >= 0) {
449 fac_ie[2] = 0x02; /* invoke ID */
451 fac_ie[4] = invoke_id;
452 fac_ie[5] = 0x02; /* Operation Code */
454 fac_ie[7] = 124; /* buildMPTY */
455 fac_ie[7] = operation_code;
457 if (error_code >= 0) {
461 fac_ie[2] = 0x02; /* invoke ID */
463 fac_ie[4] = invoke_id;
464 fac_ie[5] = 0x02; /* Error Code */
466 fac_ie[7] = error_code;
468 mncc->facility.len = fac_len;
471 /* send facility request */
472 void Pgsm_bs::facility_req(int operation_code, int error_code, unsigned char invoke_id)
474 struct gsm_mncc *mncc;
476 gsm_trace_header(p_interface_name, this, MNCC_FACILITY_REQ, DIRECTION_OUT);
477 mncc = create_mncc(MNCC_FACILITY_REQ, p_g_callref);
479 enc_ie_facility(mncc, operation_code, error_code, invoke_id);
481 gsm_trace_facility((unsigned char *)mncc->facility.info, mncc->facility.len);
483 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
486 /* FACILITY INDICATION */
487 void Pgsm_bs::facility_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
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;
496 if (mncc->fields & MNCC_F_FACILITY) {
497 fac_ie = (unsigned char *)mncc->facility.info;
498 fac_len = mncc->facility.len;
500 gsm_trace_header(p_interface_name, this, msg_type, DIRECTION_IN);
501 gsm_trace_facility(fac_ie, fac_len);
510 if (fac_ie[1] > fac_len - 2) {
511 PDEBUG(DEBUG_GSM, "Component Tag in facility message greater than message length\n");
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");
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");
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");
539 operation_code = comp_val[2 + i];
540 PDEBUG(DEBUG_GSM, "Operation Code Tag inside Component TAG with Code=%d\n", operation_code);
542 PDEBUG(DEBUG_GSM, "Unknown Tag (0x%02x) inside Component TAG, ignoring\n", comp_val[0 + i]);
544 i += comp_val[1 + i] + 2;
547 /* check component type */
549 case 0xa1: /* Invoke */
551 PDEBUG(DEBUG_GSM, "error: Invoke without Invoke ID\n");
555 PDEBUG(DEBUG_GSM, "error: Invoke without Operation Tag\n");
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);
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);
575 case 122: /* holdMTPY */
577 facility_req(-1, 122, invoke_id); /* rejected by network */
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);
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);
592 case 123: /* retrieveMTPY */
594 facility_req(-1, 122, invoke_id); /* rejected by network */
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);
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);
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);
616 PDEBUG(DEBUG_GSM, "error: Unsupported Operation\n");
617 facility_req(-1, 122, invoke_id); /* rejected by network */
626 void Pgsm_bs::message_3pty(unsigned int epoint_id, int message_id, union parameter *param)
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 */
634 if (param->threepty.error) {
635 facility_req(-1, 122, param->threepty.invoke_id); /* rejected by network */
639 void Pgsm_bs::enc_ie_facility_ect(struct gsm_mncc *mncc, struct param_transfer *transfer)
641 if (transfer->result) {
642 enc_ie_facility(mncc, 126, -1, transfer->invoke_id); /* explicitCT */
644 if (transfer->error) {
645 enc_ie_facility(mncc, -1, 122, transfer->invoke_id); /* rejected by network */
649 /* MESSAGE_TRANSFER */
650 void Pgsm_bs::message_transfer(unsigned int epoint_id, int message_id, union parameter *param)
653 struct gsm_mncc *mncc;
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, ¶m->transfer);
659 gsm_trace_facility((unsigned char *)mncc->facility.info, mncc->facility.len);
661 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
666 * handles all indications
668 /* SETUP INDICATION */
669 void Pgsm_bs::setup_ind(unsigned int msg_type, unsigned int callref, struct gsm_mncc *mncc)
671 class Endpoint *epoint;
672 struct lcr_msg *message;
673 struct gsm_mncc *proceeding, *frame;
674 struct interface *interface;
676 unsigned char payload_types[8];
679 interface = getinterfacebyname(p_interface_name);
681 PERROR("Cannot find interface %s.\n", p_interface_name);
685 /* process given callref */
686 gsm_trace_header(p_interface_name, this, 0, DIRECTION_IN);
687 add_trace("callref", "new", "0x%x", callref);
689 /* release in case the ID is already in use */
690 add_trace("error", NULL, "callref already in use");
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");
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);
708 p_g_callref = callref;
711 SCPY(p_g_imsi, mncc->imsi);
715 p_callerinfo.present = INFO_PRESENT_RESTRICTED;
717 p_callerinfo.present = INFO_PRESENT_ALLOWED;
718 if (mncc->calling.number[0])
719 SCPY(p_callerinfo.id, mncc->calling.number);
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);
727 /* dialing information */
728 SCAT(p_dialinginfo.id, mncc->called.number);
729 switch (mncc->called.type) {
731 p_dialinginfo.ntype = INFO_NTYPE_INTERNATIONAL;
734 p_dialinginfo.ntype = INFO_NTYPE_NATIONAL;
737 p_dialinginfo.ntype = INFO_NTYPE_SUBSCRIBER;
740 p_dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
743 if (mncc->emergency) {
744 SCPY(p_dialinginfo.id, "emergency");
746 p_dialinginfo.sending_complete = 1;
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;
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 */
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");
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);
776 /* if no given payload type is supported, we reject the call */
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);
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);
793 /* create endpoint */
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);
801 /* modify lchan in case of no rtp bridge */
803 modify_lchan(media_types[0]);
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);
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);
818 send_and_free_mncc(p_g_lcr_gsm, proceeding->msg_type, proceeding);
820 new_state(PORT_STATE_IN_PROCEEDING);
822 if (p_g_tones && !p_g_tch_connected) { /* only if ... */
823 gsm_trace_header(p_interface_name, this, MNCC_FRAME_RECV, DIRECTION_OUT);
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;
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;
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);
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++;
856 message_put(message);
861 * BSC sends message to port
863 int message_bsc(struct lcr_gsm *lcr_gsm, int msg_type, void *arg)
865 struct gsm_mncc *mncc = (struct gsm_mncc *)arg;
866 unsigned int callref = mncc->callref;
868 class Pgsm_bs *pgsm_bs = NULL;
870 // struct mISDNport *mISDNport;
872 /* Special messages */
877 callref = mncc->callref;
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) {
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) {
895 /* inject DTMF, if enabled */
896 if (pgsm_bs->p_g_dtmf) {
897 unsigned char data[160];
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;
906 pgsm_bs->bridge_tx(data, 160);
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];
914 i = pgsm_bs->read_audio(data, 160);
916 pgsm_bs->audio_send(data, i);
923 struct interface *interface;
925 if (msg_type != MNCC_SETUP_IND)
928 interface = getinterfacebyname(lcr_gsm->interface_name);
930 struct gsm_mncc *rej;
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);
943 send_and_free_mncc(lcr_gsm, rej->msg_type, rej);
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");
954 pgsm_bs->setup_ind(msg_type, callref, mncc);
957 case MNCC_RTP_CREATE:
958 pgsm_bs->rtp_create_ind(msg_type, callref, mncc);
961 case MNCC_RTP_CONNECT:
962 pgsm_bs->rtp_connect_ind(msg_type, callref, mncc);
965 case MNCC_START_DTMF_IND:
966 pgsm_bs->start_dtmf_ind(msg_type, callref, mncc);
969 case MNCC_STOP_DTMF_IND:
970 pgsm_bs->stop_dtmf_ind(msg_type, callref, mncc);
973 case MNCC_CALL_CONF_IND:
974 pgsm_bs->call_conf_ind(msg_type, callref, mncc);
978 pgsm_bs->alert_ind(msg_type, callref, mncc);
982 pgsm_bs->setup_cnf(msg_type, callref, mncc);
985 case MNCC_SETUP_COMPL_IND:
986 pgsm_bs->setup_compl_ind(msg_type, callref, mncc);
990 pgsm_bs->disc_ind(msg_type, callref, mncc);
996 pgsm_bs->rel_ind(msg_type, callref, mncc);
999 case MNCC_NOTIFY_IND:
1000 pgsm_bs->notify_ind(msg_type, callref, mncc);
1004 pgsm_bs->hold_ind(msg_type, callref, mncc);
1007 case MNCC_RETRIEVE_IND:
1008 pgsm_bs->retr_ind(msg_type, callref, mncc);
1011 case MNCC_FACILITY_IND:
1012 pgsm_bs->facility_ind(msg_type, callref, mncc);
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);
1022 void Pgsm_bs::message_setup(unsigned int epoint_id, int message_id, union parameter *param)
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;
1030 interface = getinterfacebyname(p_interface_name);
1032 PERROR("Cannot find interface %s.\n", p_interface_name);
1036 /* copy setup infos to port */
1037 memcpy(&p_callerinfo, ¶m->setup.callerinfo, sizeof(p_callerinfo));
1038 memcpy(&p_dialinginfo, ¶m->setup.dialinginfo, sizeof(p_dialinginfo));
1039 memcpy(&p_capainfo, ¶m->setup.capainfo, sizeof(p_capainfo));
1040 memcpy(&p_redirinfo, ¶m->setup.redirinfo, sizeof(p_redirinfo));
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.");
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);
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.");
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);
1070 /* unsupported codec for RTP bridge */
1071 if (param->setup.rtpinfo.port) {
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 */
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];
1093 add_trace("rtp", "payload", "%s:%d unsupported", media_type2name(param->setup.rtpinfo.media_types[i]), param->setup.rtpinfo.payload_types[i]);
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");
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);
1110 /* since we support half rate compatible codecss, we can page with tchh */
1111 if (p_g_hr_encoder || p_g_amr_encoder)
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);
1119 /* attach only if not already */
1120 epointlist = p_epointlist;
1122 if (epointlist->epoint_id == epoint_id)
1124 epointlist = epointlist->next;
1127 epointlist_new(epoint_id);
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);
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;
1144 case INFO_NTYPE_INTERNATIONAL:
1145 mncc->calling.type = 0x1;
1147 case INFO_NTYPE_NATIONAL:
1148 mncc->calling.type = 0x2;
1150 case INFO_NTYPE_SUBSCRIBER:
1151 mncc->calling.type = 0x4;
1153 default: /* INFO_NTYPE_NOTPRESENT */
1154 mncc->fields &= ~MNCC_F_CALLING;
1157 switch (p_callerinfo.screen) {
1158 case INFO_SCREEN_USER:
1159 mncc->calling.screen = 0;
1161 default: /* INFO_SCREEN_NETWORK */
1162 mncc->calling.screen = 3;
1165 switch (p_callerinfo.present) {
1166 case INFO_PRESENT_ALLOWED:
1167 mncc->calling.present = 0;
1169 case INFO_PRESENT_RESTRICTED:
1170 mncc->calling.present = 1;
1172 default: /* INFO_PRESENT_NOTAVAIL */
1173 mncc->calling.present = 2;
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);
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);
1190 SCPY(mncc->called.number, p_dialinginfo.id);
1191 add_trace("dialing", "number", "%s", mncc->called.number);
1194 /* sending user-user */
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;
1203 case INFO_NTYPE_INTERNATIONAL:
1204 mncc->redirecting.type = 0x1;
1206 case INFO_NTYPE_NATIONAL:
1207 mncc->redirecting.type = 0x2;
1209 case INFO_NTYPE_SUBSCRIBER:
1210 mncc->redirecting.type = 0x4;
1212 default: /* INFO_NTYPE_NOTPRESENT */
1213 mncc->fields &= ~MNCC_F_REDIRECTING;
1216 switch (p_redirinfo.screen) {
1217 case INFO_SCREEN_USER:
1218 mncc->redirecting.screen = 0;
1220 default: /* INFO_SCREE_NETWORK */
1221 mncc->redirecting.screen = 3;
1224 switch (p_redirinfo.present) {
1225 case INFO_PRESENT_ALLOWED:
1226 mncc->redirecting.present = 0;
1228 case INFO_PRESENT_RESTRICTED:
1229 mncc->redirecting.present = 1;
1231 default: /* INFO_PRESENT_NOTAVAIL */
1232 mncc->redirecting.present = 2;
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);
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;
1254 add_trace("lchan", "type", "TCH/F");
1255 mncc->lchan_type = GSM_LCHAN_TCH_F;
1259 send_and_free_mncc(p_g_lcr_gsm, mncc->msg_type, mncc);
1261 new_state(PORT_STATE_OUT_SETUP);
1263 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_PROCEEDING);
1264 message_put(message);
1267 if (param->setup.rtpinfo.port) {
1269 p_g_rtp_ip_remote = param->setup.rtpinfo.ip;
1270 p_g_rtp_port_remote = param->setup.rtpinfo.port;
1276 * endpoint sends messages to the port
1278 int Pgsm_bs::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1280 if (Pgsm::message_epoint(epoint_id, message_id, param))
1283 switch(message_id) {
1284 case MESSAGE_SETUP: /* dial-out command received from epoint */
1285 if (p_state!=PORT_STATE_IDLE)
1287 message_setup(epoint_id, message_id, param);
1291 message_3pty(epoint_id, message_id, param);
1294 case MESSAGE_TRANSFER:
1295 message_transfer(epoint_id, message_id, param);
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);
1305 int gsm_bs_exit(int rc)
1307 /* free gsm instance */
1309 if (gsm_bs->mncc_lfd.fd > -1) {
1310 close(gsm_bs->mncc_lfd.fd);
1311 unregister_fd(&gsm_bs->mncc_lfd);
1314 del_timer(&gsm_bs->socket_retry);
1323 int gsm_bs_init(struct interface *interface)
1325 /* create gsm instance */
1326 gsm_bs = (struct lcr_gsm *)MALLOC(sizeof(struct lcr_gsm));
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");
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);
1336 /* do the initial connect */
1337 mncc_socket_retry_cb(&gsm_bs->socket_retry, gsm_bs, 0);