1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
15 #include <mISDNuser/net_l2.h>
21 #ifndef CMX_TXDATA_OFF
36 #warning *********************************************************
38 #warning * It seems that you use an older version of mISDN.
39 #warning * Features like voice recording or echo will not work.
40 #warning * Also it causes problems with loading modules and may
41 #warning * not work at all.
43 #warning * Please upgrade to newer version. A working version can
44 #warning * be found at www.linux-call-router.de.
46 #warning * Do not use the mISDN_1_1 branch, it does not have all
47 #warning * the features that are required. Use the master branch
50 #warning *********************************************************
55 #ifndef ISDN_PID_L4_B_USER
56 #define ISDN_PID_L4_B_USER 0x440000ff
60 // timeouts if activating/deactivating response from mISDN got lost
61 #define B_TIMER_ACTIVATING 1 // seconds
62 #define B_TIMER_DEACTIVATING 1 // seconds
64 /* list of mISDN ports */
65 struct mISDNport *mISDNport_first;
67 /* noise randomizer */
68 unsigned char mISDN_rand[256];
69 int mISDN_rand_count = 0;
74 int mISDN_initialize(void)
76 /* try to open raw socket to check kernel */
77 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
80 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
84 /* open debug, if enabled and not only stack debugging */
85 if (options.deb && (options.deb != DEBUG_STACK))
87 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
88 debug_fp = fopen(debug_log, "a");
91 if (options.deb & DEBUG_STACK)
93 SPRINT(debug_stack, "%s/debug_mISDN.log", INSTALL_DATA);
94 mISDN_debug_init(DBGM_ALL, debug_stack, debug_stack, debug_stack);
96 mISDN_debug_init(0, NULL, NULL, NULL);
99 init_layer3(4); // buffer of 4
104 void mISDN_deinitialize(void)
114 if (mISDNsocket > -1)
118 int entity = 0; /* used for udevice */
119 int mISDNdevice = -1; /* the device handler and port list */
121 int mISDN_initialize(void)
124 unsigned char buff[1025];
125 iframe_t *frm = (iframe_t *)buff;
128 /* initialize stuff of the NT lib */
129 if (options.deb & DEBUG_STACK)
131 global_debug = 0xffffffff & ~DBGM_MSG;
132 // global_debug = DBGM_L3DATA;
134 global_debug = DBGM_MAN;
135 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
136 if (options.deb & DEBUG_LOG)
137 debug_init(global_debug, debug_log, debug_log, debug_log);
139 debug_init(global_debug, NULL, NULL, NULL);
142 /* open mISDNdevice if not already open */
148 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));
152 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
154 /* create entity for layer 3 TE-mode */
155 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
156 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
157 if (ret < (int)mISDN_HEADER_LEN)
160 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
162 entity = frm->dinfo & 0xffff;
165 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
170 void mISDN_deinitialize(void)
172 unsigned char buff[1025];
177 if (mISDNdevice >= 0)
180 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
182 mISDN_close(mISDNdevice);
184 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
192 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
194 p_m_mISDNport = mISDNport;
195 p_m_portnum = mISDNport->portnum;
202 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
203 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
211 p_m_dtmf = !mISDNport->ifport->nodtmf;
214 p_m_remote_ref = 0; /* channel shall be exported to given remote */
215 p_m_remote_id = 0; /* channel shall be exported to given remote */
216 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
224 p_m_crypt_listen = 0;
225 p_m_crypt_msg_loops = 0;
226 p_m_crypt_msg_loops = 0;
227 p_m_crypt_msg_len = 0;
228 p_m_crypt_msg[0] = '\0';
229 p_m_crypt_msg_current = 0;
230 p_m_crypt_key_len = 0;
231 p_m_crypt_listen = 0;
232 p_m_crypt_listen_state = 0;
233 p_m_crypt_listen_len = 0;
234 p_m_crypt_listen_msg[0] = '\0';
235 p_m_crypt_listen_crc = 0;
236 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
238 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
239 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
243 /* if any channel requested by constructor */
244 if (channel == CHANNEL_ANY)
246 /* reserve channel */
248 mISDNport->b_reserved++;
251 /* reserve channel */
252 if (channel > 0) // only if constructor was called with a channel resevation
253 seize_bchannel(channel, exclusive);
255 /* we increase the number of objects: */
257 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
266 struct message *message;
268 /* remove bchannel relation */
274 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
275 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
276 message->param.disconnectinfo.cause = 16;
277 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
278 message_put(message);
279 /* remove from list */
280 free_epointlist(p_epointlist);
283 /* we decrease the number of objects: */
284 p_m_mISDNport->use--;
285 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
292 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
294 /* init trace with given values */
295 start_trace(mISDNport?mISDNport->portnum:0,
296 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
297 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
298 port?port->p_dialinginfo.id:NULL,
301 port?port->p_serial:0,
309 static struct isdn_message {
313 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
314 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
315 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
316 {"DL_RELEASE", L2_RELEASE_REQ},
317 {"UNKNOWN", L3_UNKNOWN},
318 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
319 {"MT_SETUP", L3_SETUP_REQ},
320 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
321 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
322 {"MT_ALERTING", L3_ALERTING_REQ},
323 {"MT_CONNECT", L3_CONNECT_REQ},
324 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
325 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
326 {"MT_RELEASE", L3_RELEASE_REQ},
327 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
328 {"MT_INFORMATION", L3_INFORMATION_REQ},
329 {"MT_PROGRESS", L3_PROGRESS_REQ},
330 {"MT_NOTIFY", L3_NOTIFY_REQ},
331 {"MT_SUSPEND", L3_SUSPEND_REQ},
332 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
333 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
334 {"MT_RESUME", L3_RESUME_REQ},
335 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
336 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
337 {"MT_HOLD", L3_HOLD_REQ},
338 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
339 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
340 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
341 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
342 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
343 {"MT_FACILITY", L3_FACILITY_REQ},
344 {"MT_STATUS", L3_STATUS_REQ},
345 {"MT_RESTART", L3_RESTART_REQ},
347 {"MT_ASSIGN", L3_ASSIGN_REQ},
348 {"MT_FREE", L3_FREE_REQ},
350 {"MT_NEW_CR", L3_NEW_CR_REQ},
351 {"MT_RELEASE_CR", L3_RELEASE_CR_REQ},
356 static char *isdn_prim[4] = {
362 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long msg, int direction)
365 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
367 /* select message and primitive text */
369 while(isdn_message[i].name)
371 if (isdn_message[i].value == (msg&0xffffff00))
373 SCPY(msgtext, isdn_message[i].name);
378 SCAT(msgtext, isdn_prim[msg&0x00000003]);
381 if (direction && (msg&0xffffff00)!=L3_NEW_CR_REQ && (msg&0xffffff00)!=L3_RELEASE_CR_REQ)
385 if (mISDNport->ntmode)
387 if (direction == DIRECTION_OUT)
388 SCAT(msgtext, " N->U");
390 SCAT(msgtext, " N<-U");
393 if (direction == DIRECTION_OUT)
394 SCAT(msgtext, " U->N");
396 SCAT(msgtext, " U<-N");
401 /* init trace with given values */
402 start_trace(mISDNport?mISDNport->portnum:0,
403 mISDNport?mISDNport->ifport->interface:NULL,
404 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
405 port?port->p_dialinginfo.id:NULL,
408 port?port->p_serial:0,
414 * send control information to the channel (dsp-module)
416 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
419 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
420 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
421 unsigned long *d = buffer+MISDN_HEADER_LEN;
424 ctrl->prim = PH_CONTROL_REQ;
428 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
430 PERROR("Failed to send to socket %d\n", handle);
432 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
433 iframe_t *ctrl = (iframe_t *)buffer;
434 unsigned long *d = (unsigned long *)&ctrl->data.p;
436 ctrl->prim = PH_CONTROL | REQUEST;
437 ctrl->addr = handle | FLG_MSG_DOWN;
439 ctrl->len = sizeof(int)*2;
442 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
444 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
445 if (c1 == CMX_CONF_JOIN)
446 add_trace(trace_name, NULL, "0x%08x", trace_value);
448 add_trace(trace_name, NULL, "%d", trace_value);
452 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)
455 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
456 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
457 unsigned long *d = buffer+MISDN_HEADER_LEN;
460 ctrl->prim = PH_CONTROL_REQ;
463 memcpy(d, c2, c2_len);
464 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
466 PERROR("Failed to send to socket %d\n", handle);
468 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
469 iframe_t *ctrl = (iframe_t *)buffer;
470 unsigned long *d = (unsigned long *)&ctrl->data.p;
472 ctrl->prim = PH_CONTROL | REQUEST;
473 ctrl->addr = handle | FLG_MSG_DOWN;
475 ctrl->len = sizeof(int)+c2_len;
477 memcpy(d, c2, c2_len);
478 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
480 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
481 add_trace(trace_name, NULL, "%d", trace_value);
487 * subfunction for bchannel_event
490 static int _bchannel_create(struct mISDNport *mISDNport, int i)
492 unsigned char buff[1024];
495 unsigned long on = 1;
496 struct sockadd_mISDN addr;
498 if (mISDNport->b_socket[i])
500 PERROR("Error: Socket already created for index %d\n", i);
505 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
506 if (mISDNport->b_socket[i] < 0)
508 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
512 /* set nonblocking io */
513 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
516 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
517 close(mISDNport->b_socket[i]);
518 mISDNport->b_socket[i] = -1;
522 /* bind socket to bchannel */
523 addr.family = AF_ISDN;
524 addr.dev = mISDNport->port-1;
525 addr.channel = i+1+(i>=15);
526 ret = bind(di->bchan, (struct sockaddr *)&addr, sizeof(addr));
529 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
530 close(mISDNport->b_socket[i]);
531 mISDNport->b_socket[i] = -1;
535 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
536 add_trace("channel", NULL, "%d", i+1+(i>=15));
537 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
543 if (!mISDNport->b_stid[i])
545 PERROR("Error: no stack for index %d\n", i);
548 if (mISDNport->b_addr[i])
550 PERROR("Error: stack already created for index %d\n", i);
554 /* create new layer */
555 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
556 memset(&li, 0, sizeof(li));
557 memset(&pid, 0, sizeof(pid));
560 li.st = mISDNport->b_stid[i];
561 UCPY(li.name, "B L4");
562 li.pid.layermask = ISDN_LAYER((4));
563 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
564 ret = mISDN_new_layer(mISDNdevice, &li);
568 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
571 mISDNport->b_addr[i] = li.id;
574 goto failed_new_layer;
576 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
578 /* create new stack */
579 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
580 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
581 pid.protocol[3] = ISDN_PID_L3_B_DSP;
582 pid.protocol[4] = ISDN_PID_L4_B_USER;
583 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
584 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
588 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
589 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
592 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
597 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
598 if (!mISDNport->b_addr[i])
600 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
601 add_trace("channel", NULL, "%d", i+1+(i>=15));
602 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
603 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
610 mISDNport->b_addr[i] = 0;
616 * subfunction for bchannel_event
617 * activate / deactivate request
619 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
622 struct mISDNhead act;
625 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
627 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
629 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
633 /* activate bchannel */
634 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
635 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
638 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
642 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
643 add_trace("channel", NULL, "%d", i+1+(i>=15));
644 if (mISDNport->b_timer[i])
645 add_trace("event", NULL, "timeout recovery");
651 * subfunction for bchannel_event
654 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
660 handle = mISDNport->b_socket[i];
662 unsigned long handle;
664 handle = mISDNport->b_addr[i];
666 port = mISDNport->b_port[i];
669 PERROR("bchannel index i=%d not associated with a port object\n", i);
673 /* set dsp features */
675 if (port->p_m_txdata)
676 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
678 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
680 if (port->p_m_tx_gain)
681 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
682 if (port->p_m_rx_gain)
683 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
685 if (port->p_m_pipeline[0])
686 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
689 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
691 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
693 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
695 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
696 // if (port->p_m_txmix)
697 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
699 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
701 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);
705 * subfunction for bchannel_event
708 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
711 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
712 add_trace("channel", NULL, "%d", i+1+(i>=15));
713 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
715 if (mISDNport->b_socket[i] > -1)
717 close(mISDNport->b_socket[i]);
718 mISDNport->b_socket[i] = -1;
721 unsigned char buff[1024];
723 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
724 add_trace("channel", NULL, "%d", i+1+(i>=15));
725 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
726 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
728 /* remove our stack only if set */
729 if (mISDNport->b_addr[i])
731 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
732 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
733 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
734 mISDNport->b_addr[i] = 0;
744 A bchannel goes through the following states in this order:
747 No one is using the bchannel.
748 It is available and not linked to Port class, nor reserved.
751 The bchannel stack is created and an activation request is sent.
752 It MAY be linked to Port class, but already unlinked due to Port class removal.
755 The bchannel is active and cofigured to the Port class needs.
756 Also it is linked to a Port class, otherwhise it would be deactivated.
758 - B_STATE_DEACTIVATING
759 The bchannel is in deactivating state, due to deactivation request.
760 It may be linked to a Port class, that likes to reactivate it.
764 After deactivating bchannel, and if not used, the bchannel becomes idle again.
766 Also the bchannel may be exported, but only if the state is or becomes idle:
769 The bchannel assignment has been sent to the remove application.
772 The bchannel assignment is acknowledged by the remote application.
775 The bchannel is re-imported by mISDN port object.
779 After re-importing bchannel, and if not used, the bchannel becomes idle again.
782 A bchannel can have the following events:
785 A bchannel is required by a Port class.
786 The bchannel shall be exported to the remote application.
789 The bchannel beomes active.
792 The bchannel is not required by Port class anymore
794 - B_EVENT_DEACTIVATED
795 The bchannel becomes inactive.
798 The bchannel is now used by remote application.
801 The bchannel is not used by remote application.
803 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
805 if an export request is receive by remote application, p_m_remote_* is set.
806 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.)
807 - set on export request from remote application (if port is assigned)
808 - set on channel use, if requested by remote application (p_m_remote_*)
809 - cleared on drop request
811 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
812 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
813 the bchannel import/export is acknowledged with stack given.
815 if exporting, b_remote_*[index] is set to the remote socket id.
816 if importing has been acknowledged. b_remote_*[index] is cleared.
821 * process bchannel events
822 * - mISDNport is a pointer to the port's structure
823 * - i is the index of the bchannel
824 * - event is the B_EVENT_* value
825 * - port is the PmISDN class pointer
827 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
829 class PmISDN *b_port = mISDNport->b_port[i];
830 int state = mISDNport->b_state[i];
831 double timer = mISDNport->b_timer[i];
832 unsigned long p_m_remote_ref = 0;
833 unsigned long p_m_remote_id = 0;
836 char *p_m_pipeline = NULL;
837 unsigned char *p_m_crypt_key = NULL;
838 int p_m_crypt_key_len = 0;
839 int p_m_crypt_key_type = 0;
841 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
843 unsigned long portid = mISDNport->b_stid[i];
848 p_m_remote_id = b_port->p_m_remote_id;
849 p_m_remote_ref = b_port->p_m_remote_ref;
850 p_m_tx_gain = b_port->p_m_tx_gain;
851 p_m_rx_gain = b_port->p_m_rx_gain;
852 p_m_pipeline = b_port->p_m_pipeline;
853 p_m_crypt_key = b_port->p_m_crypt_key;
854 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
855 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
861 /* port must be linked in order to allow activation */
863 FATAL("bchannel must be linked to a Port class\n");
869 /* export bchannel */
870 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);
871 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
872 add_trace("type", NULL, "assign");
874 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
876 add_trace("socket", "id", "%d", portid);
879 state = B_STATE_EXPORTING;
880 mISDNport->b_remote_id[i] = p_m_remote_id;
881 mISDNport->b_remote_ref[i] = p_m_remote_ref;
884 /* create stack and send activation request */
885 if (_bchannel_create(mISDNport, i))
887 _bchannel_activate(mISDNport, i, 1);
888 state = B_STATE_ACTIVATING;
889 timer = now_d + B_TIMER_ACTIVATING;
894 case B_STATE_ACTIVATING:
895 case B_STATE_EXPORTING:
896 /* do nothing, because it is already activating */
899 case B_STATE_DEACTIVATING:
900 case B_STATE_IMPORTING:
901 /* do nothing, because we must wait until we can reactivate */
905 /* problems that might ocurr:
906 * B_EVENT_USE is received when channel already in use.
907 * bchannel exported, but not freed by other port
909 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
913 case B_EVENT_EXPORTREQUEST:
914 /* special case where the bchannel is requested by remote */
917 PERROR("export request without remote channel set, please correct.\n");
923 /* in case, the bchannel is exported right after seize_bchannel */
924 /* export bchannel */
925 /* p_m_remote_id is set, when this event happens. */
926 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);
927 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
928 add_trace("type", NULL, "assign");
930 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
932 add_trace("socket", "id", "%d", portid);
935 state = B_STATE_EXPORTING;
936 mISDNport->b_remote_id[i] = p_m_remote_id;
937 mISDNport->b_remote_ref[i] = p_m_remote_ref;
940 case B_STATE_ACTIVATING:
941 case B_STATE_EXPORTING:
942 /* do nothing, because it is already activating */
945 case B_STATE_DEACTIVATING:
946 case B_STATE_IMPORTING:
947 /* do nothing, because we must wait until we can reactivate */
951 /* bchannel is active, so we deactivate */
952 _bchannel_activate(mISDNport, i, 0);
953 state = B_STATE_DEACTIVATING;
954 timer = now_d + B_TIMER_DEACTIVATING;
958 /* problems that might ocurr:
959 * ... when channel already in use.
960 * bchannel exported, but not freed by other port
962 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
966 case B_EVENT_ACTIVATED:
970 case B_STATE_ACTIVATING:
971 if (b_port && !p_m_remote_id)
973 /* bchannel is active and used by Port class, so we configure bchannel */
974 _bchannel_configure(mISDNport, i);
975 state = B_STATE_ACTIVE;
978 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
979 _bchannel_activate(mISDNport, i, 0);
980 state = B_STATE_DEACTIVATING;
981 timer = now_d + B_TIMER_DEACTIVATING;
986 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
990 case B_EVENT_EXPORTED:
993 case B_STATE_EXPORTING:
994 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
996 /* remote export done */
997 state = B_STATE_REMOTE;
1000 /* bchannel is now exported, but we need bchannel back
1001 * OR bchannel is not used anymore
1002 * OR bchannel has been exported to an obsolete ref,
1003 * so reimport, to later export to new remote */
1004 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1005 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1006 add_trace("type", NULL, "remove");
1008 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1010 add_trace("socket", "id", "%d", portid);
1013 state = B_STATE_IMPORTING;
1018 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1024 FATAL("bchannel must be linked to a Port class\n");
1028 /* bchannel is idle due to an error, so we do nothing */
1031 case B_STATE_ACTIVATING:
1032 case B_STATE_EXPORTING:
1033 /* do nothing because we must wait until bchanenl is active before deactivating */
1036 case B_STATE_ACTIVE:
1037 /* bchannel is active, so we deactivate */
1038 _bchannel_activate(mISDNport, i, 0);
1039 state = B_STATE_DEACTIVATING;
1040 timer = now_d + B_TIMER_DEACTIVATING;
1043 case B_STATE_REMOTE:
1044 /* bchannel is exported, so we re-import */
1045 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1046 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1047 add_trace("type", NULL, "remove");
1049 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1051 add_trace("socket", "id", "%d", portid);
1054 state = B_STATE_IMPORTING;
1057 case B_STATE_DEACTIVATING:
1058 case B_STATE_IMPORTING:
1059 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1063 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1067 case B_EVENT_DEACTIVATED:
1072 /* ignore due to deactivation confirm after unloading */
1075 case B_STATE_DEACTIVATING:
1076 _bchannel_destroy(mISDNport, i);
1077 state = B_STATE_IDLE;
1080 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1083 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);
1084 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1085 add_trace("type", NULL, "assign");
1087 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1089 add_trace("socket", "id", "%d", portid);
1092 state = B_STATE_EXPORTING;
1093 mISDNport->b_remote_id[i] = p_m_remote_id;
1094 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1097 if (_bchannel_create(mISDNport, i))
1099 _bchannel_activate(mISDNport, i, 1);
1100 state = B_STATE_ACTIVATING;
1101 timer = now_d + B_TIMER_ACTIVATING;
1108 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1112 case B_EVENT_IMPORTED:
1115 case B_STATE_IMPORTING:
1116 state = B_STATE_IDLE;
1117 mISDNport->b_remote_id[i] = 0;
1118 mISDNport->b_remote_ref[i] = 0;
1121 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1124 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);
1125 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1126 add_trace("type", NULL, "assign");
1128 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1130 add_trace("socket", "id", "%d", portid);
1133 state = B_STATE_EXPORTING;
1134 mISDNport->b_remote_id[i] = p_m_remote_id;
1135 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1138 if (_bchannel_create(mISDNport, i))
1140 _bchannel_activate(mISDNport, i, 1);
1141 state = B_STATE_ACTIVATING;
1142 timer = now_d + B_TIMER_ACTIVATING;
1149 /* ignore, because not assigned */
1154 case B_EVENT_TIMEOUT:
1159 /* ignore due to deactivation confirm after unloading */
1162 case B_STATE_ACTIVATING:
1163 _bchannel_activate(mISDNport, i, 1);
1164 timer = now_d + B_TIMER_ACTIVATING;
1167 case B_STATE_DEACTIVATING:
1168 _bchannel_activate(mISDNport, i, 0);
1169 timer = now_d + B_TIMER_DEACTIVATING;
1173 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1178 PERROR("Illegal event %d, please correct.\n", event);
1181 mISDNport->b_state[i] = state;
1182 mISDNport->b_timer[i] = timer;
1189 * check for available channel and reserve+set it.
1190 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1191 * give exclusiv flag
1192 * returns -(cause value) or x = channel x or 0 = no channel
1193 * NOTE: no activation is done here
1195 int PmISDN::seize_bchannel(int channel, int exclusive)
1199 /* the channel is what we have */
1200 if (p_m_b_channel == channel)
1203 /* if channel already in use, release it */
1208 if (channel==CHANNEL_NO || channel==0)
1211 /* is channel in range ? */
1213 || (channel>p_m_mISDNport->b_num && channel<16)
1214 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1215 return(-6); /* channel unacceptable */
1217 /* request exclusive channel */
1218 if (exclusive && channel>0)
1220 i = channel-1-(channel>16);
1221 if (p_m_mISDNport->b_port[i])
1222 return(-44); /* requested channel not available */
1226 /* ask for channel */
1229 i = channel-1-(channel>16);
1230 if (p_m_mISDNport->b_port[i] == NULL)
1234 /* search for channel */
1236 while(i < p_m_mISDNport->b_num)
1238 if (!p_m_mISDNport->b_port[i])
1240 channel = i+1+(i>=15);
1245 return(-34); /* no free channel */
1248 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1251 p_m_mISDNport->b_port[i] = this;
1253 p_m_b_channel = channel;
1254 p_m_b_exclusive = exclusive;
1256 /* reserve channel */
1260 p_m_mISDNport->b_reserved++;
1267 * drop reserved channel and unset it.
1268 * deactivation is also done
1270 void PmISDN::drop_bchannel(void)
1272 /* unreserve channel */
1274 p_m_mISDNport->b_reserved--;
1278 if (p_m_b_index < 0)
1283 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1285 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1286 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1287 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1290 p_m_b_exclusive = 0;
1293 /* process bchannel export/import message from join */
1294 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1296 class Endpoint *epoint;
1298 class PmISDN *isdnport;
1299 struct mISDNport *mISDNport;
1304 case BCHANNEL_REQUEST:
1305 /* find the port object for the join object ref */
1306 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1308 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1311 if (!epoint->ep_portlist)
1313 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1316 if (epoint->ep_portlist->next)
1318 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);
1320 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1322 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1325 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1327 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1329 isdnport = (class PmISDN *)port;
1332 if (isdnport->p_m_remote_id)
1334 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1337 mISDNport = isdnport->p_m_mISDNport;
1338 i = isdnport->p_m_b_index;
1339 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1340 add_trace("type", NULL, "export request");
1341 isdnport->p_m_remote_ref = joinremote->j_serial;
1342 isdnport->p_m_remote_id = joinremote->j_remote_id;
1343 if (mISDNport && i>=0)
1345 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1350 case BCHANNEL_ASSIGN_ACK:
1351 case BCHANNEL_REMOVE_ACK:
1352 /* find mISDNport for stack ID */
1353 mISDNport = mISDNport_first;
1357 ii = mISDNport->b_num;
1361 if (mISDNport->b_socket[i] == handle)
1363 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1370 mISDNport = mISDNport->next;
1374 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1377 /* mISDNport may now be set or NULL */
1380 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1381 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1382 if (mISDNport && i>=0)
1383 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1387 PERROR("received wrong bchannel message type %d from remote\n", type);
1395 audio transmission procedure:
1396 -----------------------------
1399 three sources of audio transmission:
1400 - crypto-data high priority
1401 - tones high priority (also high)
1402 - remote-data low priority
1405 a variable that temporarily shows the number of samples elapsed since last transmission process.
1406 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1409 a variable that is increased whenever data is transmitted.
1410 it is decreased while time elapses. it stores the number of samples that
1411 are currently loaded to dsp module.
1412 since clock in dsp module is the same clock for user space process, these
1416 there are two levels:
1417 ISDN_LOAD will give the load that have to be kept in dsp.
1418 ISDN_MAXLOAD will give the maximum load before dropping.
1420 * procedure for low priority data
1421 see txfromup() for procedure
1422 in short: remote data is ignored during high priority tones
1424 * procedure for high priority data
1425 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1426 if no more data is available, load becomes empty again.
1429 0 ISDN_LOAD ISDN_MAXLOAD
1430 +--------------------+----------------------+
1432 +--------------------+----------------------+
1434 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1435 0 ISDN_LOAD ISDN_MAXLOAD
1436 +--------------------+----------------------+
1437 |TTTTTTTTTTTTTTTTTTTT| |
1438 +--------------------+----------------------+
1440 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1441 0 ISDN_LOAD ISDN_MAXLOAD
1442 +--------------------+----------------------+
1443 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1444 +--------------------+----------------------+
1447 int PmISDN::handler(void)
1449 struct message *message;
1453 if ((ret = Port::handler()))
1457 if (p_m_last_tv_sec)
1459 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1460 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1463 /* set clock of first process ever in this instance */
1464 p_m_last_tv_sec = now_tv.tv_sec;
1465 p_m_last_tv_msec = now_tv.tv_usec/1000;
1467 /* process only if we have a minimum of samples, to make packets not too small */
1468 if (elapsed >= ISDN_TRANSMIT)
1470 /* set clock of last process! */
1471 p_m_last_tv_sec = now_tv.tv_sec;
1472 p_m_last_tv_msec = now_tv.tv_usec/1000;
1475 if (elapsed < p_m_load)
1476 p_m_load -= elapsed;
1480 /* to send data, tone must be active OR crypt messages must be on */
1481 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1482 && (p_m_load < ISDN_LOAD)
1483 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1485 int tosend = ISDN_LOAD - p_m_load, length;
1487 unsigned char buf[MISDN_HEADER_LEN+tosend];
1488 struct mISDNhead *frm = (struct mISDNhead *)buf;
1489 unsigned long *d = buf+MISDN_HEADER_LEN;
1491 unsigned char buf[mISDN_HEADER_LEN+tosend];
1492 iframe_t *frm = (iframe_t *)buf;
1493 unsigned char *p = buf+mISDN_HEADER_LEN;
1496 /* copy crypto loops */
1497 while (p_m_crypt_msg_loops && tosend)
1499 /* how much do we have to send */
1500 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1503 if (length > tosend)
1506 /* copy message (part) to buffer */
1507 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1510 p_m_crypt_msg_current += length;
1511 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1514 p_m_crypt_msg_current = 0;
1515 p_m_crypt_msg_loops--;
1516 // puts("eine loop weniger");
1524 if (p_tone_name[0] && tosend)
1526 tosend -= read_audio(p, tosend);
1531 frm->prim = DL_DATA_REQ;
1533 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1535 PERROR("Failed to send to socket %d\n", handle);
1537 frm->prim = DL_DATA | REQUEST;
1538 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1540 frm->len = ISDN_LOAD - p_m_load - tosend;
1543 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1544 p_m_load += frm->len;
1548 // NOTE: deletion is done by the child class
1550 /* handle timeouts */
1553 if (p_m_timer+p_m_timeout < now_d)
1555 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1557 /* send timeout to endpoint */
1558 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1559 message->param.state = p_state;
1560 message_put(message);
1565 return(0); /* nothing done */
1570 * whenever we get audio data from bchannel, we process it here
1573 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1575 unsigned long cont = *((unsigned long *)data);
1577 void PmISDN::bchannel_receive(iframe_t *frm)
1580 unsigned long cont = *((unsigned long *)&frm->data.p);
1581 unsigned char *data =(unsigned char *)&frm->data.p;
1583 unsigned char *data_temp;
1584 unsigned long length_temp;
1585 struct message *message;
1590 if (hh->prim == PH_CONTROL_IND)
1592 if (frm->prim == (PH_CONTROL | INDICATION))
1597 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1600 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1602 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1603 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1605 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1606 message->param.dtmf = cont & DTMF_TONE_MASK;
1607 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1608 message_put(message);
1614 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1615 add_trace("DSP-CRYPT", NULL, "error");
1617 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1618 message->param.crypt.type = CC_ERROR_IND;
1619 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1620 message_put(message);
1624 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1625 add_trace("DSP-CRYPT", NULL, "ok");
1627 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1628 message->param.crypt.type = CC_ACTBF_CONF;
1629 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1630 message_put(message);
1634 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1635 add_trace("unknown", NULL, "0x%x", cont);
1641 if (hh->prim == PH_SIGNAL_IND)
1643 if (frm->prim == (PH_SIGNAL | INDICATION))
1652 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1653 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1656 /* see below (same condition) */
1657 if (p_state!=PORT_STATE_CONNECT
1658 && !p_m_mISDNport->tones)
1660 // printf(".");fflush(stdout);return;
1662 record(data, len, 1); // from up
1667 chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
1668 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1674 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1676 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1678 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1680 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1684 /* calls will not process any audio data unless
1685 * the call is connected OR interface features audio during call setup.
1687 //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);
1688 #ifndef DEBUG_COREBRIDGE
1689 if (p_state!=PORT_STATE_CONNECT
1690 && !p_m_mISDNport->tones)
1694 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1697 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1703 record(data, len, 0); // from down
1705 /* randomize and listen to crypt message if enabled */
1706 if (p_m_crypt_listen)
1708 /* the noisy randomizer */
1712 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1714 cryptman_listen_bch(data, len);
1719 /* send data to epoint */
1720 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1726 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1727 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1728 memcpy(message->param.data.data, data_temp, message->param.data.len);
1729 message_put(message);
1730 if (length_temp <= sizeof(message->param.data.data))
1732 data_temp += sizeof(message->param.data.data);
1733 length_temp -= sizeof(message->param.data.data);
1742 void PmISDN::set_echotest(int echo)
1744 if (p_m_echo != echo)
1747 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1749 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1751 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);
1753 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);
1761 void PmISDN::set_tone(char *dir, char *tone)
1767 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1774 /* check if we NOT really have to use a dsp-tone */
1775 if (!options.dsptones)
1779 if (p_m_b_index >= 0)
1780 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1782 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1784 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1786 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1790 Port::set_tone(dir, tone);
1796 /* now we USE dsp-tone, convert name */
1797 else if (!strcmp(tone, "dialtone"))
1799 switch(options.dsptones) {
1800 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1801 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1802 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1804 } else if (!strcmp(tone, "dialpbx"))
1806 switch(options.dsptones) {
1807 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1808 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1809 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1811 } else if (!strcmp(tone, "ringing"))
1813 switch(options.dsptones) {
1814 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1815 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1816 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1818 } else if (!strcmp(tone, "ringpbx"))
1820 switch(options.dsptones) {
1821 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1822 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1823 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1825 } else if (!strcmp(tone, "busy"))
1828 switch(options.dsptones) {
1829 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1830 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1831 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1833 } else if (!strcmp(tone, "release"))
1836 switch(options.dsptones) {
1837 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1838 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1839 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1841 } else if (!strcmp(tone, "cause_10"))
1843 else if (!strcmp(tone, "cause_11"))
1845 else if (!strcmp(tone, "cause_22"))
1847 switch(options.dsptones) {
1848 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1849 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1850 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1852 } else if (!strncmp(tone, "cause_", 6))
1853 id = TONE_SPECIAL_INFO;
1857 /* if we have a tone that is not supported by dsp */
1858 if (id==TONE_OFF && tone[0])
1866 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1867 if (p_m_b_index >= 0)
1868 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1870 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);
1872 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);
1875 /* turn user-space tones off in cases of no tone OR dsp tone */
1876 Port::set_tone("",NULL);
1880 /* MESSAGE_mISDNSIGNAL */
1881 //extern struct message *dddebug;
1882 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1884 switch(param->mISDNsignal.message)
1886 case mISDNSIGNAL_VOLUME:
1887 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1889 p_m_tx_gain = param->mISDNsignal.tx_gain;
1890 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1891 if (p_m_b_index >= 0)
1892 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1894 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);
1896 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);
1899 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1900 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1902 p_m_rx_gain = param->mISDNsignal.rx_gain;
1903 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1904 if (p_m_b_index >= 0)
1905 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1907 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);
1909 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);
1912 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1915 case mISDNSIGNAL_CONF:
1916 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1917 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1918 if (p_m_conf != param->mISDNsignal.conf)
1920 p_m_conf = param->mISDNsignal.conf;
1921 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1922 if (p_m_b_index >= 0)
1923 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1925 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);
1927 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);
1930 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1931 /* we must set, even if currently tone forbids conf */
1932 p_m_conf = param->mISDNsignal.conf;
1933 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1936 case mISDNSIGNAL_JOINDATA:
1937 if (p_m_joindata != param->mISDNsignal.joindata)
1939 p_m_joindata = param->mISDNsignal.joindata;
1940 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1942 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1945 case mISDNSIGNAL_DELAY:
1946 if (p_m_delay != param->mISDNsignal.delay)
1948 p_m_delay = param->mISDNsignal.delay;
1949 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1951 if (p_m_b_index >= 0)
1952 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1954 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);
1956 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);
1960 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1964 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1969 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1971 struct message *message;
1973 switch(param->crypt.type)
1975 case CC_ACTBF_REQ: /* activate blowfish */
1977 p_m_crypt_key_len = param->crypt.len;
1978 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1980 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1981 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1982 message->param.crypt.type = CC_ERROR_IND;
1983 message_put(message);
1986 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1988 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1989 if (p_m_b_index >= 0)
1990 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1992 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);
1994 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);
1998 case CC_DACT_REQ: /* deactivate session encryption */
2003 case CR_LISTEN_REQ: /* start listening to messages */
2004 p_m_crypt_listen = 1;
2005 p_m_crypt_listen_state = 0;
2008 case CR_UNLISTEN_REQ: /* stop listening to messages */
2009 p_m_crypt_listen = 0;
2012 case CR_MESSAGE_REQ: /* send message */
2013 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2014 if (!p_m_crypt_msg_len)
2016 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2019 p_m_crypt_msg_current = 0; /* reset */
2020 p_m_crypt_msg_loops = 6; /* enable */
2022 /* disable txmix, or we get corrupt data due to audio process */
2023 if (p_m_txmix && p_m_b_index>=0)
2025 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2027 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2029 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2036 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2042 * endpoint sends messages to the port
2044 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2046 if (Port::message_epoint(epoint_id, message_id, param))
2051 case MESSAGE_DATA: /* tx-data from upper layer */
2052 txfromup(param->data.data, param->data.len);
2055 case MESSAGE_mISDNSIGNAL: /* user command */
2056 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2057 message_mISDNsignal(epoint_id, message_id, param);
2060 case MESSAGE_CRYPT: /* crypt control command */
2061 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2062 message_crypt(epoint_id, message_id, param);
2071 * main loop for processing messages from mISDN
2074 int mISDN_handler(void)
2077 struct mISDNport *mISDNport;
2078 class PmISDN *isdnport;
2080 char buffer[2048+MISDN_HEADER_LEN];
2081 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2083 /* process all ports */
2084 mISDNport = mISDNport_first;
2087 /* process all bchannels */
2089 while(i < mISDNport->b_num)
2091 /* process timer events for bchannel handling */
2092 if (mISDNport->b_timer[i])
2094 if (mISDNport->b_timer[i] <= now_d)
2095 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2097 /* handle port of bchannel */
2098 isdnport=mISDNport->b_port[i];
2101 /* call bridges in user space OR crypto OR recording */
2102 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2104 /* rx IS required */
2105 if (isdnport->p_m_rxoff)
2108 isdnport->p_m_rxoff = 0;
2109 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2110 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2111 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2116 /* rx NOT required */
2117 if (!isdnport->p_m_rxoff)
2120 isdnport->p_m_rxoff = 1;
2121 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2122 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2123 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2128 if (isdnport->p_record)
2130 /* txdata IS required */
2131 if (!isdnport->p_m_txdata)
2134 isdnport->p_m_txdata = 1;
2135 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2136 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2137 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2142 /* txdata NOT required */
2143 if (isdnport->p_m_txdata)
2146 isdnport->p_m_txdata = 0;
2147 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2148 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2149 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2155 /* handle message from bchannel */
2156 if (mISDNport->b_stack[i] > -1)
2158 ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
2159 if (ret >= MISDN_HEADER_LEN)
2164 /* we don't care about confirms, we use rx data to sync tx */
2169 /* we receive audio data, we respond to it AND we send tones */
2173 case PH_CONTROL_IND:
2174 if (mISDNport->b_port[i])
2175 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2177 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_stack[i]);
2180 case PH_ACTIVATE_IND:
2181 case DL_ESTABLISH_IND:
2182 case PH_ACTIVATE_CONF:
2183 case DL_ESTABLISH_CONF:
2184 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2185 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2188 case PH_DEACTIVATE_IND:
2189 case DL_RELEASE_IND:
2190 case PH_DEACTIVATE_CONF:
2191 case DL_RELEASE_CONF:
2192 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2193 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2197 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], msg->len);
2201 if (ret < 0 && errno != EWOULDBLOCK)
2202 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2209 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2211 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2212 mISDNport->l1timeout = 0;
2215 /* layer 2 establish timer */
2216 if (mISDNport->l2establish)
2218 if (now-mISDNport->l2establish > 5)
2221 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2222 mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2223 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2230 mISDNport = mISDNport->next;
2233 /* if we received at least one b-frame, we will return 1 */
2237 int mISDN_handler(void)
2240 struct mISDNport *mISDNport;
2241 class PmISDN *isdnport;
2246 mISDNuser_head_t *hh;
2249 /* the que avoids loopbacks when replying to stack after receiving
2251 mISDNport = mISDNport_first;
2254 /* process turning on/off rx */
2256 while(i < mISDNport->b_num)
2258 /* process timer events for bchannel handling */
2259 if (mISDNport->b_timer[i])
2261 if (mISDNport->b_timer[i] <= now_d)
2262 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2264 isdnport=mISDNport->b_port[i];
2267 /* call bridges in user space OR crypto OR recording */
2268 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2270 /* rx IS required */
2271 if (isdnport->p_m_rxoff)
2274 isdnport->p_m_rxoff = 0;
2275 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2276 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2277 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2282 /* rx NOT required */
2283 if (!isdnport->p_m_rxoff)
2286 isdnport->p_m_rxoff = 1;
2287 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2288 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2289 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2294 if (isdnport->p_record)
2296 /* txdata IS required */
2297 if (!isdnport->p_m_txdata)
2300 isdnport->p_m_txdata = 1;
2301 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2303 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2304 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2310 /* txdata NOT required */
2311 if (isdnport->p_m_txdata)
2314 isdnport->p_m_txdata = 0;
2315 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2317 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2318 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2327 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2329 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2330 mISDNport->l1timeout = 0;
2333 if (mISDNport->l2establish)
2335 if (now-mISDNport->l2establish > 5)
2337 if (mISDNport->ntmode)
2339 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2340 time(&mISDNport->l2establish);
2342 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2343 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2348 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2349 time(&mISDNport->l2establish);
2351 act.prim = DL_ESTABLISH | REQUEST;
2352 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2355 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2357 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2362 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2364 if (mISDNport->ntmode)
2366 hh = (mISDNuser_head_t *)dmsg->data;
2367 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);
2368 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2372 frm = (iframe_t *)dmsg->data;
2373 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2374 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2375 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);
2376 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2381 mISDNport = mISDNport->next;
2384 /* no device, no read */
2385 if (mISDNdevice < 0)
2388 /* get message from kernel */
2389 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2391 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2395 if (errno == EAGAIN)
2397 FATAL("Failed to do mISDN_read()\n");
2402 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2406 frm = (iframe_t *)msg->data;
2411 case MGR_DELLAYER | CONFIRM:
2412 case MGR_INITTIMER | CONFIRM:
2413 case MGR_ADDTIMER | CONFIRM:
2414 case MGR_DELTIMER | CONFIRM:
2415 case MGR_REMOVETIMER | CONFIRM:
2420 /* handle timer events from mISDN for NT-stack
2421 * note: they do not associate with a stack */
2422 if (frm->prim == (MGR_TIMER | INDICATION))
2426 /* find mISDNport */
2427 mISDNport = mISDNport_first;
2431 if (mISDNport->ntmode)
2433 it = mISDNport->nst.tlist;
2437 if (it->id == (int)frm->addr)
2444 mISDNport = mISDNport->next;
2448 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2449 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2451 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2452 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2453 ret = it->function(it->data);
2456 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2461 /* find the mISDNport that belongs to the stack */
2462 mISDNport = mISDNport_first;
2465 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2467 mISDNport = mISDNport->next;
2471 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2472 // show a list of all mISDNports and their address
2474 mISDNport = mISDNport_first;
2477 PERROR(" port %s %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2478 mISDNport = mISDNport->next;
2485 if (!(frm->addr&FLG_CHILD_STACK))
2490 case MGR_SHORTSTATUS | INDICATION:
2491 case MGR_SHORTSTATUS | CONFIRM:
2492 switch(frm->dinfo) {
2493 case SSTATUS_L1_ACTIVATED:
2494 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2497 case SSTATUS_L1_DEACTIVATED:
2498 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2501 case SSTATUS_L2_ESTABLISHED:
2502 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2505 case SSTATUS_L2_RELEASED:
2506 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2512 case PH_ACTIVATE | CONFIRM:
2513 case PH_ACTIVATE | INDICATION:
2514 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2516 if (mISDNport->ntmode)
2518 mISDNport->l1link = 1;
2519 setup_queue(mISDNport, 1);
2523 mISDNport->l1link = 1;
2524 setup_queue(mISDNport, 1);
2527 case PH_DEACTIVATE | CONFIRM:
2528 case PH_DEACTIVATE | INDICATION:
2529 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2531 if (mISDNport->ntmode)
2533 mISDNport->l1link = 0;
2534 setup_queue(mISDNport, 0);
2538 mISDNport->l1link = 0;
2539 setup_queue(mISDNport, 0);
2542 case PH_CONTROL | CONFIRM:
2543 case PH_CONTROL | INDICATION:
2544 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2547 case DL_ESTABLISH | INDICATION:
2548 case DL_ESTABLISH | CONFIRM:
2549 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2551 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2553 if (mISDNport->l2establish)
2555 mISDNport->l2establish = 0;
2556 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2558 mISDNport->l2link = 1;
2561 case DL_RELEASE | INDICATION:
2562 case DL_RELEASE | CONFIRM:
2563 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2565 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2567 mISDNport->l2link = 0;
2570 time(&mISDNport->l2establish);
2571 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2577 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);
2578 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2580 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2583 if (mISDNport->ntmode)
2585 /* l1-data enters the nt-mode library */
2586 nst = &mISDNport->nst;
2587 if (nst->l1_l2(nst, msg))
2592 /* l3-data is sent to pbx */
2593 if (stack2manager_te(mISDNport, msg))
2604 /* we don't care about confirms, we use rx data to sync tx */
2605 case PH_DATA | CONFIRM:
2606 case DL_DATA | CONFIRM:
2609 /* we receive audio data, we respond to it AND we send tones */
2610 case PH_DATA | INDICATION:
2611 case DL_DATA | INDICATION:
2612 case PH_CONTROL | INDICATION:
2613 case PH_SIGNAL | INDICATION:
2615 while(i < mISDNport->b_num)
2617 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2621 if (i == mISDNport->b_num)
2623 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2626 if (mISDNport->b_port[i])
2628 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2629 mISDNport->b_port[i]->bchannel_receive(frm);
2631 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2634 case PH_ACTIVATE | INDICATION:
2635 case DL_ESTABLISH | INDICATION:
2636 case PH_ACTIVATE | CONFIRM:
2637 case DL_ESTABLISH | CONFIRM:
2638 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2640 while(i < mISDNport->b_num)
2642 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2646 if (i == mISDNport->b_num)
2648 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2651 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2654 case PH_DEACTIVATE | INDICATION:
2655 case DL_RELEASE | INDICATION:
2656 case PH_DEACTIVATE | CONFIRM:
2657 case DL_RELEASE | CONFIRM:
2658 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2660 while(i < mISDNport->b_num)
2662 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2666 if (i == mISDNport->b_num)
2668 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2671 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2675 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2686 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2688 struct mISDNport *mISDNport = ml3->private;
2690 if (cmd == MT_ASSIGN)
2692 if (angeforderte, dann schreiben, weil wir )
2697 pthread_mutex_lock(&mutex_lcr);
2698 achtung MT_ASSIGN kommt hier an
2703 #warning shortstatus
2705 case MGR_SHORTSTATUS_IND:
2706 case MGR_SHORTSTATUS_CONF:
2707 switch(frm->dinfo) {
2708 case SSTATUS_L1_ACTIVATED:
2709 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2712 case SSTATUS_L1_DEACTIVATED:
2713 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2716 case SSTATUS_L2_ESTABLISHED:
2717 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2720 case SSTATUS_L2_RELEASED:
2721 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2729 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2732 mISDNport->l1link = 1;
2734 if (mISDNport->ntmode)
2735 setup_queue(mISDNport, 1);
2739 case MT_L1DEACTIVATE:
2740 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2743 mISDNport->l1link = 0;
2744 raus mit der setup-queue, da dies im stack geschieht
2746 if (mISDNport->ntmode)
2747 setup_queue(mISDNport, 0);
2752 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2753 // special config commands for interface (ip-address/LOS/AIS/RDI/SLIP)
2756 case MT_L2ESTABLISH:
2757 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2760 if (mISDNport->l2establish)
2762 mISDNport->l2establish = 0;
2763 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2765 mISDNport->l2link = 1;
2769 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2772 mISDNport->l2link = 0;
2775 time(&mISDNport->l2establish);
2776 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2781 /* l3-data is sent to LCR */
2782 stack2manager(mISDNport, cmd, pid, l3m);
2790 pthread_mutex_unlock(&mutex_lcr);
2799 * global function to add a new card (port)
2801 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2804 unsigned char buff[1025];
2805 iframe_t *frm = (iframe_t *)buff;
2806 struct mISDNport *mISDNport, **mISDNportp;
2808 int pri, bri, ports;
2811 struct mlayer3 *ml3;
2812 struct mISDN_devinfo devinfo;
2814 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2817 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2821 // interface_info_t ii;
2825 stack_info_t *stinf;
2827 /* query port's requirements */
2828 cnt = mISDN_get_stack_count(mISDNdevice);
2833 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2836 if (port>cnt || port<1)
2838 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2842 pri = bri = ports = nt = te = 0;
2844 devinfo.id = port - 1;
2845 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2848 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2851 /* output the port info */
2852 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2857 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2863 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2870 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2877 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2884 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2890 if (force_nt && !nt)
2892 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2897 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2900 if (pots && !bri && !pri)
2902 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2907 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2912 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2915 /* force nt, by turning off TE */
2918 /* if TE an NT is supported (and not forced to NT), turn off NT */
2922 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2925 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2928 stinf = (stack_info_t *)&frm->data.p;
2929 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2931 case ISDN_PID_L0_TE_S0:
2932 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2934 case ISDN_PID_L0_NT_S0:
2935 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2938 case ISDN_PID_L0_TE_E1:
2939 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2942 case ISDN_PID_L0_NT_E1:
2943 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2948 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2954 if (stinf->pid.protocol[1] == 0)
2956 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2959 if (stinf->pid.protocol[2])
2961 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2968 if (stinf->pid.protocol[1] == 0)
2970 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2973 if (stinf->pid.protocol[2] == 0)
2975 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2978 if (stinf->pid.protocol[3] == 0)
2980 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2984 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2986 case ISDN_PID_L3_DSS1USER:
2990 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2994 if (stinf->pid.protocol[4])
2996 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3002 /* add mISDNport structure */
3003 mISDNportp = &mISDNport_first;
3005 mISDNportp = &((*mISDNportp)->next);
3006 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3008 *mISDNportp = mISDNport;
3010 /* allocate ressources of port */
3013 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
3018 prop |= FLG_FORCE_PTMP;
3019 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
3020 if (!mISDNport->ml3)
3022 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3027 /* if ntmode, establish L1 to send the tei removal during start */
3028 if (mISDNport->ntmode)
3032 act.prim = PH_ACTIVATE | REQUEST;
3033 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3034 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3037 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3038 usleep(10000); /* to be sure, that l1 is up */
3042 SCPY(mISDNport->name, devinfo.name);
3043 mISDNport->b_num = devinfo.nrbchan;
3045 msg_queue_init(&mISDNport->downqueue);
3046 mISDNport->d_stid = stinf->id;
3047 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3048 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
3050 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
3054 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
3059 /* create layer intance */
3060 memset(&li, 0, sizeof(li));
3061 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3064 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3065 li.pid.layermask = ISDN_LAYER((nt?2:4));
3066 li.st = mISDNport->d_stid;
3067 ret = mISDN_new_layer(mISDNdevice, &li);
3070 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3072 mISDNport_close(mISDNport);
3075 mISDNport->upper_id = li.id;
3076 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3079 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3082 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3083 if (mISDNport->lower_id < 0)
3085 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3088 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3089 if (mISDNport->upper_id < 0)
3091 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3094 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3096 /* if ntmode, establish L1 to send the tei removal during start */
3097 if (mISDNport->ntmode)
3101 act.prim = PH_ACTIVATE | REQUEST;
3102 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3103 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3106 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3107 usleep(10000); /* to be sure, that l1 is up */
3110 /* create nst (nt-mode only) */
3113 mgr = &mISDNport->mgr;
3114 nst = &mISDNport->nst;
3119 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3120 nst->device = mISDNdevice;
3122 nst->d_stid = mISDNport->d_stid;
3124 nst->feature = FEATURE_NET_HOLD;
3126 nst->feature |= FEATURE_NET_PTP;
3128 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3131 while(i < mISDNport->b_num)
3133 nst->b_stid[i] = mISDNport->b_stid[i];
3137 nst->l1_id = mISDNport->lower_id;
3138 nst->l2_id = mISDNport->upper_id;
3141 msg_queue_init(&nst->down_queue);
3147 mISDNport->b_num = stinf->childcnt;
3149 mISDNport->portnum = port;
3150 mISDNport->ntmode = nt;
3151 mISDNport->pri = pri;
3152 mISDNport->ptp = ptp;
3153 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3155 while(i < mISDNport->b_num)
3157 mISDNport->b_state[i] = B_STATE_IDLE;
3159 mISDNport->b_socket = -1;
3161 mISDNport->b_stid[i] = stinf->child[i];
3162 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3167 /* if te-mode, query state link */
3168 if (!mISDNport->ntmode)
3172 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3173 act.prim = MGR_SHORTSTATUS | REQUEST;
3174 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3175 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3177 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3179 /* if ptp AND te-mode, pull up the link */
3180 if (mISDNport->ptp && !mISDNport->ntmode)
3184 act.prim = DL_ESTABLISH | REQUEST;
3185 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3188 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3190 /* if ptp AND nt-mode, pull up the link */
3191 if (mISDNport->ptp && mISDNport->ntmode)
3195 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3196 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3199 /* initially, we assume that the link is down, exept for nt-ptmp */
3200 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3202 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3204 start_trace(mISDNport->portnum,
3212 add_trace("channels", NULL, "%d", mISDNport->b_num);
3219 * function to free ALL cards (ports)
3221 void mISDNport_close_all(void)
3223 /* free all ports */
3224 while(mISDNport_first)
3225 mISDNport_close(mISDNport_first);
3229 * free only one port
3231 void mISDNport_close(struct mISDNport *mISDNport)
3233 struct mISDNport **mISDNportp;
3235 class PmISDN *isdnport;
3237 unsigned char buf[32];
3240 /* remove all port instance that are linked to this mISDNport */
3244 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3246 isdnport = (class PmISDN *)port;
3247 if (isdnport->p_m_mISDNport)
3249 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3256 /* only if we are already part of interface */
3257 if (mISDNport->ifport)
3259 start_trace(mISDNport->portnum,
3260 mISDNport->ifport->interface,
3270 /* free bchannels */
3272 while(i < mISDNport->b_num)
3274 if (mISDNport->b_addr[i])
3276 _bchannel_destroy(mISDNport, i);
3277 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3283 close_layer3(mISDNport->ml3);
3285 /* free ressources of port */
3286 msg_queue_purge(&mISDNport->downqueue);
3289 if (mISDNport->ntmode)
3291 nst = &mISDNport->nst;
3292 if (nst->manager) /* to see if initialized */
3294 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");
3295 cleanup_Isdnl3(nst);
3296 cleanup_Isdnl2(nst);
3299 msg_queue_purge(&nst->down_queue);
3300 if (nst->phd_down_msg)
3301 FREE(nst->phd_down_msg, 0);
3305 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3306 if (mISDNport->d_stid)
3308 if (mISDNport->upper_id)
3309 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3313 /* remove from list */
3314 mISDNportp = &mISDNport_first;
3317 if (*mISDNportp == mISDNport)
3319 *mISDNportp = (*mISDNportp)->next;
3323 mISDNportp = &((*mISDNportp)->next);
3327 FATAL("mISDNport not in list\n");
3329 FREE(mISDNport, sizeof(struct mISDNport));
3336 * global function to show all available isdn ports
3338 void mISDN_port_info(void)
3342 int useable, nt, te, pri, bri, pots;
3343 unsigned char buff[1025];
3344 iframe_t *frm = (iframe_t *)buff;
3346 struct mISDN_devinfo devinfo;
3350 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3353 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3357 /* get number of stacks */
3359 ret = ioctl(socket, IMGETCOUNT, &ii);
3362 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3366 stack_info_t *stinf;
3370 if ((device = mISDN_open()) < 0)
3372 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));
3376 /* get number of stacks */
3378 ii = mISDN_get_stack_count(device);
3383 printf("Found no card. Please be sure to load card drivers.\n");
3387 /* loop the number of cards and get their info */
3390 nt = te = bri = pri = pots = 0;
3395 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
3398 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3402 /* output the port info */
3403 printf("Port %2d name='%s': ", i, devinfo.name);
3404 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3409 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3415 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3422 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3429 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3436 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3442 if ((te || nt) && (bri || pri || ports))
3446 printf("TE-mode BRI S/T interface line (for phone lines)");
3448 printf("NT-mode BRI S/T interface port (for phones)");
3450 printf("TE-mode PRI E1 interface line (for phone lines)");
3452 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3454 printf("FXS POTS interface port (for analog lines)");
3456 printf("FXO POTS interface port (for analog phones)");
3460 printf("\n -> Analog interfaces are not supported.");
3464 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3468 printf(" - %d B-channels\n", devinfo.nfbchan);
3470 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3473 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3476 stinf = (stack_info_t *)&frm->data.p;
3478 /* output the port info */
3479 printf("Port %2d: ", i);
3480 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3482 case ISDN_PID_L0_TE_S0:
3486 printf("TE-mode BRI S/T interface line (for phone lines)");
3488 case ISDN_PID_L0_NT_S0:
3492 printf("NT-mode BRI S/T interface port (for phones)");
3494 case ISDN_PID_L0_TE_E1:
3498 printf("TE-mode PRI E1 interface line (for phone lines)");
3500 case ISDN_PID_L0_NT_E1:
3504 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3508 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3514 if (stinf->pid.protocol[1] == 0)
3517 printf(" -> Missing layer 1 NT-mode protocol.\n");
3520 while(p <= MAX_LAYER_NR) {
3521 if (stinf->pid.protocol[p])
3524 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3531 printf(" -> Interface is Point-To-Point (PRI).\n");
3533 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3538 if (stinf->pid.protocol[1] == 0)
3541 printf(" -> Missing layer 1 protocol.\n");
3543 if (stinf->pid.protocol[2] == 0)
3546 printf(" -> Missing layer 2 protocol.\n");
3548 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3550 printf(" -> Interface is Poin-To-Point.\n");
3552 if (stinf->pid.protocol[3] == 0)
3555 printf(" -> Missing layer 3 protocol.\n");
3558 printf(" -> Protocol: ");
3559 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3561 case ISDN_PID_L3_DSS1USER:
3562 printf("DSS1 (Euro ISDN)");
3567 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3572 while(p <= MAX_LAYER_NR) {
3573 if (stinf->pid.protocol[p])
3576 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3581 printf(" - %d B-channels\n", stinf->childcnt);
3585 printf(" * Port NOT useable for LCR\n");
3587 printf("--------\n");
3598 if ((ret = mISDN_close(device)))
3599 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3605 * enque data from upper buffer
3607 void PmISDN::txfromup(unsigned char *data, int length)
3610 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3611 struct mISDNhead *frm = (struct mISDNhead *)buf;
3613 if (p_m_b_index < 0)
3615 if (!p_m_mISDNport->b_socket[p_m_b_index])
3618 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3619 iframe_t *frm = (iframe_t *)buf;
3621 if (p_m_b_index < 0)
3623 if (!p_m_mISDNport->b_addr[p_m_b_index])
3627 /* check if high priority tones exist
3628 * ignore data in this case
3630 if (p_tone_name[0] || p_m_crypt_msg_loops)
3633 /* preload procedure
3634 * if transmit buffer in DSP module is empty,
3635 * preload it to DSP_LOAD to prevent jitter gaps.
3637 if (p_m_load==0 && ISDN_LOAD>0)
3640 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3641 frm->len = ISDN_LOAD;
3642 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3643 p_m_load += frm->len;
3646 /* drop if load would exceed ISDN_MAXLOAD
3647 * this keeps the delay not too high
3649 if (p_m_load+length > ISDN_MAXLOAD)
3652 /* make and send frame */
3654 frm->prim = DL_DATA_REQ;
3656 memcpy(buf+MISDN_HEADER_LEN, data, length);
3657 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3659 PERROR("Failed to send to socket %d\n", handle);
3661 frm->prim = DL_DATA | REQUEST;
3662 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3665 memcpy(buf+mISDN_HEADER_LEN, data, length);
3666 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);