1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
17 #include <mISDNuser/net_l2.h>
23 #ifndef CMX_TXDATA_OFF
38 #warning *********************************************************
40 #warning * It seems that you use an older version of mISDN.
41 #warning * Features like voice recording or echo will not work.
42 #warning * Also it causes problems with loading modules and may
43 #warning * not work at all.
45 #warning * Please upgrade to newer version. A working version can
46 #warning * be found at www.linux-call-router.de.
48 #warning * Do not use the mISDN_1_1 branch, it does not have all
49 #warning * the features that are required. Use the master branch
52 #warning *********************************************************
57 #ifndef ISDN_PID_L4_B_USER
58 #define ISDN_PID_L4_B_USER 0x440000ff
63 #include <sys/socket.h>
66 #include <mISDNuser/mISDNif.h>
67 #include <mISDNuser/q931.h>
68 #include <mISDNuser/mlayer3.h>
71 // timeouts if activating/deactivating response from mISDN got lost
72 #define B_TIMER_ACTIVATING 1 // seconds
73 #define B_TIMER_DEACTIVATING 1 // seconds
75 /* list of mISDN ports */
76 struct mISDNport *mISDNport_first;
78 /* noise randomizer */
79 unsigned char mISDN_rand[256];
80 int mISDN_rand_count = 0;
83 unsigned long mt_assign_pid = ~0;
87 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(filename, "%s/debug.log", INSTALL_DATA);
103 debug_fp = fopen(filename, "a");
106 if (options.deb & DEBUG_STACK)
108 SPRINT(filename, "%s/debug_mISDN.log", INSTALL_DATA);
109 mISDN_debug_init(0xffffffff, filename, filename, filename);
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 > -1)
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 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
329 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
330 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
331 {"DL_RELEASE", L2_RELEASE_REQ},
332 {"UNKNOWN", L3_UNKNOWN},
333 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
334 {"MT_SETUP", L3_SETUP_REQ},
335 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
336 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
337 {"MT_ALERTING", L3_ALERTING_REQ},
338 {"MT_CONNECT", L3_CONNECT_REQ},
339 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
340 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
341 {"MT_RELEASE", L3_RELEASE_REQ},
342 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
343 {"MT_INFORMATION", L3_INFORMATION_REQ},
344 {"MT_PROGRESS", L3_PROGRESS_REQ},
345 {"MT_NOTIFY", L3_NOTIFY_REQ},
346 {"MT_SUSPEND", L3_SUSPEND_REQ},
347 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
348 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
349 {"MT_RESUME", L3_RESUME_REQ},
350 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
351 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
352 {"MT_HOLD", L3_HOLD_REQ},
353 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
354 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
355 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
356 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
357 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
358 {"MT_FACILITY", L3_FACILITY_REQ},
359 {"MT_STATUS", L3_STATUS_REQ},
360 {"MT_RESTART", L3_RESTART_REQ},
362 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
363 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
365 {"MT_NEW_CR", L3_NEW_CR_REQ},
366 {"MT_RELEASE_CR", L3_RELEASE_CR_REQ},
371 static char *isdn_prim[4] = {
377 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long msg, int direction)
380 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
382 /* select message and primitive text */
384 while(isdn_message[i].name)
386 if (isdn_message[i].value == (msg&0xffffff00))
388 SCPY(msgtext, isdn_message[i].name);
393 SCAT(msgtext, isdn_prim[msg&0x00000003]);
397 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
399 if (direction && (msg&0xffffff00)!=L3_NEW_CR_REQ && (msg&0xffffff00)!=L3_RELEASE_CR_REQ)
404 if (mISDNport->ntmode)
406 if (direction == DIRECTION_OUT)
407 SCAT(msgtext, " N->U");
409 SCAT(msgtext, " N<-U");
412 if (direction == DIRECTION_OUT)
413 SCAT(msgtext, " U->N");
415 SCAT(msgtext, " U<-N");
420 /* init trace with given values */
421 start_trace(mISDNport?mISDNport->portnum:0,
422 mISDNport?mISDNport->ifport->interface:NULL,
423 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
424 port?port->p_dialinginfo.id:NULL,
427 port?port->p_serial:0,
433 * send control information to the channel (dsp-module)
435 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
438 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
439 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
440 unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
443 ctrl->prim = PH_CONTROL_REQ;
447 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
449 PERROR("Failed to send to socket %d\n", handle);
451 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
452 iframe_t *ctrl = (iframe_t *)buffer;
453 unsigned long *d = (unsigned long *)&ctrl->data.p;
455 ctrl->prim = PH_CONTROL | REQUEST;
456 ctrl->addr = handle | FLG_MSG_DOWN;
458 ctrl->len = sizeof(int)*2;
461 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
463 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
464 if (c1 == CMX_CONF_JOIN)
465 add_trace(trace_name, NULL, "0x%08x", trace_value);
467 add_trace(trace_name, NULL, "%d", trace_value);
471 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)
474 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
475 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
476 unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
479 ctrl->prim = PH_CONTROL_REQ;
482 memcpy(d, c2, c2_len);
483 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
485 PERROR("Failed to send to socket %d\n", handle);
487 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
488 iframe_t *ctrl = (iframe_t *)buffer;
489 unsigned long *d = (unsigned long *)&ctrl->data.p;
491 ctrl->prim = PH_CONTROL | REQUEST;
492 ctrl->addr = handle | FLG_MSG_DOWN;
494 ctrl->len = sizeof(int)+c2_len;
496 memcpy(d, c2, c2_len);
497 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
499 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
500 add_trace(trace_name, NULL, "%d", trace_value);
506 * subfunction for bchannel_event
509 static int _bchannel_create(struct mISDNport *mISDNport, int i)
513 unsigned long on = 1;
514 struct sockaddr_mISDN addr;
516 if (mISDNport->b_socket[i])
518 PERROR("Error: Socket already created for index %d\n", i);
523 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
524 if (mISDNport->b_socket[i] < 0)
526 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
530 /* set nonblocking io */
531 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
534 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
535 close(mISDNport->b_socket[i]);
536 mISDNport->b_socket[i] = -1;
540 /* bind socket to bchannel */
541 addr.family = AF_ISDN;
542 addr.dev = mISDNport->portnum-1;
543 addr.channel = i+1+(i>=15);
544 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
547 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
548 close(mISDNport->b_socket[i]);
549 mISDNport->b_socket[i] = -1;
553 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
554 add_trace("channel", NULL, "%d", i+1+(i>=15));
555 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
560 unsigned char buff[1024];
564 if (!mISDNport->b_stid[i])
566 PERROR("Error: no stack for index %d\n", i);
569 if (mISDNport->b_addr[i])
571 PERROR("Error: stack already created for index %d\n", i);
575 /* create new layer */
576 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
577 memset(&li, 0, sizeof(li));
578 memset(&pid, 0, sizeof(pid));
581 li.st = mISDNport->b_stid[i];
582 UCPY(li.name, "B L4");
583 li.pid.layermask = ISDN_LAYER((4));
584 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
585 ret = mISDN_new_layer(mISDNdevice, &li);
589 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
592 mISDNport->b_addr[i] = li.id;
595 goto failed_new_layer;
597 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
599 /* create new stack */
600 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
601 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
602 pid.protocol[3] = ISDN_PID_L3_B_DSP;
603 pid.protocol[4] = ISDN_PID_L4_B_USER;
604 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
605 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
609 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
610 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
613 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
618 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
619 if (!mISDNport->b_addr[i])
621 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
622 add_trace("channel", NULL, "%d", i+1+(i>=15));
623 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
624 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
630 mISDNport->b_addr[i] = 0;
637 * subfunction for bchannel_event
638 * activate / deactivate request
640 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
643 struct mISDNhead act;
646 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
648 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
650 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
654 /* activate bchannel */
655 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
656 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
659 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
663 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
664 add_trace("channel", NULL, "%d", i+1+(i>=15));
665 if (mISDNport->b_timer[i])
666 add_trace("event", NULL, "timeout recovery");
672 * subfunction for bchannel_event
675 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
681 handle = mISDNport->b_socket[i];
683 unsigned long handle;
685 handle = mISDNport->b_addr[i];
687 port = mISDNport->b_port[i];
690 PERROR("bchannel index i=%d not associated with a port object\n", i);
694 /* set dsp features */
696 if (port->p_m_txdata)
697 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
699 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
701 if (port->p_m_tx_gain)
702 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
703 if (port->p_m_rx_gain)
704 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
706 if (port->p_m_pipeline[0])
707 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
710 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
712 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
714 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
716 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
717 // if (port->p_m_txmix)
718 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
720 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
722 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);
726 * subfunction for bchannel_event
729 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
732 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
733 add_trace("channel", NULL, "%d", i+1+(i>=15));
734 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
736 if (mISDNport->b_socket[i] > -1)
738 close(mISDNport->b_socket[i]);
739 mISDNport->b_socket[i] = -1;
742 unsigned char buff[1024];
744 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
745 add_trace("channel", NULL, "%d", i+1+(i>=15));
746 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
747 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
749 /* remove our stack only if set */
750 if (mISDNport->b_addr[i])
752 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
753 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
754 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
755 mISDNport->b_addr[i] = 0;
765 A bchannel goes through the following states in this order:
768 No one is using the bchannel.
769 It is available and not linked to Port class, nor reserved.
772 The bchannel stack is created and an activation request is sent.
773 It MAY be linked to Port class, but already unlinked due to Port class removal.
776 The bchannel is active and cofigured to the Port class needs.
777 Also it is linked to a Port class, otherwhise it would be deactivated.
779 - B_STATE_DEACTIVATING
780 The bchannel is in deactivating state, due to deactivation request.
781 It may be linked to a Port class, that likes to reactivate it.
785 After deactivating bchannel, and if not used, the bchannel becomes idle again.
787 Also the bchannel may be exported, but only if the state is or becomes idle:
790 The bchannel assignment has been sent to the remove application.
793 The bchannel assignment is acknowledged by the remote application.
796 The bchannel is re-imported by mISDN port object.
800 After re-importing bchannel, and if not used, the bchannel becomes idle again.
803 A bchannel can have the following events:
806 A bchannel is required by a Port class.
807 The bchannel shall be exported to the remote application.
810 The bchannel beomes active.
813 The bchannel is not required by Port class anymore
815 - B_EVENT_DEACTIVATED
816 The bchannel becomes inactive.
819 The bchannel is now used by remote application.
822 The bchannel is not used by remote application.
824 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
826 if an export request is receive by remote application, p_m_remote_* is set.
827 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.)
828 - set on export request from remote application (if port is assigned)
829 - set on channel use, if requested by remote application (p_m_remote_*)
830 - cleared on drop request
832 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
833 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
834 the bchannel import/export is acknowledged with stack given.
836 if exporting, b_remote_*[index] is set to the remote socket id.
837 if importing has been acknowledged. b_remote_*[index] is cleared.
842 * process bchannel events
843 * - mISDNport is a pointer to the port's structure
844 * - i is the index of the bchannel
845 * - event is the B_EVENT_* value
846 * - port is the PmISDN class pointer
848 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
850 class PmISDN *b_port = mISDNport->b_port[i];
851 int state = mISDNport->b_state[i];
852 double timer = mISDNport->b_timer[i];
853 unsigned long p_m_remote_ref = 0;
854 unsigned long p_m_remote_id = 0;
857 char *p_m_pipeline = NULL;
858 unsigned char *p_m_crypt_key = NULL;
859 int p_m_crypt_key_len = 0;
860 int p_m_crypt_key_type = 0;
862 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
864 unsigned long portid = mISDNport->b_stid[i];
869 p_m_remote_id = b_port->p_m_remote_id;
870 p_m_remote_ref = b_port->p_m_remote_ref;
871 p_m_tx_gain = b_port->p_m_tx_gain;
872 p_m_rx_gain = b_port->p_m_rx_gain;
873 p_m_pipeline = b_port->p_m_pipeline;
874 p_m_crypt_key = b_port->p_m_crypt_key;
875 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
876 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
882 /* port must be linked in order to allow activation */
884 FATAL("bchannel must be linked to a Port class\n");
890 /* export bchannel */
891 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);
892 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
893 add_trace("type", NULL, "assign");
895 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
897 add_trace("socket", "id", "%d", portid);
900 state = B_STATE_EXPORTING;
901 mISDNport->b_remote_id[i] = p_m_remote_id;
902 mISDNport->b_remote_ref[i] = p_m_remote_ref;
905 /* create stack and send activation request */
906 if (_bchannel_create(mISDNport, i))
908 _bchannel_activate(mISDNport, i, 1);
909 state = B_STATE_ACTIVATING;
910 timer = now_d + B_TIMER_ACTIVATING;
915 case B_STATE_ACTIVATING:
916 case B_STATE_EXPORTING:
917 /* do nothing, because it is already activating */
920 case B_STATE_DEACTIVATING:
921 case B_STATE_IMPORTING:
922 /* do nothing, because we must wait until we can reactivate */
926 /* problems that might ocurr:
927 * B_EVENT_USE is received when channel already in use.
928 * bchannel exported, but not freed by other port
930 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
934 case B_EVENT_EXPORTREQUEST:
935 /* special case where the bchannel is requested by remote */
938 PERROR("export request without remote channel set, please correct.\n");
944 /* in case, the bchannel is exported right after seize_bchannel */
945 /* export bchannel */
946 /* p_m_remote_id is set, when this event happens. */
947 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);
948 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
949 add_trace("type", NULL, "assign");
951 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
953 add_trace("socket", "id", "%d", portid);
956 state = B_STATE_EXPORTING;
957 mISDNport->b_remote_id[i] = p_m_remote_id;
958 mISDNport->b_remote_ref[i] = p_m_remote_ref;
961 case B_STATE_ACTIVATING:
962 case B_STATE_EXPORTING:
963 /* do nothing, because it is already activating */
966 case B_STATE_DEACTIVATING:
967 case B_STATE_IMPORTING:
968 /* do nothing, because we must wait until we can reactivate */
972 /* bchannel is active, so we deactivate */
973 _bchannel_activate(mISDNport, i, 0);
974 state = B_STATE_DEACTIVATING;
975 timer = now_d + B_TIMER_DEACTIVATING;
979 /* problems that might ocurr:
980 * ... when channel already in use.
981 * bchannel exported, but not freed by other port
983 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
987 case B_EVENT_ACTIVATED:
991 case B_STATE_ACTIVATING:
992 if (b_port && !p_m_remote_id)
994 /* bchannel is active and used by Port class, so we configure bchannel */
995 _bchannel_configure(mISDNport, i);
996 state = B_STATE_ACTIVE;
999 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
1000 _bchannel_activate(mISDNport, i, 0);
1001 state = B_STATE_DEACTIVATING;
1002 timer = now_d + B_TIMER_DEACTIVATING;
1007 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1011 case B_EVENT_EXPORTED:
1014 case B_STATE_EXPORTING:
1015 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
1017 /* remote export done */
1018 state = B_STATE_REMOTE;
1021 /* bchannel is now exported, but we need bchannel back
1022 * OR bchannel is not used anymore
1023 * OR bchannel has been exported to an obsolete ref,
1024 * so reimport, to later export to new remote */
1025 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1026 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1027 add_trace("type", NULL, "remove");
1029 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1031 add_trace("socket", "id", "%d", portid);
1034 state = B_STATE_IMPORTING;
1039 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1045 FATAL("bchannel must be linked to a Port class\n");
1049 /* bchannel is idle due to an error, so we do nothing */
1052 case B_STATE_ACTIVATING:
1053 case B_STATE_EXPORTING:
1054 /* do nothing because we must wait until bchanenl is active before deactivating */
1057 case B_STATE_ACTIVE:
1058 /* bchannel is active, so we deactivate */
1059 _bchannel_activate(mISDNport, i, 0);
1060 state = B_STATE_DEACTIVATING;
1061 timer = now_d + B_TIMER_DEACTIVATING;
1064 case B_STATE_REMOTE:
1065 /* bchannel is exported, so we re-import */
1066 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1067 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1068 add_trace("type", NULL, "remove");
1070 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1072 add_trace("socket", "id", "%d", portid);
1075 state = B_STATE_IMPORTING;
1078 case B_STATE_DEACTIVATING:
1079 case B_STATE_IMPORTING:
1080 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1084 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1088 case B_EVENT_DEACTIVATED:
1093 /* ignore due to deactivation confirm after unloading */
1096 case B_STATE_DEACTIVATING:
1097 _bchannel_destroy(mISDNport, i);
1098 state = B_STATE_IDLE;
1101 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1104 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);
1105 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1106 add_trace("type", NULL, "assign");
1108 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1110 add_trace("socket", "id", "%d", portid);
1113 state = B_STATE_EXPORTING;
1114 mISDNport->b_remote_id[i] = p_m_remote_id;
1115 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1118 if (_bchannel_create(mISDNport, i))
1120 _bchannel_activate(mISDNport, i, 1);
1121 state = B_STATE_ACTIVATING;
1122 timer = now_d + B_TIMER_ACTIVATING;
1129 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1133 case B_EVENT_IMPORTED:
1136 case B_STATE_IMPORTING:
1137 state = B_STATE_IDLE;
1138 mISDNport->b_remote_id[i] = 0;
1139 mISDNport->b_remote_ref[i] = 0;
1142 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1145 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);
1146 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1147 add_trace("type", NULL, "assign");
1149 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1151 add_trace("socket", "id", "%d", portid);
1154 state = B_STATE_EXPORTING;
1155 mISDNport->b_remote_id[i] = p_m_remote_id;
1156 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1159 if (_bchannel_create(mISDNport, i))
1161 _bchannel_activate(mISDNport, i, 1);
1162 state = B_STATE_ACTIVATING;
1163 timer = now_d + B_TIMER_ACTIVATING;
1170 /* ignore, because not assigned */
1175 case B_EVENT_TIMEOUT:
1180 /* ignore due to deactivation confirm after unloading */
1183 case B_STATE_ACTIVATING:
1184 _bchannel_activate(mISDNport, i, 1);
1185 timer = now_d + B_TIMER_ACTIVATING;
1188 case B_STATE_DEACTIVATING:
1189 _bchannel_activate(mISDNport, i, 0);
1190 timer = now_d + B_TIMER_DEACTIVATING;
1194 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1199 PERROR("Illegal event %d, please correct.\n", event);
1202 mISDNport->b_state[i] = state;
1203 mISDNport->b_timer[i] = timer;
1210 * check for available channel and reserve+set it.
1211 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1212 * give exclusiv flag
1213 * returns -(cause value) or x = channel x or 0 = no channel
1214 * NOTE: no activation is done here
1216 int PmISDN::seize_bchannel(int channel, int exclusive)
1220 /* the channel is what we have */
1221 if (p_m_b_channel == channel)
1224 /* if channel already in use, release it */
1229 if (channel==CHANNEL_NO || channel==0)
1232 /* is channel in range ? */
1234 || (channel>p_m_mISDNport->b_num && channel<16)
1235 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1236 return(-6); /* channel unacceptable */
1238 /* request exclusive channel */
1239 if (exclusive && channel>0)
1241 i = channel-1-(channel>16);
1242 if (p_m_mISDNport->b_port[i])
1243 return(-44); /* requested channel not available */
1247 /* ask for channel */
1250 i = channel-1-(channel>16);
1251 if (p_m_mISDNport->b_port[i] == NULL)
1255 /* search for channel */
1257 while(i < p_m_mISDNport->b_num)
1259 if (!p_m_mISDNport->b_port[i])
1261 channel = i+1+(i>=15);
1266 return(-34); /* no free channel */
1269 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1272 p_m_mISDNport->b_port[i] = this;
1274 p_m_b_channel = channel;
1275 p_m_b_exclusive = exclusive;
1277 /* reserve channel */
1281 p_m_mISDNport->b_reserved++;
1288 * drop reserved channel and unset it.
1289 * deactivation is also done
1291 void PmISDN::drop_bchannel(void)
1293 /* unreserve channel */
1295 p_m_mISDNport->b_reserved--;
1299 if (p_m_b_index < 0)
1304 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1306 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1307 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1308 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1311 p_m_b_exclusive = 0;
1314 /* process bchannel export/import message from join */
1315 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1317 class Endpoint *epoint;
1319 class PmISDN *isdnport;
1320 struct mISDNport *mISDNport;
1325 case BCHANNEL_REQUEST:
1326 /* find the port object for the join object ref */
1327 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1329 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1332 if (!epoint->ep_portlist)
1334 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1337 if (epoint->ep_portlist->next)
1339 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);
1341 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1343 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1346 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1348 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1350 isdnport = (class PmISDN *)port;
1353 if (isdnport->p_m_remote_id)
1355 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1358 mISDNport = isdnport->p_m_mISDNport;
1359 i = isdnport->p_m_b_index;
1360 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1361 add_trace("type", NULL, "export request");
1362 isdnport->p_m_remote_ref = joinremote->j_serial;
1363 isdnport->p_m_remote_id = joinremote->j_remote_id;
1364 if (mISDNport && i>=0)
1366 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1371 case BCHANNEL_ASSIGN_ACK:
1372 case BCHANNEL_REMOVE_ACK:
1373 /* find mISDNport for stack ID */
1374 mISDNport = mISDNport_first;
1378 ii = mISDNport->b_num;
1382 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1384 if (mISDNport->b_addr[i] == handle)
1391 mISDNport = mISDNport->next;
1395 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1398 /* mISDNport may now be set or NULL */
1401 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1402 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1403 if (mISDNport && i>=0)
1404 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1408 PERROR("received wrong bchannel message type %d from remote\n", type);
1416 audio transmission procedure:
1417 -----------------------------
1420 three sources of audio transmission:
1421 - crypto-data high priority
1422 - tones high priority (also high)
1423 - remote-data low priority
1426 a variable that temporarily shows the number of samples elapsed since last transmission process.
1427 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1430 a variable that is increased whenever data is transmitted.
1431 it is decreased while time elapses. it stores the number of samples that
1432 are currently loaded to dsp module.
1433 since clock in dsp module is the same clock for user space process, these
1437 there are two levels:
1438 ISDN_LOAD will give the load that have to be kept in dsp.
1439 ISDN_MAXLOAD will give the maximum load before dropping.
1441 * procedure for low priority data
1442 see txfromup() for procedure
1443 in short: remote data is ignored during high priority tones
1445 * procedure for high priority data
1446 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1447 if no more data is available, load becomes empty again.
1450 0 ISDN_LOAD ISDN_MAXLOAD
1451 +--------------------+----------------------+
1453 +--------------------+----------------------+
1455 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1456 0 ISDN_LOAD ISDN_MAXLOAD
1457 +--------------------+----------------------+
1458 |TTTTTTTTTTTTTTTTTTTT| |
1459 +--------------------+----------------------+
1461 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1462 0 ISDN_LOAD ISDN_MAXLOAD
1463 +--------------------+----------------------+
1464 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1465 +--------------------+----------------------+
1468 int PmISDN::handler(void)
1470 struct message *message;
1474 if ((ret = Port::handler()))
1478 if (p_m_last_tv_sec)
1480 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1481 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1484 /* set clock of first process ever in this instance */
1485 p_m_last_tv_sec = now_tv.tv_sec;
1486 p_m_last_tv_msec = now_tv.tv_usec/1000;
1488 /* process only if we have a minimum of samples, to make packets not too small */
1489 if (elapsed >= ISDN_TRANSMIT)
1491 /* set clock of last process! */
1492 p_m_last_tv_sec = now_tv.tv_sec;
1493 p_m_last_tv_msec = now_tv.tv_usec/1000;
1496 if (elapsed < p_m_load)
1497 p_m_load -= elapsed;
1501 /* to send data, tone must be active OR crypt messages must be on */
1502 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1503 && (p_m_load < ISDN_LOAD)
1504 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1506 int tosend = ISDN_LOAD - p_m_load, length;
1508 unsigned char buf[MISDN_HEADER_LEN+tosend];
1509 struct mISDNhead *frm = (struct mISDNhead *)buf;
1510 unsigned char *p = buf+MISDN_HEADER_LEN;
1512 unsigned char buf[mISDN_HEADER_LEN+tosend];
1513 iframe_t *frm = (iframe_t *)buf;
1514 unsigned char *p = buf+mISDN_HEADER_LEN;
1517 /* copy crypto loops */
1518 while (p_m_crypt_msg_loops && tosend)
1520 /* how much do we have to send */
1521 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1524 if (length > tosend)
1527 /* copy message (part) to buffer */
1528 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1531 p_m_crypt_msg_current += length;
1532 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1535 p_m_crypt_msg_current = 0;
1536 p_m_crypt_msg_loops--;
1537 // puts("eine loop weniger");
1545 if (p_tone_name[0] && tosend)
1547 tosend -= read_audio(p, tosend);
1552 frm->prim = DL_DATA_REQ;
1554 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1556 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
1558 frm->prim = DL_DATA | REQUEST;
1559 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1561 frm->len = ISDN_LOAD - p_m_load - tosend;
1563 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1565 p_m_load += ISDN_LOAD - p_m_load - tosend;
1569 // NOTE: deletion is done by the child class
1571 /* handle timeouts */
1574 if (p_m_timer+p_m_timeout < now_d)
1576 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1578 /* send timeout to endpoint */
1579 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1580 message->param.state = p_state;
1581 message_put(message);
1586 return(0); /* nothing done */
1591 * whenever we get audio data from bchannel, we process it here
1594 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1596 unsigned long cont = *((unsigned long *)data);
1598 void PmISDN::bchannel_receive(iframe_t *frm)
1601 unsigned long cont = *((unsigned long *)&frm->data.p);
1602 unsigned char *data =(unsigned char *)&frm->data.p;
1604 unsigned char *data_temp;
1605 unsigned long length_temp;
1606 struct message *message;
1611 if (hh->prim == PH_CONTROL_IND)
1613 if (frm->prim == (PH_CONTROL | INDICATION))
1618 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1621 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1623 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1624 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1626 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1627 message->param.dtmf = cont & DTMF_TONE_MASK;
1628 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1629 message_put(message);
1635 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1636 add_trace("DSP-CRYPT", NULL, "error");
1638 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1639 message->param.crypt.type = CC_ERROR_IND;
1640 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1641 message_put(message);
1645 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1646 add_trace("DSP-CRYPT", NULL, "ok");
1648 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1649 message->param.crypt.type = CC_ACTBF_CONF;
1650 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1651 message_put(message);
1655 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1656 add_trace("unknown", NULL, "0x%x", cont);
1662 if (hh->prim == PH_CONTROL_IND)
1666 if (frm->prim == (PH_SIGNAL | INDICATION)
1667 || frm->prim == (PH_CONTROL | INDICATION))
1676 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1677 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1680 /* see below (same condition) */
1681 if (p_state!=PORT_STATE_CONNECT
1682 && !p_m_mISDNport->tones)
1684 // printf(".");fflush(stdout);return;
1686 record(data, len, 1); // from up
1691 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1693 add_trace("unknown", NULL, "0x%x", hh->id);
1695 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1702 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1704 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1706 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1708 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1712 /* calls will not process any audio data unless
1713 * the call is connected OR interface features audio during call setup.
1715 //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);
1716 #ifndef DEBUG_COREBRIDGE
1717 if (p_state!=PORT_STATE_CONNECT
1718 && !p_m_mISDNport->tones)
1722 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1725 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1731 record(data, len, 0); // from down
1733 /* randomize and listen to crypt message if enabled */
1734 if (p_m_crypt_listen)
1736 /* the noisy randomizer */
1740 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1742 cryptman_listen_bch(data, len);
1747 /* send data to epoint */
1748 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1754 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1755 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1756 memcpy(message->param.data.data, data_temp, message->param.data.len);
1757 message_put(message);
1758 if (length_temp <= sizeof(message->param.data.data))
1760 data_temp += sizeof(message->param.data.data);
1761 length_temp -= sizeof(message->param.data.data);
1770 void PmISDN::set_echotest(int echo)
1772 if (p_m_echo != echo)
1775 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1777 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1779 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);
1781 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);
1789 void PmISDN::set_tone(char *dir, char *tone)
1795 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1802 /* check if we NOT really have to use a dsp-tone */
1803 if (!options.dsptones)
1807 if (p_m_b_index > -1)
1808 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1810 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1812 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1814 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1818 Port::set_tone(dir, tone);
1824 /* now we USE dsp-tone, convert name */
1825 else if (!strcmp(tone, "dialtone"))
1827 switch(options.dsptones) {
1828 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1829 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1830 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1832 } else if (!strcmp(tone, "dialpbx"))
1834 switch(options.dsptones) {
1835 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1836 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1837 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1839 } else if (!strcmp(tone, "ringing"))
1841 switch(options.dsptones) {
1842 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1843 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1844 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1846 } else if (!strcmp(tone, "ringpbx"))
1848 switch(options.dsptones) {
1849 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1850 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1851 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1853 } else if (!strcmp(tone, "busy"))
1856 switch(options.dsptones) {
1857 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1858 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1859 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1861 } else if (!strcmp(tone, "release"))
1864 switch(options.dsptones) {
1865 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1866 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1867 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1869 } else if (!strcmp(tone, "cause_10"))
1871 else if (!strcmp(tone, "cause_11"))
1873 else if (!strcmp(tone, "cause_22"))
1875 switch(options.dsptones) {
1876 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1877 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1878 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1880 } else if (!strncmp(tone, "cause_", 6))
1881 id = TONE_SPECIAL_INFO;
1885 /* if we have a tone that is not supported by dsp */
1886 if (id==TONE_OFF && tone[0])
1894 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1895 if (p_m_b_index > -1)
1896 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1898 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);
1900 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);
1903 /* turn user-space tones off in cases of no tone OR dsp tone */
1904 Port::set_tone("",NULL);
1908 /* MESSAGE_mISDNSIGNAL */
1909 //extern struct message *dddebug;
1910 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1912 switch(param->mISDNsignal.message)
1914 case mISDNSIGNAL_VOLUME:
1915 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1917 p_m_tx_gain = param->mISDNsignal.tx_gain;
1918 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1919 if (p_m_b_index > -1)
1920 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1922 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);
1924 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);
1927 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1928 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1930 p_m_rx_gain = param->mISDNsignal.rx_gain;
1931 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1932 if (p_m_b_index > -1)
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], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1937 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);
1940 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1943 case mISDNSIGNAL_CONF:
1944 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1945 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1946 if (p_m_conf != param->mISDNsignal.conf)
1948 p_m_conf = param->mISDNsignal.conf;
1949 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1950 if (p_m_b_index > -1)
1951 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1953 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);
1955 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);
1958 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1959 /* we must set, even if currently tone forbids conf */
1960 p_m_conf = param->mISDNsignal.conf;
1961 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1964 case mISDNSIGNAL_JOINDATA:
1965 if (p_m_joindata != param->mISDNsignal.joindata)
1967 p_m_joindata = param->mISDNsignal.joindata;
1968 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1970 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1973 case mISDNSIGNAL_DELAY:
1974 if (p_m_delay != param->mISDNsignal.delay)
1976 p_m_delay = param->mISDNsignal.delay;
1977 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1979 if (p_m_b_index > -1)
1980 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1982 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);
1984 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);
1988 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1992 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1997 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1999 struct message *message;
2001 switch(param->crypt.type)
2003 case CC_ACTBF_REQ: /* activate blowfish */
2005 p_m_crypt_key_len = param->crypt.len;
2006 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
2008 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
2009 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
2010 message->param.crypt.type = CC_ERROR_IND;
2011 message_put(message);
2014 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
2016 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
2017 if (p_m_b_index > -1)
2018 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2020 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);
2022 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);
2026 case CC_DACT_REQ: /* deactivate session encryption */
2031 case CR_LISTEN_REQ: /* start listening to messages */
2032 p_m_crypt_listen = 1;
2033 p_m_crypt_listen_state = 0;
2036 case CR_UNLISTEN_REQ: /* stop listening to messages */
2037 p_m_crypt_listen = 0;
2040 case CR_MESSAGE_REQ: /* send message */
2041 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2042 if (!p_m_crypt_msg_len)
2044 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2047 p_m_crypt_msg_current = 0; /* reset */
2048 p_m_crypt_msg_loops = 6; /* enable */
2050 /* disable txmix, or we get corrupt data due to audio process */
2051 if (p_m_txmix && p_m_b_index>=0)
2053 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2055 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2057 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2064 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2070 * endpoint sends messages to the port
2072 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2074 if (Port::message_epoint(epoint_id, message_id, param))
2079 case MESSAGE_DATA: /* tx-data from upper layer */
2080 txfromup(param->data.data, param->data.len);
2083 case MESSAGE_mISDNSIGNAL: /* user command */
2084 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2085 message_mISDNsignal(epoint_id, message_id, param);
2088 case MESSAGE_CRYPT: /* crypt control command */
2089 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2090 message_crypt(epoint_id, message_id, param);
2099 * main loop for processing messages from mISDN
2102 int mISDN_handler(void)
2105 struct mISDNport *mISDNport;
2106 class PmISDN *isdnport;
2108 unsigned char buffer[2048+MISDN_HEADER_LEN];
2109 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2111 /* process all ports */
2112 mISDNport = mISDNport_first;
2115 /* process all bchannels */
2117 while(i < mISDNport->b_num)
2119 /* process timer events for bchannel handling */
2120 if (mISDNport->b_timer[i])
2122 if (mISDNport->b_timer[i] <= now_d)
2123 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2125 /* handle port of bchannel */
2126 isdnport=mISDNport->b_port[i];
2129 /* call bridges in user space OR crypto OR recording */
2130 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2132 /* rx IS required */
2133 if (isdnport->p_m_rxoff)
2136 isdnport->p_m_rxoff = 0;
2137 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2138 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2139 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2144 /* rx NOT required */
2145 if (!isdnport->p_m_rxoff)
2148 isdnport->p_m_rxoff = 1;
2149 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2150 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2151 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2156 if (isdnport->p_record)
2158 /* txdata IS required */
2159 if (!isdnport->p_m_txdata)
2162 isdnport->p_m_txdata = 1;
2163 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2164 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2165 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2170 /* txdata NOT required */
2171 if (isdnport->p_m_txdata)
2174 isdnport->p_m_txdata = 0;
2175 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2176 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2177 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2183 /* handle message from bchannel */
2184 if (mISDNport->b_socket[i] > -1)
2186 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
2187 if (ret >= (int)MISDN_HEADER_LEN)
2192 /* we don't care about confirms, we use rx data to sync tx */
2196 /* we receive audio data, we respond to it AND we send tones */
2199 case PH_CONTROL_IND:
2200 if (mISDNport->b_port[i])
2201 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2203 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
2206 case PH_ACTIVATE_IND:
2207 case DL_ESTABLISH_IND:
2208 case PH_ACTIVATE_CNF:
2209 case DL_ESTABLISH_CNF:
2210 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2211 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2214 case PH_DEACTIVATE_IND:
2215 case DL_RELEASE_IND:
2216 case PH_DEACTIVATE_CNF:
2217 case DL_RELEASE_CNF:
2218 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2219 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2223 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
2227 if (ret < 0 && errno != EWOULDBLOCK)
2228 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2235 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2237 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2238 mISDNport->l1timeout = 0;
2241 /* layer 2 establish timer */
2242 if (mISDNport->l2establish)
2244 if (now-mISDNport->l2establish > 5)
2247 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2249 // mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2250 // l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2257 mISDNport = mISDNport->next;
2260 /* if we received at least one b-frame, we will return 1 */
2264 int mISDN_handler(void)
2267 struct mISDNport *mISDNport;
2268 class PmISDN *isdnport;
2273 mISDNuser_head_t *hh;
2276 /* the que avoids loopbacks when replying to stack after receiving
2278 mISDNport = mISDNport_first;
2281 /* process turning on/off rx */
2283 while(i < mISDNport->b_num)
2285 /* process timer events for bchannel handling */
2286 if (mISDNport->b_timer[i])
2288 if (mISDNport->b_timer[i] <= now_d)
2289 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2291 isdnport=mISDNport->b_port[i];
2294 /* call bridges in user space OR crypto OR recording */
2295 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2297 /* rx IS required */
2298 if (isdnport->p_m_rxoff)
2301 isdnport->p_m_rxoff = 0;
2302 PDEBUG(DEBUG_BCHANNEL, "%s: receive 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_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2309 /* rx NOT required */
2310 if (!isdnport->p_m_rxoff)
2313 isdnport->p_m_rxoff = 1;
2314 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2315 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2316 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2321 if (isdnport->p_record)
2323 /* txdata IS required */
2324 if (!isdnport->p_m_txdata)
2327 isdnport->p_m_txdata = 1;
2328 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2330 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2331 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2337 /* txdata NOT required */
2338 if (isdnport->p_m_txdata)
2341 isdnport->p_m_txdata = 0;
2342 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2344 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2345 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2354 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2356 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2357 mISDNport->l1timeout = 0;
2360 if (mISDNport->l2establish)
2362 if (now-mISDNport->l2establish > 5)
2364 if (mISDNport->ntmode)
2366 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2367 time(&mISDNport->l2establish);
2369 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2370 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2375 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2376 time(&mISDNport->l2establish);
2378 act.prim = DL_ESTABLISH | REQUEST;
2379 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2382 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2384 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2389 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2391 if (mISDNport->ntmode)
2393 hh = (mISDNuser_head_t *)dmsg->data;
2394 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);
2395 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2399 frm = (iframe_t *)dmsg->data;
2400 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2401 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2402 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);
2403 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2408 mISDNport = mISDNport->next;
2411 /* no device, no read */
2412 if (mISDNdevice < 0)
2415 /* get message from kernel */
2416 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2418 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2422 if (errno == EAGAIN)
2424 FATAL("Failed to do mISDN_read()\n");
2429 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2433 frm = (iframe_t *)msg->data;
2438 case MGR_DELLAYER | CONFIRM:
2439 case MGR_INITTIMER | CONFIRM:
2440 case MGR_ADDTIMER | CONFIRM:
2441 case MGR_DELTIMER | CONFIRM:
2442 case MGR_REMOVETIMER | CONFIRM:
2447 /* handle timer events from mISDN for NT-stack
2448 * note: they do not associate with a stack */
2449 if (frm->prim == (MGR_TIMER | INDICATION))
2453 /* find mISDNport */
2454 mISDNport = mISDNport_first;
2458 if (mISDNport->ntmode)
2460 it = mISDNport->nst.tlist;
2464 if (it->id == (int)frm->addr)
2471 mISDNport = mISDNport->next;
2475 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2476 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2478 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2479 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2480 ret = it->function(it->data);
2483 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2488 /* find the mISDNport that belongs to the stack */
2489 mISDNport = mISDNport_first;
2492 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2494 mISDNport = mISDNport->next;
2498 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2499 // show a list of all mISDNports and their address
2501 mISDNport = mISDNport_first;
2504 PERROR(" port %s %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2505 mISDNport = mISDNport->next;
2512 if (!(frm->addr&FLG_CHILD_STACK))
2517 case MGR_SHORTSTATUS | INDICATION:
2518 case MGR_SHORTSTATUS | CONFIRM:
2519 switch(frm->dinfo) {
2520 case SSTATUS_L1_ACTIVATED:
2521 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2524 case SSTATUS_L1_DEACTIVATED:
2525 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2528 case SSTATUS_L2_ESTABLISHED:
2529 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2532 case SSTATUS_L2_RELEASED:
2533 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2539 case PH_ACTIVATE | CONFIRM:
2540 case PH_ACTIVATE | INDICATION:
2541 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2543 if (mISDNport->ntmode)
2545 mISDNport->l1link = 1;
2546 setup_queue(mISDNport, 1);
2550 mISDNport->l1link = 1;
2551 setup_queue(mISDNport, 1);
2554 case PH_DEACTIVATE | CONFIRM:
2555 case PH_DEACTIVATE | INDICATION:
2556 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2558 if (mISDNport->ntmode)
2560 mISDNport->l1link = 0;
2561 setup_queue(mISDNport, 0);
2565 mISDNport->l1link = 0;
2566 setup_queue(mISDNport, 0);
2569 case PH_CONTROL | CONFIRM:
2570 case PH_CONTROL | INDICATION:
2571 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2574 case DL_ESTABLISH | INDICATION:
2575 case DL_ESTABLISH | CONFIRM:
2576 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2578 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2580 if (mISDNport->l2establish)
2582 mISDNport->l2establish = 0;
2583 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2585 mISDNport->l2link = 1;
2588 case DL_RELEASE | INDICATION:
2589 case DL_RELEASE | CONFIRM:
2590 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2592 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2594 mISDNport->l2link = 0;
2597 time(&mISDNport->l2establish);
2598 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2604 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);
2605 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2607 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2610 if (mISDNport->ntmode)
2612 /* l1-data enters the nt-mode library */
2613 nst = &mISDNport->nst;
2614 if (nst->l1_l2(nst, msg))
2619 /* l3-data is sent to pbx */
2620 if (stack2manager_te(mISDNport, msg))
2631 /* we don't care about confirms, we use rx data to sync tx */
2632 case PH_DATA | CONFIRM:
2633 case DL_DATA | CONFIRM:
2636 /* we receive audio data, we respond to it AND we send tones */
2637 case PH_DATA | INDICATION:
2638 case DL_DATA | INDICATION:
2639 case PH_CONTROL | INDICATION:
2640 case PH_SIGNAL | INDICATION:
2642 while(i < mISDNport->b_num)
2644 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2648 if (i == mISDNport->b_num)
2650 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2653 if (mISDNport->b_port[i])
2655 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2656 mISDNport->b_port[i]->bchannel_receive(frm);
2658 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2661 case PH_ACTIVATE | INDICATION:
2662 case DL_ESTABLISH | INDICATION:
2663 case PH_ACTIVATE | CONFIRM:
2664 case DL_ESTABLISH | CONFIRM:
2665 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2667 while(i < mISDNport->b_num)
2669 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2673 if (i == mISDNport->b_num)
2675 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2678 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2681 case PH_DEACTIVATE | INDICATION:
2682 case DL_RELEASE | INDICATION:
2683 case PH_DEACTIVATE | CONFIRM:
2684 case DL_RELEASE | CONFIRM:
2685 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2687 while(i < mISDNport->b_num)
2689 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2693 if (i == mISDNport->b_num)
2695 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2698 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2702 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2713 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2717 * l3m must be freed, except for MT_ASSIGN
2720 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2722 /* special MT_ASSIGN handling:
2724 * if we request a PID from mlayer, we always do it while lcr is locked.
2725 * therefore we must check the MT_ASSIGN reply first before we lock.
2726 * this is because the MT_ASSIGN reply is received with the requesting
2727 * process, not by the mlayer thread!
2728 * this means, that the reply is sent during call of the request.
2729 * we must check if we get a reply and we know that we lcr is currently
2732 if (cmd == MT_ASSIGN)
2734 /* let's do some checking if someone changes stack behaviour */
2735 if (mt_assign_pid != 0)
2736 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2737 if ((pid >> 16) != MISDN_CES_MASTER)
2738 FATAL("someone played with the mISDNuser stack. MT_ASSIGN is expected with master CES.\n");
2739 mt_assign_pid = pid;
2744 pthread_mutex_lock(&mutex_lcr);
2751 case MGR_SHORTSTATUS_IND:
2752 case MGR_SHORTSTATUS_CNF:
2753 switch(frm->dinfo) {
2754 case SSTATUS_L1_ACTIVATED:
2755 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2758 case SSTATUS_L1_DEACTIVATED:
2759 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2762 case SSTATUS_L2_ESTABLISHED:
2763 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2766 case SSTATUS_L2_RELEASED:
2767 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2777 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2780 mISDNport->l1link = 1;
2783 case MT_L1DEACTIVATE:
2784 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2787 mISDNport->l1link = 0;
2791 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2792 // special config commands for interface (ip-address/LOS/AIS/RDI/SLIP)
2796 case MT_L2ESTABLISH:
2797 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2800 if (mISDNport->l2establish)
2802 mISDNport->l2establish = 0;
2803 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2805 mISDNport->l2link = 1;
2809 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2812 mISDNport->l2link = 0;
2815 time(&mISDNport->l2establish);
2816 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2821 /* l3-data is sent to LCR */
2822 stack2manager(mISDNport, cmd, pid, l3m);
2830 pthread_mutex_unlock(&mutex_lcr);
2839 * global function to add a new card (port)
2841 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2844 struct mISDNport *mISDNport, **mISDNportp;
2849 // struct mlayer3 *ml3;
2850 struct mISDN_devinfo devinfo;
2851 unsigned int protocol, prop;
2853 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2856 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2860 unsigned char buff[1025];
2861 iframe_t *frm = (iframe_t *)buff;
2862 // interface_info_t ii;
2866 stack_info_t *stinf;
2868 /* query port's requirements */
2869 cnt = mISDN_get_stack_count(mISDNdevice);
2874 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2877 if (port>cnt || port<1)
2879 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2883 pri = bri = pots = nt = te = 0;
2885 devinfo.id = port - 1;
2886 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2889 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2892 /* output the port info */
2893 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2898 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2904 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2911 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2918 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2925 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2931 if (force_nt && !nt)
2933 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2938 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2941 if (pots && !bri && !pri)
2943 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2948 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2953 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2956 /* force nt, by turning off TE */
2959 /* if TE an NT is supported (and not forced to NT), turn off NT */
2963 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2966 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2969 stinf = (stack_info_t *)&frm->data.p;
2970 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2972 case ISDN_PID_L0_TE_S0:
2973 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2975 case ISDN_PID_L0_NT_S0:
2976 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2979 case ISDN_PID_L0_TE_E1:
2980 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2983 case ISDN_PID_L0_NT_E1:
2984 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2989 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2995 if (stinf->pid.protocol[1] == 0)
2997 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
3000 if (stinf->pid.protocol[2])
3002 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
3009 if (stinf->pid.protocol[1] == 0)
3011 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
3014 if (stinf->pid.protocol[2] == 0)
3016 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
3019 if (stinf->pid.protocol[3] == 0)
3021 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
3025 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3027 case ISDN_PID_L3_DSS1USER:
3031 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
3035 if (stinf->pid.protocol[4])
3037 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3043 /* add mISDNport structure */
3044 mISDNportp = &mISDNport_first;
3046 mISDNportp = &((*mISDNportp)->next);
3047 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3049 *mISDNportp = mISDNport;
3051 /* allocate ressources of port */
3054 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NET;
3056 if (ptp) // ptp forced
3057 prop |= MISDN_FLG_PTP;
3060 if (ptmp && pri) // ptmp forced
3061 prop |= FLG_FORCE_PTMP;
3063 if (nt) // supports hold/retrieve on nt-mode
3064 prop |= MISDN_FLG_NET_HOLD;
3065 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
3066 if (!mISDNport->ml3)
3068 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3073 /* if ntmode, establish L1 to send the tei removal during start */
3074 if (mISDNport->ntmode)
3078 act.prim = PH_ACTIVATE | REQUEST;
3079 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3080 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3083 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3084 usleep(10000); /* to be sure, that l1 is up */
3088 SCPY(mISDNport->name, devinfo.name);
3089 mISDNport->b_num = devinfo.nrbchan;
3091 msg_queue_init(&mISDNport->downqueue);
3092 mISDNport->d_stid = stinf->id;
3093 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3094 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
3096 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
3100 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
3105 /* create layer intance */
3106 memset(&li, 0, sizeof(li));
3107 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3110 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3111 li.pid.layermask = ISDN_LAYER((nt?2:4));
3112 li.st = mISDNport->d_stid;
3113 ret = mISDN_new_layer(mISDNdevice, &li);
3116 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3118 mISDNport_close(mISDNport);
3121 mISDNport->upper_id = li.id;
3122 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3125 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3128 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3129 if (mISDNport->lower_id < 0)
3131 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3134 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3135 if (mISDNport->upper_id < 0)
3137 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3140 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3142 /* if ntmode, establish L1 to send the tei removal during start */
3143 if (mISDNport->ntmode)
3147 act.prim = PH_ACTIVATE | REQUEST;
3148 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3149 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3152 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3153 usleep(10000); /* to be sure, that l1 is up */
3156 /* create nst (nt-mode only) */
3159 mgr = &mISDNport->mgr;
3160 nst = &mISDNport->nst;
3165 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3166 nst->device = mISDNdevice;
3168 nst->d_stid = mISDNport->d_stid;
3170 nst->feature = FEATURE_NET_HOLD;
3172 nst->feature |= FEATURE_NET_PTP;
3174 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3177 while(i < mISDNport->b_num)
3179 nst->b_stid[i] = mISDNport->b_stid[i];
3183 nst->l1_id = mISDNport->lower_id;
3184 nst->l2_id = mISDNport->upper_id;
3187 msg_queue_init(&nst->down_queue);
3193 mISDNport->b_num = stinf->childcnt;
3195 mISDNport->portnum = port;
3196 mISDNport->ntmode = nt;
3197 mISDNport->pri = pri;
3198 mISDNport->ptp = ptp;
3199 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3201 while(i < mISDNport->b_num)
3203 mISDNport->b_state[i] = B_STATE_IDLE;
3205 mISDNport->b_socket[i] = -1;
3207 mISDNport->b_stid[i] = stinf->child[i];
3208 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3214 /* if ptp, pull up the link */
3218 // mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
3219 // l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3221 time(&mISDNport->l2establish);
3224 /* if te-mode, query state link */
3225 if (!mISDNport->ntmode)
3229 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3230 act.prim = MGR_SHORTSTATUS | REQUEST;
3231 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3232 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3234 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3235 time(&mISDNport->l2establish);
3237 /* if ptp AND te-mode, pull up the link */
3238 if (mISDNport->ptp && !mISDNport->ntmode)
3242 act.prim = DL_ESTABLISH | REQUEST;
3243 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3246 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3247 time(&mISDNport->l2establish);
3249 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3252 /* if ptp AND nt-mode, pull up the link */
3253 if (mISDNport->ptp && mISDNport->ntmode)
3257 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3258 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3260 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3264 /* initially, we assume that the link is down, exept for nt-ptmp */
3265 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3267 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3269 start_trace(mISDNport->portnum,
3277 add_trace("channels", NULL, "%d", mISDNport->b_num);
3284 * function to free ALL cards (ports)
3286 void mISDNport_close_all(void)
3288 /* free all ports */
3289 while(mISDNport_first)
3290 mISDNport_close(mISDNport_first);
3294 * free only one port
3296 void mISDNport_close(struct mISDNport *mISDNport)
3298 struct mISDNport **mISDNportp;
3300 class PmISDN *isdnport;
3304 unsigned char buf[32];
3308 /* remove all port instance that are linked to this mISDNport */
3312 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3314 isdnport = (class PmISDN *)port;
3315 if (isdnport->p_m_mISDNport)
3317 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3324 /* only if we are already part of interface */
3325 if (mISDNport->ifport)
3327 start_trace(mISDNport->portnum,
3328 mISDNport->ifport->interface,
3338 /* free bchannels */
3340 while(i < mISDNport->b_num)
3343 if (mISDNport->b_socket[i] > -1)
3345 if (mISDNport->b_addr[i])
3348 _bchannel_destroy(mISDNport, i);
3349 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3355 close_layer3(mISDNport->ml3);
3357 /* free ressources of port */
3358 msg_queue_purge(&mISDNport->downqueue);
3361 if (mISDNport->ntmode)
3363 nst = &mISDNport->nst;
3364 if (nst->manager) /* to see if initialized */
3366 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");
3367 cleanup_Isdnl3(nst);
3368 cleanup_Isdnl2(nst);
3371 msg_queue_purge(&nst->down_queue);
3372 if (nst->phd_down_msg)
3373 FREE(nst->phd_down_msg, 0);
3377 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3378 if (mISDNport->d_stid)
3380 if (mISDNport->upper_id)
3381 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3385 /* remove from list */
3386 mISDNportp = &mISDNport_first;
3389 if (*mISDNportp == mISDNport)
3391 *mISDNportp = (*mISDNportp)->next;
3395 mISDNportp = &((*mISDNportp)->next);
3399 FATAL("mISDNport not in list\n");
3401 FREE(mISDNport, sizeof(struct mISDNport));
3408 * global function to show all available isdn ports
3410 void mISDN_port_info(void)
3414 int useable, nt, te, pri, bri, pots;
3416 struct mISDN_devinfo devinfo;
3420 sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3423 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3427 /* get number of stacks */
3429 ret = ioctl(sock, IMGETCOUNT, &ii);
3432 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3437 unsigned char buff[1025];
3438 iframe_t *frm = (iframe_t *)buff;
3439 stack_info_t *stinf;
3443 if ((device = mISDN_open()) < 0)
3445 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));
3449 /* get number of stacks */
3451 ii = mISDN_get_stack_count(device);
3456 printf("Found no card. Please be sure to load card drivers.\n");
3460 /* loop the number of cards and get their info */
3463 nt = te = bri = pri = pots = 0;
3468 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
3471 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3475 /* output the port info */
3476 printf("Port %2d name='%s': ", i, devinfo.name);
3477 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3482 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3488 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3495 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3502 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3509 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3515 if ((te || nt) && (bri || pri || pots))
3519 printf("TE-mode BRI S/T interface line (for phone lines)");
3521 printf("NT-mode BRI S/T interface port (for phones)");
3523 printf("TE-mode PRI E1 interface line (for phone lines)");
3525 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3527 printf("FXS POTS interface port (for analog lines)");
3529 printf("FXO POTS interface port (for analog phones)");
3533 printf("\n -> Analog interfaces are not supported.");
3537 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3541 printf(" - %d B-channels\n", devinfo.nrbchan);
3543 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3546 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3549 stinf = (stack_info_t *)&frm->data.p;
3551 /* output the port info */
3552 printf("Port %2d: ", i);
3553 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3555 case ISDN_PID_L0_TE_S0:
3559 printf("TE-mode BRI S/T interface line (for phone lines)");
3561 case ISDN_PID_L0_NT_S0:
3565 printf("NT-mode BRI S/T interface port (for phones)");
3567 case ISDN_PID_L0_TE_E1:
3571 printf("TE-mode PRI E1 interface line (for phone lines)");
3573 case ISDN_PID_L0_NT_E1:
3577 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3581 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3587 if (stinf->pid.protocol[1] == 0)
3590 printf(" -> Missing layer 1 NT-mode protocol.\n");
3593 while(p <= MAX_LAYER_NR) {
3594 if (stinf->pid.protocol[p])
3597 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3604 printf(" -> Interface is Point-To-Point (PRI).\n");
3606 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3611 if (stinf->pid.protocol[1] == 0)
3614 printf(" -> Missing layer 1 protocol.\n");
3616 if (stinf->pid.protocol[2] == 0)
3619 printf(" -> Missing layer 2 protocol.\n");
3621 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3623 printf(" -> Interface is Poin-To-Point.\n");
3625 if (stinf->pid.protocol[3] == 0)
3628 printf(" -> Missing layer 3 protocol.\n");
3631 printf(" -> Protocol: ");
3632 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3634 case ISDN_PID_L3_DSS1USER:
3635 printf("DSS1 (Euro ISDN)");
3640 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3645 while(p <= MAX_LAYER_NR) {
3646 if (stinf->pid.protocol[p])
3649 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3654 printf(" - %d B-channels\n", stinf->childcnt);
3658 printf(" * Port NOT useable for LCR\n");
3660 printf("--------\n");
3671 if ((ret = mISDN_close(device)))
3672 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3678 * enque data from upper buffer
3680 void PmISDN::txfromup(unsigned char *data, int length)
3683 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3684 struct mISDNhead *hh = (struct mISDNhead *)buf;
3687 if (p_m_b_index < 0)
3689 if (!p_m_mISDNport->b_socket[p_m_b_index])
3692 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3693 iframe_t *frm = (iframe_t *)buf;
3695 if (p_m_b_index < 0)
3697 if (!p_m_mISDNport->b_addr[p_m_b_index])
3701 /* check if high priority tones exist
3702 * ignore data in this case
3704 if (p_tone_name[0] || p_m_crypt_msg_loops)
3707 /* preload procedure
3708 * if transmit buffer in DSP module is empty,
3709 * preload it to DSP_LOAD to prevent jitter gaps.
3711 if (p_m_load==0 && ISDN_LOAD>0)
3714 hh->prim = DL_DATA_REQ;
3716 memcpy(buf+MISDN_HEADER_LEN, data, ISDN_LOAD);
3717 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
3719 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3721 frm->prim = DL_DATA | REQUEST;
3722 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3724 frm->len = ISDN_LOAD;
3725 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3726 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+ISDN_LOAD, TIMEOUT_1SEC);
3728 p_m_load += ISDN_LOAD;
3731 /* drop if load would exceed ISDN_MAXLOAD
3732 * this keeps the delay not too high
3734 if (p_m_load+length > ISDN_MAXLOAD)
3737 /* make and send frame */
3739 hh->prim = DL_DATA_REQ;
3741 memcpy(buf+MISDN_HEADER_LEN, data, length);
3742 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3744 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3746 frm->prim = DL_DATA | REQUEST;
3747 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3750 memcpy(buf+mISDN_HEADER_LEN, data, length);
3751 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);