1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
15 #include <sys/ioctl.h>
16 #include <sys/types.h>
20 #include <netinet/udp.h>
21 #include <netinet/in.h>
23 #include <sys/socket.h>
25 #include <linux/mISDNif.h>
30 #include <mISDNuser/net_l2.h>
37 #ifndef CMX_TXDATA_OFF
52 #warning *********************************************************
54 #warning * It seems that you use an older version of mISDN.
55 #warning * Features like voice recording or echo will not work.
56 #warning * Also it causes problems with loading modules and may
57 #warning * not work at all.
59 #warning * Please upgrade to newer version. A working version can
60 #warning * be found at www.linux-call-router.de.
62 #warning * Do not use the mISDN_1_1 branch, it does not have all
63 #warning * the features that are required. Use the master branch
66 #warning *********************************************************
71 #ifndef ISDN_PID_L4_B_USER
72 #define ISDN_PID_L4_B_USER 0x440000ff
75 // timeouts if activating/deactivating response from mISDN got lost
76 #define B_TIMER_ACTIVATING 1
77 #define B_TIMER_DEACTIVATING 1
79 /* list of mISDN ports */
80 struct mISDNport *mISDNport_first;
82 /* noise randomizer */
83 unsigned char mISDN_rand[256];
84 int mISDN_rand_count = 0;
89 int mISDN_initialize(void)
91 /* try to open raw socket to check kernel */
92 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
95 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
99 /* open debug, if enabled and not only stack debugging */
100 if (options.deb && (options.deb != DEBUG_STACK))
102 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
103 debug_fp = fopen(debug_log, "a");
106 if (options.deb & DEBUG_STACK)
108 SPRINT(debug_stack, "%s/debug_mISDN.log", INSTALL_DATA);
109 mISDN_debug_init(DBGM_ALL, debug_stack, debug_stack, debug_stack);
111 mISDN_debug_init(0, NULL, NULL, NULL);
114 init_layer3(4); // buffer of 4
119 void mISDN_deinitialize(void)
129 if (mISDNsocket > -1)
133 int entity = 0; /* used for udevice */
134 int mISDNdevice = -1; /* the device handler and port list */
136 int mISDN_initialize(void)
139 unsigned char buff[1025];
140 iframe_t *frm = (iframe_t *)buff;
143 /* initialize stuff of the NT lib */
144 if (options.deb & DEBUG_STACK)
146 global_debug = 0xffffffff & ~DBGM_MSG;
147 // global_debug = DBGM_L3DATA;
149 global_debug = DBGM_MAN;
150 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
151 if (options.deb & DEBUG_LOG)
152 debug_init(global_debug, debug_log, debug_log, debug_log);
154 debug_init(global_debug, NULL, NULL, NULL);
157 /* open mISDNdevice if not already open */
163 fprintf(stderr, "cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
167 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
169 /* create entity for layer 3 TE-mode */
170 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
171 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
172 if (ret < (int)mISDN_HEADER_LEN)
175 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
177 entity = frm->dinfo & 0xffff;
180 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
185 void mISDN_deinitialize(void)
187 unsigned char buff[1025];
192 if (mISDNdevice >= 0)
195 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
197 mISDN_close(mISDNdevice);
199 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
207 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
209 p_m_mISDNport = mISDNport;
210 p_m_portnum = mISDNport->portnum;
217 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
218 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
226 p_m_dtmf = !mISDNport->ifport->nodtmf;
229 p_m_remote_ref = 0; /* channel shall be exported to given remote */
230 p_m_remote_id = 0; /* channel shall be exported to given remote */
231 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
239 p_m_crypt_listen = 0;
240 p_m_crypt_msg_loops = 0;
241 p_m_crypt_msg_loops = 0;
242 p_m_crypt_msg_len = 0;
243 p_m_crypt_msg[0] = '\0';
244 p_m_crypt_msg_current = 0;
245 p_m_crypt_key_len = 0;
246 p_m_crypt_listen = 0;
247 p_m_crypt_listen_state = 0;
248 p_m_crypt_listen_len = 0;
249 p_m_crypt_listen_msg[0] = '\0';
250 p_m_crypt_listen_crc = 0;
251 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
253 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
254 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
258 /* if any channel requested by constructor */
259 if (channel == CHANNEL_ANY)
261 /* reserve channel */
263 mISDNport->b_reserved++;
266 /* reserve channel */
267 if (channel > 0) // only if constructor was called with a channel resevation
268 seize_bchannel(channel, exclusive);
270 /* we increase the number of objects: */
272 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
281 struct message *message;
283 /* remove bchannel relation */
289 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
290 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
291 message->param.disconnectinfo.cause = 16;
292 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
293 message_put(message);
294 /* remove from list */
295 free_epointlist(p_epointlist);
298 /* we decrease the number of objects: */
299 p_m_mISDNport->use--;
300 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
307 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
309 /* init trace with given values */
310 start_trace(mISDNport?mISDNport->portnum:0,
311 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
312 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
313 port?port->p_dialinginfo.id:NULL,
316 port?port->p_serial:0,
324 static struct isdn_message {
328 {"TIMEOUT", CC_TIMEOUT},
330 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
331 {"PROCEEDING", CC_PROCEEDING},
332 {"ALERTING", CC_ALERTING},
333 {"CONNECT", CC_CONNECT},
334 {"CONNECT RES", CC_CONNECT},
335 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
336 {"DISCONNECT", CC_DISCONNECT},
337 {"RELEASE", CC_RELEASE},
338 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
339 {"INFORMATION", CC_INFORMATION},
340 {"PROGRESS", CC_PROGRESS},
341 {"NOTIFY", CC_NOTIFY},
342 {"SUSPEND", CC_SUSPEND},
343 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
344 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
345 {"RESUME", CC_RESUME},
346 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
347 {"RESUME_REJ", CC_RESUME_REJECT},
349 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
350 {"HOLD_REJ", CC_HOLD_REJECT},
351 {"RETRIEVE", CC_RETRIEVE},
352 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
353 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
354 {"FACILITY", CC_FACILITY},
355 {"STATUS", CC_STATUS},
356 {"RESTART", CC_RESTART},
357 {"RELEASE_CR", CC_RELEASE_CR},
358 {"NEW_CR", CC_NEW_CR},
359 {"DL_ESTABLISH", DL_ESTABLISH},
360 {"DL_RELEASE", DL_RELEASE},
361 {"PH_ACTIVATE", PH_ACTIVATE},
362 {"PH_DEACTIVATE", PH_DEACTIVATE},
366 static char *isdn_prim[4] = {
372 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
375 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
377 /* select message and primitive text */
379 while(isdn_message[i].name)
381 if (isdn_message[i].value == (prim&0xffffff00))
383 SCPY(msgtext, isdn_message[i].name);
388 SCAT(msgtext, isdn_prim[prim&0x00000003]);
391 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
395 if (mISDNport->ntmode)
397 if (direction == DIRECTION_OUT)
398 SCAT(msgtext, " N->U");
400 SCAT(msgtext, " N<-U");
403 if (direction == DIRECTION_OUT)
404 SCAT(msgtext, " U->N");
406 SCAT(msgtext, " U<-N");
411 /* init trace with given values */
412 start_trace(mISDNport?mISDNport->portnum:0,
413 mISDNport?mISDNport->ifport->interface:NULL,
414 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
415 port?port->p_dialinginfo.id:NULL,
418 port?port->p_serial:0,
424 * send control information to the channel (dsp-module)
426 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
429 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
430 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
431 unsigned long *d = buffer+MISDN_HEADER_LEN;
434 ctrl->prim = PH_CONTROL_REQ;
438 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
440 PERROR("Failed to send to socket %d\n", handle);
442 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
443 iframe_t *ctrl = (iframe_t *)buffer;
444 unsigned long *d = (unsigned long *)&ctrl->data.p;
446 ctrl->prim = PH_CONTROL | REQUEST;
447 ctrl->addr = handle | FLG_MSG_DOWN;
449 ctrl->len = sizeof(int)*2;
452 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
454 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
455 if (c1 == CMX_CONF_JOIN)
456 add_trace(trace_name, NULL, "0x%08x", trace_value);
458 add_trace(trace_name, NULL, "%d", trace_value);
462 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
465 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
466 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
467 unsigned long *d = buffer+MISDN_HEADER_LEN;
470 ctrl->prim = PH_CONTROL_REQ;
473 memcpy(d, c2, c2_len);
474 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
476 PERROR("Failed to send to socket %d\n", handle);
478 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
479 iframe_t *ctrl = (iframe_t *)buffer;
480 unsigned long *d = (unsigned long *)&ctrl->data.p;
482 ctrl->prim = PH_CONTROL | REQUEST;
483 ctrl->addr = handle | FLG_MSG_DOWN;
485 ctrl->len = sizeof(int)+c2_len;
487 memcpy(d, c2, c2_len);
488 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
490 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
491 add_trace(trace_name, NULL, "%d", trace_value);
497 * subfunction for bchannel_event
500 static int _bchannel_create(struct mISDNport *mISDNport, int i)
502 unsigned char buff[1024];
505 unsigned long on = 1;
506 struct sockadd_mISDN addr;
508 if (mISDNport->b_socket[i])
510 PERROR("Error: Socket already created for index %d\n", i);
515 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
516 if (mISDNport->b_socket[i] < 0)
518 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
522 /* set nonblocking io */
523 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
526 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
527 close(mISDNport->b_socket[i]);
528 mISDNport->b_socket[i] = -1;
532 /* bind socket to bchannel */
533 addr.family = AF_ISDN;
534 addr.dev = mISDNport->port-1;
535 addr.channel = i+1+(i>=15);
536 ret = bind(di->bchan, (struct sockaddr *)&addr, sizeof(addr));
539 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
540 close(mISDNport->b_socket[i]);
541 mISDNport->b_socket[i] = -1;
545 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
546 add_trace("channel", NULL, "%d", i+1+(i>=15));
547 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
553 if (!mISDNport->b_stid[i])
555 PERROR("Error: no stack for index %d\n", i);
558 if (mISDNport->b_addr[i])
560 PERROR("Error: stack already created for index %d\n", i);
564 /* create new layer */
565 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
566 memset(&li, 0, sizeof(li));
567 memset(&pid, 0, sizeof(pid));
570 li.st = mISDNport->b_stid[i];
571 UCPY(li.name, "B L4");
572 li.pid.layermask = ISDN_LAYER((4));
573 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
574 ret = mISDN_new_layer(mISDNdevice, &li);
578 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
581 mISDNport->b_addr[i] = li.id;
584 goto failed_new_layer;
586 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
588 /* create new stack */
589 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
590 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
591 pid.protocol[3] = ISDN_PID_L3_B_DSP;
592 pid.protocol[4] = ISDN_PID_L4_B_USER;
593 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
594 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
598 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
599 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
602 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
607 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
608 if (!mISDNport->b_addr[i])
610 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
611 add_trace("channel", NULL, "%d", i+1+(i>=15));
612 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
613 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
620 mISDNport->b_addr[i] = 0;
626 * subfunction for bchannel_event
627 * activate / deactivate request
629 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
632 struct mISDNhead act;
635 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
637 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
639 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
643 /* activate bchannel */
644 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
645 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
648 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
652 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
653 add_trace("channel", NULL, "%d", i+1+(i>=15));
654 if (mISDNport->b_timer[i])
655 add_trace("event", NULL, "timeout recovery");
661 * subfunction for bchannel_event
664 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
670 handle = mISDNport->b_socket[i];
672 unsigned long handle;
674 handle = mISDNport->b_addr[i];
676 port = mISDNport->b_port[i];
679 PERROR("bchannel index i=%d not associated with a port object\n", i);
683 /* set dsp features */
685 if (port->p_m_txdata)
686 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
688 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
690 if (port->p_m_tx_gain)
691 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
692 if (port->p_m_rx_gain)
693 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
695 if (port->p_m_pipeline[0])
696 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
699 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
701 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
703 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
705 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
706 // if (port->p_m_txmix)
707 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
709 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
711 ph_control_block(mISDNport, port, handle, BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
715 * subfunction for bchannel_event
718 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
721 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
722 add_trace("channel", NULL, "%d", i+1+(i>=15));
723 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
725 if (mISDNport->b_socket[i] > -1)
727 close(mISDNport->b_socket[i]);
728 mISDNport->b_socket[i] = -1;
731 unsigned char buff[1024];
733 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
734 add_trace("channel", NULL, "%d", i+1+(i>=15));
735 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
736 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
738 /* remove our stack only if set */
739 if (mISDNport->b_addr[i])
741 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
742 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
743 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
744 mISDNport->b_addr[i] = 0;
754 A bchannel goes through the following states in this order:
757 No one is using the bchannel.
758 It is available and not linked to Port class, nor reserved.
761 The bchannel stack is created and an activation request is sent.
762 It MAY be linked to Port class, but already unlinked due to Port class removal.
765 The bchannel is active and cofigured to the Port class needs.
766 Also it is linked to a Port class, otherwhise it would be deactivated.
768 - B_STATE_DEACTIVATING
769 The bchannel is in deactivating state, due to deactivation request.
770 It may be linked to a Port class, that likes to reactivate it.
774 After deactivating bchannel, and if not used, the bchannel becomes idle again.
776 Also the bchannel may be exported, but only if the state is or becomes idle:
779 The bchannel assignment has been sent to the remove application.
782 The bchannel assignment is acknowledged by the remote application.
785 The bchannel is re-imported by mISDN port object.
789 After re-importing bchannel, and if not used, the bchannel becomes idle again.
792 A bchannel can have the following events:
795 A bchannel is required by a Port class.
796 The bchannel shall be exported to the remote application.
799 The bchannel beomes active.
802 The bchannel is not required by Port class anymore
804 - B_EVENT_DEACTIVATED
805 The bchannel becomes inactive.
808 The bchannel is now used by remote application.
811 The bchannel is not used by remote application.
813 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
815 if an export request is receive by remote application, p_m_remote_* is set.
816 the b_remote_*[index] indicates if and where the channel is exported to. (set from the point on, where export is initiated, until imported is acknowledged.)
817 - set on export request from remote application (if port is assigned)
818 - set on channel use, if requested by remote application (p_m_remote_*)
819 - cleared on drop request
821 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
822 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
823 the bchannel import/export is acknowledged with stack given.
825 if exporting, b_remote_*[index] is set to the remote socket id.
826 if importing has been acknowledged. b_remote_*[index] is cleared.
831 * process bchannel events
832 * - mISDNport is a pointer to the port's structure
833 * - i is the index of the bchannel
834 * - event is the B_EVENT_* value
835 * - port is the PmISDN class pointer
837 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
839 class PmISDN *b_port = mISDNport->b_port[i];
840 int state = mISDNport->b_state[i];
841 double timer = mISDNport->b_timer[i];
842 unsigned long p_m_remote_ref = 0;
843 unsigned long p_m_remote_id = 0;
846 char *p_m_pipeline = NULL;
847 unsigned char *p_m_crypt_key = NULL;
848 int p_m_crypt_key_len = 0;
849 int p_m_crypt_key_type = 0;
851 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
853 unsigned long portid = mISDNport->b_stid[i];
858 p_m_remote_id = b_port->p_m_remote_id;
859 p_m_remote_ref = b_port->p_m_remote_ref;
860 p_m_tx_gain = b_port->p_m_tx_gain;
861 p_m_rx_gain = b_port->p_m_rx_gain;
862 p_m_pipeline = b_port->p_m_pipeline;
863 p_m_crypt_key = b_port->p_m_crypt_key;
864 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
865 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
871 /* port must be linked in order to allow activation */
873 FATAL("bchannel must be linked to a Port class\n");
879 /* export bchannel */
880 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
881 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
882 add_trace("type", NULL, "assign");
884 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
886 add_trace("socket", "id", "%d", portid);
889 state = B_STATE_EXPORTING;
890 mISDNport->b_remote_id[i] = p_m_remote_id;
891 mISDNport->b_remote_ref[i] = p_m_remote_ref;
894 /* create stack and send activation request */
895 if (_bchannel_create(mISDNport, i))
897 _bchannel_activate(mISDNport, i, 1);
898 state = B_STATE_ACTIVATING;
899 timer = now_d + B_TIMER_ACTIVATING;
904 case B_STATE_ACTIVATING:
905 case B_STATE_EXPORTING:
906 /* do nothing, because it is already activating */
909 case B_STATE_DEACTIVATING:
910 case B_STATE_IMPORTING:
911 /* do nothing, because we must wait until we can reactivate */
915 /* problems that might ocurr:
916 * B_EVENT_USE is received when channel already in use.
917 * bchannel exported, but not freed by other port
919 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
923 case B_EVENT_EXPORTREQUEST:
924 /* special case where the bchannel is requested by remote */
927 PERROR("export request without remote channel set, please correct.\n");
933 /* in case, the bchannel is exported right after seize_bchannel */
934 /* export bchannel */
935 /* p_m_remote_id is set, when this event happens. */
936 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
937 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
938 add_trace("type", NULL, "assign");
940 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
942 add_trace("socket", "id", "%d", portid);
945 state = B_STATE_EXPORTING;
946 mISDNport->b_remote_id[i] = p_m_remote_id;
947 mISDNport->b_remote_ref[i] = p_m_remote_ref;
950 case B_STATE_ACTIVATING:
951 case B_STATE_EXPORTING:
952 /* do nothing, because it is already activating */
955 case B_STATE_DEACTIVATING:
956 case B_STATE_IMPORTING:
957 /* do nothing, because we must wait until we can reactivate */
961 /* bchannel is active, so we deactivate */
962 _bchannel_activate(mISDNport, i, 0);
963 state = B_STATE_DEACTIVATING;
964 timer = now_d + B_TIMER_DEACTIVATING;
968 /* problems that might ocurr:
969 * ... when channel already in use.
970 * bchannel exported, but not freed by other port
972 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
976 case B_EVENT_ACTIVATED:
980 case B_STATE_ACTIVATING:
981 if (b_port && !p_m_remote_id)
983 /* bchannel is active and used by Port class, so we configure bchannel */
984 _bchannel_configure(mISDNport, i);
985 state = B_STATE_ACTIVE;
988 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
989 _bchannel_activate(mISDNport, i, 0);
990 state = B_STATE_DEACTIVATING;
991 timer = now_d + B_TIMER_DEACTIVATING;
996 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1000 case B_EVENT_EXPORTED:
1003 case B_STATE_EXPORTING:
1004 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
1006 /* remote export done */
1007 state = B_STATE_REMOTE;
1010 /* bchannel is now exported, but we need bchannel back
1011 * OR bchannel is not used anymore
1012 * OR bchannel has been exported to an obsolete ref,
1013 * so reimport, to later export to new remote */
1014 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1015 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1016 add_trace("type", NULL, "remove");
1018 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1020 add_trace("socket", "id", "%d", portid);
1023 state = B_STATE_IMPORTING;
1028 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1034 FATAL("bchannel must be linked to a Port class\n");
1038 /* bchannel is idle due to an error, so we do nothing */
1041 case B_STATE_ACTIVATING:
1042 case B_STATE_EXPORTING:
1043 /* do nothing because we must wait until bchanenl is active before deactivating */
1046 case B_STATE_ACTIVE:
1047 /* bchannel is active, so we deactivate */
1048 _bchannel_activate(mISDNport, i, 0);
1049 state = B_STATE_DEACTIVATING;
1050 timer = now_d + B_TIMER_DEACTIVATING;
1053 case B_STATE_REMOTE:
1054 /* bchannel is exported, so we re-import */
1055 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1056 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1057 add_trace("type", NULL, "remove");
1059 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1061 add_trace("socket", "id", "%d", portid);
1064 state = B_STATE_IMPORTING;
1067 case B_STATE_DEACTIVATING:
1068 case B_STATE_IMPORTING:
1069 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1073 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1077 case B_EVENT_DEACTIVATED:
1082 /* ignore due to deactivation confirm after unloading */
1085 case B_STATE_DEACTIVATING:
1086 _bchannel_destroy(mISDNport, i);
1087 state = B_STATE_IDLE;
1090 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1093 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
1094 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1095 add_trace("type", NULL, "assign");
1097 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1099 add_trace("socket", "id", "%d", portid);
1102 state = B_STATE_EXPORTING;
1103 mISDNport->b_remote_id[i] = p_m_remote_id;
1104 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1107 if (_bchannel_create(mISDNport, i))
1109 _bchannel_activate(mISDNport, i, 1);
1110 state = B_STATE_ACTIVATING;
1111 timer = now_d + B_TIMER_ACTIVATING;
1118 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1122 case B_EVENT_IMPORTED:
1125 case B_STATE_IMPORTING:
1126 state = B_STATE_IDLE;
1127 mISDNport->b_remote_id[i] = 0;
1128 mISDNport->b_remote_ref[i] = 0;
1131 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1134 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
1135 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1136 add_trace("type", NULL, "assign");
1138 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1140 add_trace("socket", "id", "%d", portid);
1143 state = B_STATE_EXPORTING;
1144 mISDNport->b_remote_id[i] = p_m_remote_id;
1145 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1148 if (_bchannel_create(mISDNport, i))
1150 _bchannel_activate(mISDNport, i, 1);
1151 state = B_STATE_ACTIVATING;
1152 timer = now_d + B_TIMER_ACTIVATING;
1159 /* ignore, because not assigned */
1164 case B_EVENT_TIMEOUT:
1169 /* ignore due to deactivation confirm after unloading */
1172 case B_STATE_ACTIVATING:
1173 _bchannel_activate(mISDNport, i, 1);
1174 timer = now_d + B_TIMER_ACTIVATING;
1177 case B_STATE_DEACTIVATING:
1178 _bchannel_activate(mISDNport, i, 0);
1179 timer = now_d + B_TIMER_DEACTIVATING;
1183 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1188 PERROR("Illegal event %d, please correct.\n", event);
1191 mISDNport->b_state[i] = state;
1192 mISDNport->b_timer[i] = timer;
1199 * check for available channel and reserve+set it.
1200 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1201 * give exclusiv flag
1202 * returns -(cause value) or x = channel x or 0 = no channel
1203 * NOTE: no activation is done here
1205 int PmISDN::seize_bchannel(int channel, int exclusive)
1209 /* the channel is what we have */
1210 if (p_m_b_channel == channel)
1213 /* if channel already in use, release it */
1218 if (channel==CHANNEL_NO || channel==0)
1221 /* is channel in range ? */
1223 || (channel>p_m_mISDNport->b_num && channel<16)
1224 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1225 return(-6); /* channel unacceptable */
1227 /* request exclusive channel */
1228 if (exclusive && channel>0)
1230 i = channel-1-(channel>16);
1231 if (p_m_mISDNport->b_port[i])
1232 return(-44); /* requested channel not available */
1236 /* ask for channel */
1239 i = channel-1-(channel>16);
1240 if (p_m_mISDNport->b_port[i] == NULL)
1244 /* search for channel */
1246 while(i < p_m_mISDNport->b_num)
1248 if (!p_m_mISDNport->b_port[i])
1250 channel = i+1+(i>=15);
1255 return(-34); /* no free channel */
1258 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1261 p_m_mISDNport->b_port[i] = this;
1263 p_m_b_channel = channel;
1264 p_m_b_exclusive = exclusive;
1266 /* reserve channel */
1270 p_m_mISDNport->b_reserved++;
1277 * drop reserved channel and unset it.
1278 * deactivation is also done
1280 void PmISDN::drop_bchannel(void)
1282 /* unreserve channel */
1284 p_m_mISDNport->b_reserved--;
1288 if (p_m_b_index < 0)
1293 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1295 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1296 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1297 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1300 p_m_b_exclusive = 0;
1303 /* process bchannel export/import message from join */
1304 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1306 class Endpoint *epoint;
1308 class PmISDN *isdnport;
1309 struct mISDNport *mISDNport;
1314 case BCHANNEL_REQUEST:
1315 /* find the port object for the join object ref */
1316 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1318 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1321 if (!epoint->ep_portlist)
1323 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1326 if (epoint->ep_portlist->next)
1328 PERROR("join %d has enpoint %d with more than one port. this shall not happen to remote joins.\n", joinremote->j_serial, epoint->ep_serial);
1330 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1332 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1335 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1337 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1339 isdnport = (class PmISDN *)port;
1342 if (isdnport->p_m_remote_id)
1344 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1347 mISDNport = isdnport->p_m_mISDNport;
1348 i = isdnport->p_m_b_index;
1349 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1350 add_trace("type", NULL, "export request");
1351 isdnport->p_m_remote_ref = joinremote->j_serial;
1352 isdnport->p_m_remote_id = joinremote->j_remote_id;
1353 if (mISDNport && i>=0)
1355 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1360 case BCHANNEL_ASSIGN_ACK:
1361 case BCHANNEL_REMOVE_ACK:
1362 /* find mISDNport for stack ID */
1363 mISDNport = mISDNport_first;
1367 ii = mISDNport->b_num;
1371 if (mISDNport->b_socket[i] == handle)
1373 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1380 mISDNport = mISDNport->next;
1384 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1387 /* mISDNport may now be set or NULL */
1390 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1391 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1392 if (mISDNport && i>=0)
1393 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1397 PERROR("received wrong bchannel message type %d from remote\n", type);
1405 audio transmission procedure:
1406 -----------------------------
1409 three sources of audio transmission:
1410 - crypto-data high priority
1411 - tones high priority (also high)
1412 - remote-data low priority
1415 a variable that temporarily shows the number of samples elapsed since last transmission process.
1416 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1419 a variable that is increased whenever data is transmitted.
1420 it is decreased while time elapses. it stores the number of samples that
1421 are currently loaded to dsp module.
1422 since clock in dsp module is the same clock for user space process, these
1426 there are two levels:
1427 ISDN_LOAD will give the load that have to be kept in dsp.
1428 ISDN_MAXLOAD will give the maximum load before dropping.
1430 * procedure for low priority data
1431 see txfromup() for procedure
1432 in short: remote data is ignored during high priority tones
1434 * procedure for high priority data
1435 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1436 if no more data is available, load becomes empty again.
1439 0 ISDN_LOAD ISDN_MAXLOAD
1440 +--------------------+----------------------+
1442 +--------------------+----------------------+
1444 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1445 0 ISDN_LOAD ISDN_MAXLOAD
1446 +--------------------+----------------------+
1447 |TTTTTTTTTTTTTTTTTTTT| |
1448 +--------------------+----------------------+
1450 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1451 0 ISDN_LOAD ISDN_MAXLOAD
1452 +--------------------+----------------------+
1453 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1454 +--------------------+----------------------+
1457 int PmISDN::handler(void)
1459 struct message *message;
1463 if ((ret = Port::handler()))
1467 if (p_m_last_tv_sec)
1469 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1470 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1473 /* set clock of first process ever in this instance */
1474 p_m_last_tv_sec = now_tv.tv_sec;
1475 p_m_last_tv_msec = now_tv.tv_usec/1000;
1477 /* process only if we have a minimum of samples, to make packets not too small */
1478 if (elapsed >= ISDN_TRANSMIT)
1480 /* set clock of last process! */
1481 p_m_last_tv_sec = now_tv.tv_sec;
1482 p_m_last_tv_msec = now_tv.tv_usec/1000;
1485 if (elapsed < p_m_load)
1486 p_m_load -= elapsed;
1490 /* to send data, tone must be active OR crypt messages must be on */
1491 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1492 && (p_m_load < ISDN_LOAD)
1493 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1495 int tosend = ISDN_LOAD - p_m_load, length;
1497 unsigned char buf[MISDN_HEADER_LEN+tosend];
1498 struct mISDNhead *frm = (struct mISDNhead *)buf;
1499 unsigned long *d = buf+MISDN_HEADER_LEN;
1501 unsigned char buf[mISDN_HEADER_LEN+tosend];
1502 iframe_t *frm = (iframe_t *)buf;
1503 unsigned char *p = buf+mISDN_HEADER_LEN;
1506 /* copy crypto loops */
1507 while (p_m_crypt_msg_loops && tosend)
1509 /* how much do we have to send */
1510 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1513 if (length > tosend)
1516 /* copy message (part) to buffer */
1517 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1520 p_m_crypt_msg_current += length;
1521 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1524 p_m_crypt_msg_current = 0;
1525 p_m_crypt_msg_loops--;
1526 // puts("eine loop weniger");
1534 if (p_tone_name[0] && tosend)
1536 tosend -= read_audio(p, tosend);
1541 frm->prim = DL_DATA_REQ;
1543 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1545 PERROR("Failed to send to socket %d\n", handle);
1547 frm->prim = DL_DATA | REQUEST;
1548 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1550 frm->len = ISDN_LOAD - p_m_load - tosend;
1553 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1554 p_m_load += frm->len;
1558 // NOTE: deletion is done by the child class
1560 /* handle timeouts */
1563 if (p_m_timer+p_m_timeout < now_d)
1565 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1567 /* send timeout to endpoint */
1568 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1569 message->param.state = p_state;
1570 message_put(message);
1575 return(0); /* nothing done */
1580 * whenever we get audio data from bchannel, we process it here
1583 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1585 unsigned long cont = *((unsigned long *)data);
1587 void PmISDN::bchannel_receive(iframe_t *frm)
1590 unsigned long cont = *((unsigned long *)&frm->data.p);
1591 unsigned char *data =(unsigned char *)&frm->data.p;
1593 unsigned char *data_temp;
1594 unsigned long length_temp;
1595 struct message *message;
1600 if (hh->prim == PH_CONTROL_IND)
1602 if (frm->prim == (PH_CONTROL | INDICATION))
1607 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1610 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1612 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1613 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1615 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1616 message->param.dtmf = cont & DTMF_TONE_MASK;
1617 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1618 message_put(message);
1624 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1625 add_trace("DSP-CRYPT", NULL, "error");
1627 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1628 message->param.crypt.type = CC_ERROR_IND;
1629 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1630 message_put(message);
1634 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1635 add_trace("DSP-CRYPT", NULL, "ok");
1637 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1638 message->param.crypt.type = CC_ACTBF_CONF;
1639 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1640 message_put(message);
1644 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1645 add_trace("unknown", NULL, "0x%x", cont);
1651 if (hh->prim == PH_SIGNAL_IND)
1653 if (frm->prim == (PH_SIGNAL | INDICATION))
1662 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1663 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1666 /* see below (same condition) */
1667 if (p_state!=PORT_STATE_CONNECT
1668 && !p_m_mISDNport->tones)
1670 // printf(".");fflush(stdout);return;
1672 record(data, len, 1); // from up
1677 chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
1678 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1684 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1686 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1688 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1690 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1694 /* calls will not process any audio data unless
1695 * the call is connected OR interface features audio during call setup.
1697 //printf("%d -> %d prim=%x joindata=%d tones=%d\n", p_serial, ACTIVE_EPOINT(p_epointlist), frm->prim, p_m_joindata, p_m_mISDNport->earlyb);
1698 #ifndef DEBUG_COREBRIDGE
1699 if (p_state!=PORT_STATE_CONNECT
1700 && !p_m_mISDNport->tones)
1704 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1707 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1713 record(data, len, 0); // from down
1715 /* randomize and listen to crypt message if enabled */
1716 if (p_m_crypt_listen)
1718 /* the noisy randomizer */
1722 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1724 cryptman_listen_bch(data, len);
1729 /* send data to epoint */
1730 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1736 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1737 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1738 memcpy(message->param.data.data, data_temp, message->param.data.len);
1739 message_put(message);
1740 if (length_temp <= sizeof(message->param.data.data))
1742 data_temp += sizeof(message->param.data.data);
1743 length_temp -= sizeof(message->param.data.data);
1752 void PmISDN::set_echotest(int echo)
1754 if (p_m_echo != echo)
1757 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1759 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1761 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1763 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1771 void PmISDN::set_tone(char *dir, char *tone)
1777 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1784 /* check if we NOT really have to use a dsp-tone */
1785 if (!options.dsptones)
1789 if (p_m_b_index >= 0)
1790 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1792 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1794 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1796 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1800 Port::set_tone(dir, tone);
1806 /* now we USE dsp-tone, convert name */
1807 else if (!strcmp(tone, "dialtone"))
1809 switch(options.dsptones) {
1810 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1811 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1812 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1814 } else if (!strcmp(tone, "dialpbx"))
1816 switch(options.dsptones) {
1817 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1818 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1819 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1821 } else if (!strcmp(tone, "ringing"))
1823 switch(options.dsptones) {
1824 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1825 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1826 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1828 } else if (!strcmp(tone, "ringpbx"))
1830 switch(options.dsptones) {
1831 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1832 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1833 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1835 } else if (!strcmp(tone, "busy"))
1838 switch(options.dsptones) {
1839 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1840 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1841 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1843 } else if (!strcmp(tone, "release"))
1846 switch(options.dsptones) {
1847 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1848 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1849 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1851 } else if (!strcmp(tone, "cause_10"))
1853 else if (!strcmp(tone, "cause_11"))
1855 else if (!strcmp(tone, "cause_22"))
1857 switch(options.dsptones) {
1858 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1859 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1860 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1862 } else if (!strncmp(tone, "cause_", 6))
1863 id = TONE_SPECIAL_INFO;
1867 /* if we have a tone that is not supported by dsp */
1868 if (id==TONE_OFF && tone[0])
1876 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1877 if (p_m_b_index >= 0)
1878 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1880 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1882 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1885 /* turn user-space tones off in cases of no tone OR dsp tone */
1886 Port::set_tone("",NULL);
1890 /* MESSAGE_mISDNSIGNAL */
1891 //extern struct message *dddebug;
1892 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1894 switch(param->mISDNsignal.message)
1896 case mISDNSIGNAL_VOLUME:
1897 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1899 p_m_tx_gain = param->mISDNsignal.tx_gain;
1900 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1901 if (p_m_b_index >= 0)
1902 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1904 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1906 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1909 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1910 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1912 p_m_rx_gain = param->mISDNsignal.rx_gain;
1913 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1914 if (p_m_b_index >= 0)
1915 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1917 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1919 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1922 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1925 case mISDNSIGNAL_CONF:
1926 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1927 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1928 if (p_m_conf != param->mISDNsignal.conf)
1930 p_m_conf = param->mISDNsignal.conf;
1931 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1932 if (p_m_b_index >= 0)
1933 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1935 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
1937 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
1940 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1941 /* we must set, even if currently tone forbids conf */
1942 p_m_conf = param->mISDNsignal.conf;
1943 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1946 case mISDNSIGNAL_JOINDATA:
1947 if (p_m_joindata != param->mISDNsignal.joindata)
1949 p_m_joindata = param->mISDNsignal.joindata;
1950 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1952 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1955 case mISDNSIGNAL_DELAY:
1956 if (p_m_delay != param->mISDNsignal.delay)
1958 p_m_delay = param->mISDNsignal.delay;
1959 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1961 if (p_m_b_index >= 0)
1962 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1964 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1966 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1970 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1974 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1979 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1981 struct message *message;
1983 switch(param->crypt.type)
1985 case CC_ACTBF_REQ: /* activate blowfish */
1987 p_m_crypt_key_len = param->crypt.len;
1988 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1990 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1991 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1992 message->param.crypt.type = CC_ERROR_IND;
1993 message_put(message);
1996 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1998 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1999 if (p_m_b_index >= 0)
2000 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2002 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
2004 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
2008 case CC_DACT_REQ: /* deactivate session encryption */
2013 case CR_LISTEN_REQ: /* start listening to messages */
2014 p_m_crypt_listen = 1;
2015 p_m_crypt_listen_state = 0;
2018 case CR_UNLISTEN_REQ: /* stop listening to messages */
2019 p_m_crypt_listen = 0;
2022 case CR_MESSAGE_REQ: /* send message */
2023 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2024 if (!p_m_crypt_msg_len)
2026 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2029 p_m_crypt_msg_current = 0; /* reset */
2030 p_m_crypt_msg_loops = 6; /* enable */
2032 /* disable txmix, or we get corrupt data due to audio process */
2033 if (p_m_txmix && p_m_b_index>=0)
2035 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2037 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2039 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2046 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2052 * endpoint sends messages to the port
2054 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2056 if (Port::message_epoint(epoint_id, message_id, param))
2061 case MESSAGE_DATA: /* tx-data from upper layer */
2062 txfromup(param->data.data, param->data.len);
2065 case MESSAGE_mISDNSIGNAL: /* user command */
2066 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2067 message_mISDNsignal(epoint_id, message_id, param);
2070 case MESSAGE_CRYPT: /* crypt control command */
2071 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2072 message_crypt(epoint_id, message_id, param);
2081 * main loop for processing messages from mISDN
2084 int mISDN_handler(void)
2087 struct mISDNport *mISDNport;
2088 class PmISDN *isdnport;
2090 char buffer[2048+MISDN_HEADER_LEN];
2091 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2093 /* process all ports */
2094 mISDNport = mISDNport_first;
2097 /* process all bchannels */
2099 while(i < mISDNport->b_num)
2101 /* process timer events for bchannel handling */
2102 if (mISDNport->b_timer[i])
2104 if (mISDNport->b_timer[i] <= now_d)
2105 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2107 /* handle port of bchannel */
2108 isdnport=mISDNport->b_port[i];
2111 /* call bridges in user space OR crypto OR recording */
2112 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2114 /* rx IS required */
2115 if (isdnport->p_m_rxoff)
2118 isdnport->p_m_rxoff = 0;
2119 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2120 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2121 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2126 /* rx NOT required */
2127 if (!isdnport->p_m_rxoff)
2130 isdnport->p_m_rxoff = 1;
2131 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2132 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2133 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2138 if (isdnport->p_record)
2140 /* txdata IS required */
2141 if (!isdnport->p_m_txdata)
2144 isdnport->p_m_txdata = 1;
2145 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2146 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2147 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2152 /* txdata NOT required */
2153 if (isdnport->p_m_txdata)
2156 isdnport->p_m_txdata = 0;
2157 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2158 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2159 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2165 /* handle message from bchannel */
2166 if (mISDNport->b_stack[i] > -1)
2168 ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
2169 if (ret >= MISDN_HEADER_LEN)
2174 /* we don't care about confirms, we use rx data to sync tx */
2179 /* we receive audio data, we respond to it AND we send tones */
2183 case PH_CONTROL_IND:
2184 if (mISDNport->b_port[i])
2185 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2187 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_stack[i]);
2190 case PH_ACTIVATE_IND:
2191 case DL_ESTABLISH_IND:
2192 case PH_ACTIVATE_CONF:
2193 case DL_ESTABLISH_CONF:
2194 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2195 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2198 case PH_DEACTIVATE_IND:
2199 case DL_RELEASE_IND:
2200 case PH_DEACTIVATE_CONF:
2201 case DL_RELEASE_CONF:
2202 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2203 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2207 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], msg->len);
2211 if (ret < 0 && errno != EWOULDBLOCK)
2212 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2219 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2221 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2222 mISDNport->l1timeout = 0;
2225 /* layer 2 establish timer */
2226 if (mISDNport->l2establish)
2228 if (now-mISDNport->l2establish > 5)
2231 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2232 mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2233 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ, DIRECTION_OUT);
2240 mISDNport = mISDNport->next;
2243 /* if we received at least one b-frame, we will return 1 */
2247 int mISDN_handler(void)
2250 struct mISDNport *mISDNport;
2251 class PmISDN *isdnport;
2256 mISDNuser_head_t *hh;
2259 /* the que avoids loopbacks when replying to stack after receiving
2261 mISDNport = mISDNport_first;
2264 /* process turning on/off rx */
2266 while(i < mISDNport->b_num)
2268 /* process timer events for bchannel handling */
2269 if (mISDNport->b_timer[i])
2271 if (mISDNport->b_timer[i] <= now_d)
2272 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2274 isdnport=mISDNport->b_port[i];
2277 /* call bridges in user space OR crypto OR recording */
2278 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2280 /* rx IS required */
2281 if (isdnport->p_m_rxoff)
2284 isdnport->p_m_rxoff = 0;
2285 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2286 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2287 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2292 /* rx NOT required */
2293 if (!isdnport->p_m_rxoff)
2296 isdnport->p_m_rxoff = 1;
2297 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2298 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2299 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2304 if (isdnport->p_record)
2306 /* txdata IS required */
2307 if (!isdnport->p_m_txdata)
2310 isdnport->p_m_txdata = 1;
2311 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2313 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2314 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2320 /* txdata NOT required */
2321 if (isdnport->p_m_txdata)
2324 isdnport->p_m_txdata = 0;
2325 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2327 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2328 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2337 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2339 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2340 mISDNport->l1timeout = 0;
2343 if (mISDNport->l2establish)
2345 if (now-mISDNport->l2establish > 5)
2347 if (mISDNport->ntmode)
2349 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2350 time(&mISDNport->l2establish);
2352 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2353 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2358 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2359 time(&mISDNport->l2establish);
2361 act.prim = DL_ESTABLISH | REQUEST;
2362 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2365 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2367 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
2372 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2374 if (mISDNport->ntmode)
2376 hh = (mISDNuser_head_t *)dmsg->data;
2377 PDEBUG(DEBUG_ISDN, "sending queued NT l3-down-message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", hh->prim, hh->dinfo, dmsg->len);
2378 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2382 frm = (iframe_t *)dmsg->data;
2383 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2384 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2385 PDEBUG(DEBUG_ISDN, "sending queued TE l3-down-message: prim(0x%x) dinfo(0x%x) msg->len(%d)\n", frm->prim, frm->dinfo, dmsg->len);
2386 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2391 mISDNport = mISDNport->next;
2394 /* no device, no read */
2395 if (mISDNdevice < 0)
2398 /* get message from kernel */
2399 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2401 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2405 if (errno == EAGAIN)
2407 FATAL("Failed to do mISDN_read()\n");
2412 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2416 frm = (iframe_t *)msg->data;
2421 case MGR_DELLAYER | CONFIRM:
2422 case MGR_INITTIMER | CONFIRM:
2423 case MGR_ADDTIMER | CONFIRM:
2424 case MGR_DELTIMER | CONFIRM:
2425 case MGR_REMOVETIMER | CONFIRM:
2430 /* handle timer events from mISDN for NT-stack
2431 * note: they do not associate with a stack */
2432 if (frm->prim == (MGR_TIMER | INDICATION))
2436 /* find mISDNport */
2437 mISDNport = mISDNport_first;
2441 if (mISDNport->ntmode)
2443 it = mISDNport->nst.tlist;
2447 if (it->id == (int)frm->addr)
2454 mISDNport = mISDNport->next;
2458 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2459 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2461 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2462 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2463 ret = it->function(it->data);
2466 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2471 /* find the mISDNport that belongs to the stack */
2472 mISDNport = mISDNport_first;
2475 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2477 mISDNport = mISDNport->next;
2481 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2482 // show a list of all mISDNports and their address
2484 mISDNport = mISDNport_first;
2487 PERROR(" port %s %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2488 mISDNport = mISDNport->next;
2495 if (!(frm->addr&FLG_CHILD_STACK))
2500 case MGR_SHORTSTATUS | INDICATION:
2501 case MGR_SHORTSTATUS | CONFIRM:
2502 switch(frm->dinfo) {
2503 case SSTATUS_L1_ACTIVATED:
2504 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2507 case SSTATUS_L1_DEACTIVATED:
2508 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2511 case SSTATUS_L2_ESTABLISHED:
2512 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
2515 case SSTATUS_L2_RELEASED:
2516 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
2522 case PH_ACTIVATE | CONFIRM:
2523 case PH_ACTIVATE | INDICATION:
2524 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2526 if (mISDNport->ntmode)
2528 mISDNport->l1link = 1;
2529 setup_queue(mISDNport, 1);
2533 mISDNport->l1link = 1;
2534 setup_queue(mISDNport, 1);
2537 case PH_DEACTIVATE | CONFIRM:
2538 case PH_DEACTIVATE | INDICATION:
2539 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2541 if (mISDNport->ntmode)
2543 mISDNport->l1link = 0;
2544 setup_queue(mISDNport, 0);
2548 mISDNport->l1link = 0;
2549 setup_queue(mISDNport, 0);
2552 case PH_CONTROL | CONFIRM:
2553 case PH_CONTROL | INDICATION:
2554 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2557 case DL_ESTABLISH | INDICATION:
2558 case DL_ESTABLISH | CONFIRM:
2559 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2561 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2563 if (mISDNport->l2establish)
2565 mISDNport->l2establish = 0;
2566 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2568 mISDNport->l2link = 1;
2571 case DL_RELEASE | INDICATION:
2572 case DL_RELEASE | CONFIRM:
2573 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2575 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2577 mISDNport->l2link = 0;
2580 time(&mISDNport->l2establish);
2581 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2587 PDEBUG(DEBUG_STACK, "GOT d-msg from %s port %d prim 0x%x dinfo 0x%x addr 0x%x\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, frm->prim, frm->dinfo, frm->addr);
2588 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2590 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2593 if (mISDNport->ntmode)
2595 /* l1-data enters the nt-mode library */
2596 nst = &mISDNport->nst;
2597 if (nst->l1_l2(nst, msg))
2602 /* l3-data is sent to pbx */
2603 if (stack2manager_te(mISDNport, msg))
2614 /* we don't care about confirms, we use rx data to sync tx */
2615 case PH_DATA | CONFIRM:
2616 case DL_DATA | CONFIRM:
2619 /* we receive audio data, we respond to it AND we send tones */
2620 case PH_DATA | INDICATION:
2621 case DL_DATA | INDICATION:
2622 case PH_CONTROL | INDICATION:
2623 case PH_SIGNAL | INDICATION:
2625 while(i < mISDNport->b_num)
2627 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2631 if (i == mISDNport->b_num)
2633 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2636 if (mISDNport->b_port[i])
2638 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2639 mISDNport->b_port[i]->bchannel_receive(frm);
2641 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2644 case PH_ACTIVATE | INDICATION:
2645 case DL_ESTABLISH | INDICATION:
2646 case PH_ACTIVATE | CONFIRM:
2647 case DL_ESTABLISH | CONFIRM:
2648 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2650 while(i < mISDNport->b_num)
2652 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2656 if (i == mISDNport->b_num)
2658 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2661 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2664 case PH_DEACTIVATE | INDICATION:
2665 case DL_RELEASE | INDICATION:
2666 case PH_DEACTIVATE | CONFIRM:
2667 case DL_RELEASE | CONFIRM:
2668 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2670 while(i < mISDNport->b_num)
2672 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2676 if (i == mISDNport->b_num)
2678 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2681 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2685 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2696 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2698 struct mISDNport *mISDNport = ml3->private;
2700 if (cmd == MT_ASSIGN)
2706 achtung MT_ASSIGN kommt hier an
2712 case MGR_SHORTSTATUS_IND:
2713 case MGR_SHORTSTATUS_CONF:
2714 switch(frm->dinfo) {
2715 case SSTATUS_L1_ACTIVATED:
2716 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE_IND, DIRECTION_IN);
2719 case SSTATUS_L1_DEACTIVATED:
2720 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE_IND, DIRECTION_IN);
2723 case SSTATUS_L2_ESTABLISHED:
2724 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_IND, DIRECTION_IN);
2727 case SSTATUS_L2_RELEASED:
2728 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_IND, DIRECTION_IN);
2734 case PH_ACTIVATE_CONF:
2735 case PH_ACTIVATE_IND:
2736 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2739 mISDNport->l1link = 1;
2741 if (mISDNport->ntmode)
2742 setup_queue(mISDNport, 1);
2746 case PH_DEACTIVATE | CONFIRM:
2747 case PH_DEACTIVATE | INDICATION:
2748 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2751 mISDNport->l1link = 0;
2752 raus mit der setup-queue, da dies im stack geschieht
2754 if (mISDNport->ntmode)
2755 setup_queue(mISDNport, 0);
2759 case PH_CONTROL_CONFIRM:
2760 case PH_CONTROL_INDICATION:
2761 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2764 case DL_ESTABLISH_IND:
2765 case DL_ESTABLISH_CONF:
2766 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2768 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2770 if (mISDNport->l2establish)
2772 mISDNport->l2establish = 0;
2773 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2775 mISDNport->l2link = 1;
2778 case DL_RELEASE_IND:
2779 case DL_RELEASE_CONF:
2780 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2783 mISDNport->l2link = 0;
2786 time(&mISDNport->l2establish);
2787 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2792 /* l3-data is sent to LCR */
2793 message_from_mlayer3(mISDNport, cmd, pid, l3m);
2809 * global function to add a new card (port)
2811 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2814 unsigned char buff[1025];
2815 iframe_t *frm = (iframe_t *)buff;
2816 struct mISDNport *mISDNport, **mISDNportp;
2818 int pri, bri, ports;
2821 struct mlayer3 *ml3;
2822 struct mISDN_devinfo devinfo;
2824 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2827 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2831 // interface_info_t ii;
2835 stack_info_t *stinf;
2837 /* query port's requirements */
2838 cnt = mISDN_get_stack_count(mISDNdevice);
2843 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2846 if (port>cnt || port<1)
2848 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2852 pri = bri = ports = nt = te = 0;
2854 devinfo.id = port - 1;
2855 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2858 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2861 /* output the port info */
2862 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2867 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2873 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2880 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2887 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2894 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2900 if (force_nt && !nt)
2902 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2907 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2910 if (pots && !bri && !pri)
2912 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2917 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2922 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2925 /* force nt, by turning off TE */
2928 /* if TE an NT is supported (and not forced to NT), turn off NT */
2932 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2935 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2938 stinf = (stack_info_t *)&frm->data.p;
2939 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2941 case ISDN_PID_L0_TE_S0:
2942 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2944 case ISDN_PID_L0_NT_S0:
2945 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2948 case ISDN_PID_L0_TE_E1:
2949 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2952 case ISDN_PID_L0_NT_E1:
2953 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2958 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2964 if (stinf->pid.protocol[1] == 0)
2966 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2969 if (stinf->pid.protocol[2])
2971 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2978 if (stinf->pid.protocol[1] == 0)
2980 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2983 if (stinf->pid.protocol[2] == 0)
2985 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2988 if (stinf->pid.protocol[3] == 0)
2990 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2994 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2996 case ISDN_PID_L3_DSS1USER:
3000 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
3004 if (stinf->pid.protocol[4])
3006 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3012 /* add mISDNport structure */
3013 mISDNportp = &mISDNport_first;
3015 mISDNportp = &((*mISDNportp)->next);
3016 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3018 *mISDNportp = mISDNport;
3020 /* allocate ressources of port */
3023 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
3028 prop |= FLG_FORCE_PTMP;
3029 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
3030 if (!mISDNport->ml3)
3032 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3037 /* if ntmode, establish L1 to send the tei removal during start */
3038 if (mISDNport->ntmode)
3042 act.prim = PH_ACTIVATE | REQUEST;
3043 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3044 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3047 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3048 usleep(10000); /* to be sure, that l1 is up */
3052 SCPY(mISDNport->name, devinfo.name);
3053 mISDNport->b_num = devinfo.nrbchan;
3055 msg_queue_init(&mISDNport->downqueue);
3056 mISDNport->d_stid = stinf->id;
3057 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3058 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
3060 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
3064 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
3069 /* create layer intance */
3070 memset(&li, 0, sizeof(li));
3071 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3074 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3075 li.pid.layermask = ISDN_LAYER((nt?2:4));
3076 li.st = mISDNport->d_stid;
3077 ret = mISDN_new_layer(mISDNdevice, &li);
3080 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3082 mISDNport_close(mISDNport);
3085 mISDNport->upper_id = li.id;
3086 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3089 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3092 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3093 if (mISDNport->lower_id < 0)
3095 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3098 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3099 if (mISDNport->upper_id < 0)
3101 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3104 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3106 /* if ntmode, establish L1 to send the tei removal during start */
3107 if (mISDNport->ntmode)
3111 act.prim = PH_ACTIVATE | REQUEST;
3112 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3113 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3116 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3117 usleep(10000); /* to be sure, that l1 is up */
3120 /* create nst (nt-mode only) */
3123 mgr = &mISDNport->mgr;
3124 nst = &mISDNport->nst;
3129 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3130 nst->device = mISDNdevice;
3132 nst->d_stid = mISDNport->d_stid;
3134 nst->feature = FEATURE_NET_HOLD;
3136 nst->feature |= FEATURE_NET_PTP;
3138 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3141 while(i < mISDNport->b_num)
3143 nst->b_stid[i] = mISDNport->b_stid[i];
3147 nst->l1_id = mISDNport->lower_id;
3148 nst->l2_id = mISDNport->upper_id;
3151 msg_queue_init(&nst->down_queue);
3157 mISDNport->b_num = stinf->childcnt;
3159 mISDNport->portnum = port;
3160 mISDNport->ntmode = nt;
3161 mISDNport->pri = pri;
3162 mISDNport->ptp = ptp;
3163 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3165 while(i < mISDNport->b_num)
3167 mISDNport->b_state[i] = B_STATE_IDLE;
3169 mISDNport->b_socket = -1;
3171 mISDNport->b_stid[i] = stinf->child[i];
3172 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3177 /* if te-mode, query state link */
3178 if (!mISDNport->ntmode)
3182 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3183 act.prim = MGR_SHORTSTATUS | REQUEST;
3184 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3185 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3187 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3189 /* if ptp AND te-mode, pull up the link */
3190 if (mISDNport->ptp && !mISDNport->ntmode)
3194 act.prim = DL_ESTABLISH | REQUEST;
3195 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3198 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3200 /* if ptp AND nt-mode, pull up the link */
3201 if (mISDNport->ptp && mISDNport->ntmode)
3205 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3206 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3209 /* initially, we assume that the link is down, exept for nt-ptmp */
3210 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3212 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3214 start_trace(mISDNport->portnum,
3222 add_trace("channels", NULL, "%d", mISDNport->b_num);
3229 * function to free ALL cards (ports)
3231 void mISDNport_close_all(void)
3233 /* free all ports */
3234 while(mISDNport_first)
3235 mISDNport_close(mISDNport_first);
3239 * free only one port
3241 void mISDNport_close(struct mISDNport *mISDNport)
3243 struct mISDNport **mISDNportp;
3245 class PmISDN *isdnport;
3247 unsigned char buf[32];
3250 /* remove all port instance that are linked to this mISDNport */
3254 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3256 isdnport = (class PmISDN *)port;
3257 if (isdnport->p_m_mISDNport)
3259 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3266 /* only if we are already part of interface */
3267 if (mISDNport->ifport)
3269 start_trace(mISDNport->portnum,
3270 mISDNport->ifport->interface,
3280 /* free bchannels */
3282 while(i < mISDNport->b_num)
3284 if (mISDNport->b_addr[i])
3286 _bchannel_destroy(mISDNport, i);
3287 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3293 close_layer3(mISDNport->ml3);
3295 /* free ressources of port */
3296 msg_queue_purge(&mISDNport->downqueue);
3299 if (mISDNport->ntmode)
3301 nst = &mISDNport->nst;
3302 if (nst->manager) /* to see if initialized */
3304 PDEBUG(DEBUG_STACK, "the following messages are ok: one L3 process always exists (broadcast process) and some L2 instances (broadcast + current telephone's instances)\n");
3305 cleanup_Isdnl3(nst);
3306 cleanup_Isdnl2(nst);
3309 msg_queue_purge(&nst->down_queue);
3310 if (nst->phd_down_msg)
3311 FREE(nst->phd_down_msg, 0);
3315 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3316 if (mISDNport->d_stid)
3318 if (mISDNport->upper_id)
3319 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3323 /* remove from list */
3324 mISDNportp = &mISDNport_first;
3327 if (*mISDNportp == mISDNport)
3329 *mISDNportp = (*mISDNportp)->next;
3333 mISDNportp = &((*mISDNportp)->next);
3337 FATAL("mISDNport not in list\n");
3339 FREE(mISDNport, sizeof(struct mISDNport));
3346 * global function to show all available isdn ports
3348 void mISDN_port_info(void)
3352 int useable, nt, te, pri, bri, pots;
3353 unsigned char buff[1025];
3354 iframe_t *frm = (iframe_t *)buff;
3356 struct mISDN_devinfo devinfo;
3360 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3363 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3367 /* get number of stacks */
3369 ret = ioctl(socket, IMGETCOUNT, &ii);
3372 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3376 stack_info_t *stinf;
3380 if ((device = mISDN_open()) < 0)
3382 fprintf(stderr, "Cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", device, errno, strerror(errno));
3386 /* get number of stacks */
3388 ii = mISDN_get_stack_count(device);
3393 printf("Found no card. Please be sure to load card drivers.\n");
3397 /* loop the number of cards and get their info */
3400 nt = te = bri = pri = pots = 0;
3405 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
3408 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3412 /* output the port info */
3413 printf("Port %2d name='%s': ", i, devinfo.name);
3414 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3419 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3425 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3432 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3439 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3446 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3452 if ((te || nt) && (bri || pri || ports))
3456 printf("TE-mode BRI S/T interface line (for phone lines)");
3458 printf("NT-mode BRI S/T interface port (for phones)");
3460 printf("TE-mode PRI E1 interface line (for phone lines)");
3462 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3464 printf("FXS POTS interface port (for analog lines)");
3466 printf("FXO POTS interface port (for analog phones)");
3470 printf("\n -> Analog interfaces are not supported.");
3474 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3478 printf(" - %d B-channels\n", devinfo.nfbchan);
3480 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3483 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3486 stinf = (stack_info_t *)&frm->data.p;
3488 /* output the port info */
3489 printf("Port %2d: ", i);
3490 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3492 case ISDN_PID_L0_TE_S0:
3496 printf("TE-mode BRI S/T interface line (for phone lines)");
3498 case ISDN_PID_L0_NT_S0:
3502 printf("NT-mode BRI S/T interface port (for phones)");
3504 case ISDN_PID_L0_TE_E1:
3508 printf("TE-mode PRI E1 interface line (for phone lines)");
3510 case ISDN_PID_L0_NT_E1:
3514 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3518 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3524 if (stinf->pid.protocol[1] == 0)
3527 printf(" -> Missing layer 1 NT-mode protocol.\n");
3530 while(p <= MAX_LAYER_NR) {
3531 if (stinf->pid.protocol[p])
3534 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3541 printf(" -> Interface is Point-To-Point (PRI).\n");
3543 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3548 if (stinf->pid.protocol[1] == 0)
3551 printf(" -> Missing layer 1 protocol.\n");
3553 if (stinf->pid.protocol[2] == 0)
3556 printf(" -> Missing layer 2 protocol.\n");
3558 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3560 printf(" -> Interface is Poin-To-Point.\n");
3562 if (stinf->pid.protocol[3] == 0)
3565 printf(" -> Missing layer 3 protocol.\n");
3568 printf(" -> Protocol: ");
3569 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3571 case ISDN_PID_L3_DSS1USER:
3572 printf("DSS1 (Euro ISDN)");
3577 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3582 while(p <= MAX_LAYER_NR) {
3583 if (stinf->pid.protocol[p])
3586 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3591 printf(" - %d B-channels\n", stinf->childcnt);
3595 printf(" * Port NOT useable for LCR\n");
3597 printf("--------\n");
3608 if ((ret = mISDN_close(device)))
3609 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3615 * enque data from upper buffer
3617 void PmISDN::txfromup(unsigned char *data, int length)
3620 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3621 struct mISDNhead *frm = (struct mISDNhead *)buf;
3623 if (p_m_b_index < 0)
3625 if (!p_m_mISDNport->b_socket[p_m_b_index])
3628 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3629 iframe_t *frm = (iframe_t *)buf;
3631 if (p_m_b_index < 0)
3633 if (!p_m_mISDNport->b_addr[p_m_b_index])
3637 /* check if high priority tones exist
3638 * ignore data in this case
3640 if (p_tone_name[0] || p_m_crypt_msg_loops)
3643 /* preload procedure
3644 * if transmit buffer in DSP module is empty,
3645 * preload it to DSP_LOAD to prevent jitter gaps.
3647 if (p_m_load==0 && ISDN_LOAD>0)
3650 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3651 frm->len = ISDN_LOAD;
3652 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3653 p_m_load += frm->len;
3656 /* drop if load would exceed ISDN_MAXLOAD
3657 * this keeps the delay not too high
3659 if (p_m_load+length > ISDN_MAXLOAD)
3662 /* make and send frame */
3664 frm->prim = DL_DATA_REQ;
3666 memcpy(buf+MISDN_HEADER_LEN, data, length);
3667 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3669 PERROR("Failed to send to socket %d\n", handle);
3671 frm->prim = DL_DATA | REQUEST;
3672 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3675 memcpy(buf+mISDN_HEADER_LEN, data, length);
3676 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);