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
68 #ifdef __compiler_offsetof
69 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
71 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
74 #define container_of(ptr, type, member) ({ \
75 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
76 (type *)( (char *)__mptr - offsetof(type,member) );})
79 // timeouts if activating/deactivating response from mISDN got lost
80 #define B_TIMER_ACTIVATING 1 // seconds
81 #define B_TIMER_DEACTIVATING 1 // seconds
83 /* list of mISDN ports */
84 struct mISDNport *mISDNport_first;
86 /* noise randomizer */
87 unsigned char mISDN_rand[256];
88 int mISDN_rand_count = 0;
91 unsigned long mt_assign_pid = ~0;
95 int mISDN_initialize(void)
99 /* try to open raw socket to check kernel */
100 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
103 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
107 /* open debug, if enabled and not only stack debugging */
108 if (options.deb && (options.deb != DEBUG_STACK))
110 SPRINT(filename, "%s/debug.log", INSTALL_DATA);
111 debug_fp = fopen(filename, "a");
114 if (options.deb & DEBUG_STACK)
116 SPRINT(filename, "%s/debug_mISDN.log", INSTALL_DATA);
117 mISDN_debug_init(0xffffffff, filename, filename, filename);
119 mISDN_debug_init(0, NULL, NULL, NULL);
122 init_layer3(4); // buffer of 4
127 void mISDN_deinitialize(void)
137 if (mISDNsocket > -1)
141 int entity = 0; /* used for udevice */
142 int mISDNdevice = -1; /* the device handler and port list */
144 int mISDN_initialize(void)
147 unsigned char buff[1025];
148 iframe_t *frm = (iframe_t *)buff;
151 /* initialize stuff of the NT lib */
152 if (options.deb & DEBUG_STACK)
154 global_debug = 0xffffffff & ~DBGM_MSG;
155 // global_debug = DBGM_L3DATA;
157 global_debug = DBGM_MAN;
158 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
159 if (options.deb & DEBUG_LOG)
160 debug_init(global_debug, debug_log, debug_log, debug_log);
162 debug_init(global_debug, NULL, NULL, NULL);
165 /* open mISDNdevice if not already open */
171 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));
175 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
177 /* create entity for layer 3 TE-mode */
178 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
179 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
180 if (ret < (int)mISDN_HEADER_LEN)
183 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
185 entity = frm->dinfo & 0xffff;
188 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
193 void mISDN_deinitialize(void)
195 unsigned char buff[1025];
200 if (mISDNdevice > -1)
203 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
205 mISDN_close(mISDNdevice);
207 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
215 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
217 p_m_mISDNport = mISDNport;
218 p_m_portnum = mISDNport->portnum;
225 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
226 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
234 p_m_dtmf = !mISDNport->ifport->nodtmf;
237 p_m_remote_ref = 0; /* channel shall be exported to given remote */
238 p_m_remote_id = 0; /* channel shall be exported to given remote */
239 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
247 p_m_crypt_listen = 0;
248 p_m_crypt_msg_loops = 0;
249 p_m_crypt_msg_loops = 0;
250 p_m_crypt_msg_len = 0;
251 p_m_crypt_msg[0] = '\0';
252 p_m_crypt_msg_current = 0;
253 p_m_crypt_key_len = 0;
254 p_m_crypt_listen = 0;
255 p_m_crypt_listen_state = 0;
256 p_m_crypt_listen_len = 0;
257 p_m_crypt_listen_msg[0] = '\0';
258 p_m_crypt_listen_crc = 0;
259 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
261 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
262 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
266 /* if any channel requested by constructor */
267 if (channel == CHANNEL_ANY)
269 /* reserve channel */
271 mISDNport->b_reserved++;
274 /* reserve channel */
275 if (channel > 0) // only if constructor was called with a channel resevation
276 seize_bchannel(channel, exclusive);
278 /* we increase the number of objects: */
280 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
289 struct lcr_msg *message;
291 /* remove bchannel relation */
297 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
298 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
299 message->param.disconnectinfo.cause = 16;
300 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
301 message_put(message);
302 /* remove from list */
303 free_epointlist(p_epointlist);
306 /* we decrease the number of objects: */
307 p_m_mISDNport->use--;
308 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
315 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
317 /* init trace with given values */
318 start_trace(mISDNport?mISDNport->portnum:0,
319 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
320 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
321 port?port->p_dialinginfo.id:NULL,
324 port?port->p_serial:0,
332 static struct isdn_message {
336 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
337 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
338 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
339 {"DL_RELEASE", L2_RELEASE_REQ},
340 {"UNKNOWN", L3_UNKNOWN},
341 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
342 {"MT_SETUP", L3_SETUP_REQ},
343 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
344 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
345 {"MT_ALERTING", L3_ALERTING_REQ},
346 {"MT_CONNECT", L3_CONNECT_REQ},
347 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
348 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
349 {"MT_RELEASE", L3_RELEASE_REQ},
350 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
351 {"MT_INFORMATION", L3_INFORMATION_REQ},
352 {"MT_PROGRESS", L3_PROGRESS_REQ},
353 {"MT_NOTIFY", L3_NOTIFY_REQ},
354 {"MT_SUSPEND", L3_SUSPEND_REQ},
355 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
356 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
357 {"MT_RESUME", L3_RESUME_REQ},
358 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
359 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
360 {"MT_HOLD", L3_HOLD_REQ},
361 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
362 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
363 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
364 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
365 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
366 {"MT_FACILITY", L3_FACILITY_REQ},
367 {"MT_STATUS", L3_STATUS_REQ},
368 {"MT_RESTART", L3_RESTART_REQ},
370 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
371 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
373 {"MT_NEW_CR", L3_NEW_CR_REQ},
374 {"MT_RELEASE_CR", L3_RELEASE_CR_REQ},
379 static char *isdn_prim[4] = {
385 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long msg, int direction)
388 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
390 /* select message and primitive text */
392 while(isdn_message[i].name)
394 if (isdn_message[i].value == (msg&0xffffff00))
396 SCPY(msgtext, isdn_message[i].name);
401 SCAT(msgtext, isdn_prim[msg&0x00000003]);
405 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
407 if (direction && (msg&0xffffff00)!=L3_NEW_CR_REQ && (msg&0xffffff00)!=L3_RELEASE_CR_REQ)
412 if (mISDNport->ntmode)
414 if (direction == DIRECTION_OUT)
415 SCAT(msgtext, " N->U");
417 SCAT(msgtext, " N<-U");
420 if (direction == DIRECTION_OUT)
421 SCAT(msgtext, " U->N");
423 SCAT(msgtext, " U<-N");
428 /* init trace with given values */
429 start_trace(mISDNport?mISDNport->portnum:0,
430 mISDNport?mISDNport->ifport->interface:NULL,
431 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
432 port?port->p_dialinginfo.id:NULL,
435 port?port->p_serial:0,
441 * send control information to the channel (dsp-module)
443 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
446 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
447 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
448 unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
451 ctrl->prim = PH_CONTROL_REQ;
455 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
457 PERROR("Failed to send to socket %d\n", handle);
459 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
460 iframe_t *ctrl = (iframe_t *)buffer;
461 unsigned long *d = (unsigned long *)&ctrl->data.p;
463 ctrl->prim = PH_CONTROL | REQUEST;
464 ctrl->addr = handle | FLG_MSG_DOWN;
466 ctrl->len = sizeof(int)*2;
469 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
471 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
473 if (c1 == DSP_CONF_JOIN)
475 if (c1 == CMX_CONF_JOIN)
477 add_trace(trace_name, NULL, "0x%08x", trace_value);
479 add_trace(trace_name, NULL, "%d", trace_value);
483 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)
486 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
487 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
488 unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
491 ctrl->prim = PH_CONTROL_REQ;
494 memcpy(d, c2, c2_len);
495 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
497 PERROR("Failed to send to socket %d\n", handle);
499 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
500 iframe_t *ctrl = (iframe_t *)buffer;
501 unsigned long *d = (unsigned long *)&ctrl->data.p;
503 ctrl->prim = PH_CONTROL | REQUEST;
504 ctrl->addr = handle | FLG_MSG_DOWN;
506 ctrl->len = sizeof(int)+c2_len;
508 memcpy(d, c2, c2_len);
509 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
511 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
512 add_trace(trace_name, NULL, "%d", trace_value);
518 * subfunction for bchannel_event
521 static int _bchannel_create(struct mISDNport *mISDNport, int i)
525 unsigned long on = 1;
526 struct sockaddr_mISDN addr;
528 if (mISDNport->b_socket[i])
530 PERROR("Error: Socket already created for index %d\n", i);
535 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
536 if (mISDNport->b_socket[i] < 0)
538 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
542 /* set nonblocking io */
543 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
546 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
547 close(mISDNport->b_socket[i]);
548 mISDNport->b_socket[i] = -1;
552 /* bind socket to bchannel */
553 addr.family = AF_ISDN;
554 addr.dev = mISDNport->portnum-1;
555 addr.channel = i+1+(i>=15);
556 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
559 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
560 close(mISDNport->b_socket[i]);
561 mISDNport->b_socket[i] = -1;
565 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
566 add_trace("channel", NULL, "%d", i+1+(i>=15));
567 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
572 unsigned char buff[1024];
576 if (!mISDNport->b_stid[i])
578 PERROR("Error: no stack for index %d\n", i);
581 if (mISDNport->b_addr[i])
583 PERROR("Error: stack already created for index %d\n", i);
587 /* create new layer */
588 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
589 memset(&li, 0, sizeof(li));
590 memset(&pid, 0, sizeof(pid));
593 li.st = mISDNport->b_stid[i];
594 UCPY(li.name, "B L4");
595 li.pid.layermask = ISDN_LAYER((4));
596 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
597 ret = mISDN_new_layer(mISDNdevice, &li);
601 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
604 mISDNport->b_addr[i] = li.id;
607 goto failed_new_layer;
609 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
611 /* create new stack */
612 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
613 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
614 pid.protocol[3] = ISDN_PID_L3_B_DSP;
615 pid.protocol[4] = ISDN_PID_L4_B_USER;
616 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
617 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
621 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
622 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
625 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
630 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
631 if (!mISDNport->b_addr[i])
633 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
634 add_trace("channel", NULL, "%d", i+1+(i>=15));
635 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
636 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
642 mISDNport->b_addr[i] = 0;
649 * subfunction for bchannel_event
650 * activate / deactivate request
652 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
655 struct mISDNhead act;
658 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
660 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
662 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
666 /* activate bchannel */
667 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
668 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
671 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
675 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
676 add_trace("channel", NULL, "%d", i+1+(i>=15));
677 if (mISDNport->b_timer[i])
678 add_trace("event", NULL, "timeout recovery");
684 * subfunction for bchannel_event
687 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
693 handle = mISDNport->b_socket[i];
694 port = mISDNport->b_port[i];
697 PERROR("bchannel index i=%d not associated with a port object\n", i);
701 /* set dsp features */
702 if (port->p_m_txdata)
703 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
705 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
706 if (port->p_m_tx_gain)
707 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
708 if (port->p_m_rx_gain)
709 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
710 if (port->p_m_pipeline[0])
711 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
713 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
715 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
717 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
719 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
720 // if (port->p_m_txmix)
721 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
723 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
725 ph_control_block(mISDNport, port, handle, DSP_BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
727 unsigned long handle;
729 handle = mISDNport->b_addr[i];
730 port = mISDNport->b_port[i];
733 PERROR("bchannel index i=%d not associated with a port object\n", i);
737 /* set dsp features */
739 if (port->p_m_txdata)
740 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
742 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
744 if (port->p_m_tx_gain)
745 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
746 if (port->p_m_rx_gain)
747 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
749 if (port->p_m_pipeline[0])
750 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
753 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
755 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
757 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
759 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
760 // if (port->p_m_txmix)
761 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
763 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
765 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);
770 * subfunction for bchannel_event
773 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
776 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
777 add_trace("channel", NULL, "%d", i+1+(i>=15));
778 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
780 if (mISDNport->b_socket[i] > -1)
782 close(mISDNport->b_socket[i]);
783 mISDNport->b_socket[i] = -1;
786 unsigned char buff[1024];
788 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
789 add_trace("channel", NULL, "%d", i+1+(i>=15));
790 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
791 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
793 /* remove our stack only if set */
794 if (mISDNport->b_addr[i])
796 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
797 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
798 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
799 mISDNport->b_addr[i] = 0;
809 A bchannel goes through the following states in this order:
812 No one is using the bchannel.
813 It is available and not linked to Port class, nor reserved.
816 The bchannel stack is created and an activation request is sent.
817 It MAY be linked to Port class, but already unlinked due to Port class removal.
820 The bchannel is active and cofigured to the Port class needs.
821 Also it is linked to a Port class, otherwhise it would be deactivated.
823 - B_STATE_DEACTIVATING
824 The bchannel is in deactivating state, due to deactivation request.
825 It may be linked to a Port class, that likes to reactivate it.
829 After deactivating bchannel, and if not used, the bchannel becomes idle again.
831 Also the bchannel may be exported, but only if the state is or becomes idle:
834 The bchannel assignment has been sent to the remove application.
837 The bchannel assignment is acknowledged by the remote application.
840 The bchannel is re-imported by mISDN port object.
844 After re-importing bchannel, and if not used, the bchannel becomes idle again.
847 A bchannel can have the following events:
850 A bchannel is required by a Port class.
851 The bchannel shall be exported to the remote application.
854 The bchannel beomes active.
857 The bchannel is not required by Port class anymore
859 - B_EVENT_DEACTIVATED
860 The bchannel becomes inactive.
863 The bchannel is now used by remote application.
866 The bchannel is not used by remote application.
868 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
870 if an export request is receive by remote application, p_m_remote_* is set.
871 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.)
872 - set on export request from remote application (if port is assigned)
873 - set on channel use, if requested by remote application (p_m_remote_*)
874 - cleared on drop request
876 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
877 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
878 the bchannel import/export is acknowledged with stack given.
880 if exporting, b_remote_*[index] is set to the remote socket id.
881 if importing has been acknowledged. b_remote_*[index] is cleared.
886 * process bchannel events
887 * - mISDNport is a pointer to the port's structure
888 * - i is the index of the bchannel
889 * - event is the B_EVENT_* value
890 * - port is the PmISDN class pointer
892 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
894 class PmISDN *b_port = mISDNport->b_port[i];
895 int state = mISDNport->b_state[i];
896 double timer = mISDNport->b_timer[i];
897 unsigned long p_m_remote_ref = 0;
898 unsigned long p_m_remote_id = 0;
901 char *p_m_pipeline = NULL;
902 unsigned char *p_m_crypt_key = NULL;
903 int p_m_crypt_key_len = 0;
904 int p_m_crypt_key_type = 0;
906 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
908 unsigned long portid = mISDNport->b_stid[i];
913 p_m_remote_id = b_port->p_m_remote_id;
914 p_m_remote_ref = b_port->p_m_remote_ref;
915 p_m_tx_gain = b_port->p_m_tx_gain;
916 p_m_rx_gain = b_port->p_m_rx_gain;
917 p_m_pipeline = b_port->p_m_pipeline;
918 p_m_crypt_key = b_port->p_m_crypt_key;
919 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
920 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
926 /* port must be linked in order to allow activation */
928 FATAL("bchannel must be linked to a Port class\n");
934 /* export bchannel */
935 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);
936 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
937 add_trace("type", NULL, "assign");
939 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
941 add_trace("socket", "id", "%d", portid);
944 state = B_STATE_EXPORTING;
945 mISDNport->b_remote_id[i] = p_m_remote_id;
946 mISDNport->b_remote_ref[i] = p_m_remote_ref;
949 /* create stack and send activation request */
950 if (_bchannel_create(mISDNport, i))
952 _bchannel_activate(mISDNport, i, 1);
953 state = B_STATE_ACTIVATING;
954 timer = now_d + B_TIMER_ACTIVATING;
959 case B_STATE_ACTIVATING:
960 case B_STATE_EXPORTING:
961 /* do nothing, because it is already activating */
964 case B_STATE_DEACTIVATING:
965 case B_STATE_IMPORTING:
966 /* do nothing, because we must wait until we can reactivate */
970 /* problems that might ocurr:
971 * B_EVENT_USE is received when channel already in use.
972 * bchannel exported, but not freed by other port
974 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
978 case B_EVENT_EXPORTREQUEST:
979 /* special case where the bchannel is requested by remote */
982 PERROR("export request without remote channel set, please correct.\n");
988 /* in case, the bchannel is exported right after seize_bchannel */
989 /* export bchannel */
990 /* p_m_remote_id is set, when this event happens. */
991 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);
992 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
993 add_trace("type", NULL, "assign");
995 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
997 add_trace("socket", "id", "%d", portid);
1000 state = B_STATE_EXPORTING;
1001 mISDNport->b_remote_id[i] = p_m_remote_id;
1002 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1005 case B_STATE_ACTIVATING:
1006 case B_STATE_EXPORTING:
1007 /* do nothing, because it is already activating */
1010 case B_STATE_DEACTIVATING:
1011 case B_STATE_IMPORTING:
1012 /* do nothing, because we must wait until we can reactivate */
1015 case B_STATE_ACTIVE:
1016 /* bchannel is active, so we deactivate */
1017 _bchannel_activate(mISDNport, i, 0);
1018 state = B_STATE_DEACTIVATING;
1019 timer = now_d + B_TIMER_DEACTIVATING;
1023 /* problems that might ocurr:
1024 * ... when channel already in use.
1025 * bchannel exported, but not freed by other port
1027 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1031 case B_EVENT_ACTIVATED:
1035 case B_STATE_ACTIVATING:
1036 if (b_port && !p_m_remote_id)
1038 /* bchannel is active and used by Port class, so we configure bchannel */
1039 _bchannel_configure(mISDNport, i);
1040 state = B_STATE_ACTIVE;
1043 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
1044 _bchannel_activate(mISDNport, i, 0);
1045 state = B_STATE_DEACTIVATING;
1046 timer = now_d + B_TIMER_DEACTIVATING;
1051 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1055 case B_EVENT_EXPORTED:
1058 case B_STATE_EXPORTING:
1059 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
1061 /* remote export done */
1062 state = B_STATE_REMOTE;
1065 /* bchannel is now exported, but we need bchannel back
1066 * OR bchannel is not used anymore
1067 * OR bchannel has been exported to an obsolete ref,
1068 * so reimport, to later export to new remote */
1069 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1070 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1071 add_trace("type", NULL, "remove");
1073 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1075 add_trace("socket", "id", "%d", portid);
1078 state = B_STATE_IMPORTING;
1083 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1089 FATAL("bchannel must be linked to a Port class\n");
1093 /* bchannel is idle due to an error, so we do nothing */
1096 case B_STATE_ACTIVATING:
1097 case B_STATE_EXPORTING:
1098 /* do nothing because we must wait until bchanenl is active before deactivating */
1101 case B_STATE_ACTIVE:
1102 /* bchannel is active, so we deactivate */
1103 _bchannel_activate(mISDNport, i, 0);
1104 state = B_STATE_DEACTIVATING;
1105 timer = now_d + B_TIMER_DEACTIVATING;
1108 case B_STATE_REMOTE:
1109 /* bchannel is exported, so we re-import */
1110 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1111 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1112 add_trace("type", NULL, "remove");
1114 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1116 add_trace("socket", "id", "%d", portid);
1119 state = B_STATE_IMPORTING;
1122 case B_STATE_DEACTIVATING:
1123 case B_STATE_IMPORTING:
1124 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1128 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1132 case B_EVENT_DEACTIVATED:
1137 /* ignore due to deactivation confirm after unloading */
1140 case B_STATE_DEACTIVATING:
1141 _bchannel_destroy(mISDNport, i);
1142 state = B_STATE_IDLE;
1145 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1148 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);
1149 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1150 add_trace("type", NULL, "assign");
1152 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1154 add_trace("socket", "id", "%d", portid);
1157 state = B_STATE_EXPORTING;
1158 mISDNport->b_remote_id[i] = p_m_remote_id;
1159 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1162 if (_bchannel_create(mISDNport, i))
1164 _bchannel_activate(mISDNport, i, 1);
1165 state = B_STATE_ACTIVATING;
1166 timer = now_d + B_TIMER_ACTIVATING;
1173 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1177 case B_EVENT_IMPORTED:
1180 case B_STATE_IMPORTING:
1181 state = B_STATE_IDLE;
1182 mISDNport->b_remote_id[i] = 0;
1183 mISDNport->b_remote_ref[i] = 0;
1186 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1189 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);
1190 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1191 add_trace("type", NULL, "assign");
1193 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1195 add_trace("socket", "id", "%d", portid);
1198 state = B_STATE_EXPORTING;
1199 mISDNport->b_remote_id[i] = p_m_remote_id;
1200 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1203 if (_bchannel_create(mISDNport, i))
1205 _bchannel_activate(mISDNport, i, 1);
1206 state = B_STATE_ACTIVATING;
1207 timer = now_d + B_TIMER_ACTIVATING;
1214 /* ignore, because not assigned */
1219 case B_EVENT_TIMEOUT:
1224 /* ignore due to deactivation confirm after unloading */
1227 case B_STATE_ACTIVATING:
1228 _bchannel_activate(mISDNport, i, 1);
1229 timer = now_d + B_TIMER_ACTIVATING;
1232 case B_STATE_DEACTIVATING:
1233 _bchannel_activate(mISDNport, i, 0);
1234 timer = now_d + B_TIMER_DEACTIVATING;
1238 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1243 PERROR("Illegal event %d, please correct.\n", event);
1246 mISDNport->b_state[i] = state;
1247 mISDNport->b_timer[i] = timer;
1254 * check for available channel and reserve+set it.
1255 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1256 * give exclusiv flag
1257 * returns -(cause value) or x = channel x or 0 = no channel
1258 * NOTE: no activation is done here
1260 int PmISDN::seize_bchannel(int channel, int exclusive)
1264 /* the channel is what we have */
1265 if (p_m_b_channel == channel)
1268 /* if channel already in use, release it */
1273 if (channel==CHANNEL_NO || channel==0)
1276 /* is channel in range ? */
1278 || (channel>p_m_mISDNport->b_num && channel<16)
1279 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1280 return(-6); /* channel unacceptable */
1282 /* request exclusive channel */
1283 if (exclusive && channel>0)
1285 i = channel-1-(channel>16);
1286 if (p_m_mISDNport->b_port[i])
1287 return(-44); /* requested channel not available */
1291 /* ask for channel */
1294 i = channel-1-(channel>16);
1295 if (p_m_mISDNport->b_port[i] == NULL)
1299 /* search for channel */
1301 while(i < p_m_mISDNport->b_num)
1303 if (!p_m_mISDNport->b_port[i])
1305 channel = i+1+(i>=15);
1310 return(-34); /* no free channel */
1313 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1316 p_m_mISDNport->b_port[i] = this;
1318 p_m_b_channel = channel;
1319 p_m_b_exclusive = exclusive;
1321 /* reserve channel */
1325 p_m_mISDNport->b_reserved++;
1332 * drop reserved channel and unset it.
1333 * deactivation is also done
1335 void PmISDN::drop_bchannel(void)
1337 /* unreserve channel */
1339 p_m_mISDNport->b_reserved--;
1343 if (p_m_b_index < 0)
1348 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1350 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1351 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1352 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1355 p_m_b_exclusive = 0;
1358 /* process bchannel export/import message from join */
1359 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1361 class Endpoint *epoint;
1363 class PmISDN *isdnport;
1364 struct mISDNport *mISDNport;
1369 case BCHANNEL_REQUEST:
1370 /* find the port object for the join object ref */
1371 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1373 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1376 if (!epoint->ep_portlist)
1378 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1381 if (epoint->ep_portlist->next)
1383 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);
1385 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1387 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1390 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1392 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1394 isdnport = (class PmISDN *)port;
1397 if (isdnport->p_m_remote_id)
1399 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1402 mISDNport = isdnport->p_m_mISDNport;
1403 i = isdnport->p_m_b_index;
1404 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1405 add_trace("type", NULL, "export request");
1406 isdnport->p_m_remote_ref = joinremote->j_serial;
1407 isdnport->p_m_remote_id = joinremote->j_remote_id;
1408 if (mISDNport && i>=0)
1410 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1415 case BCHANNEL_ASSIGN_ACK:
1416 case BCHANNEL_REMOVE_ACK:
1417 /* find mISDNport for stack ID */
1418 mISDNport = mISDNport_first;
1422 ii = mISDNport->b_num;
1426 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1428 if (mISDNport->b_addr[i] == handle)
1435 mISDNport = mISDNport->next;
1439 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1442 /* mISDNport may now be set or NULL */
1445 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1446 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1447 if (mISDNport && i>=0)
1448 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1452 PERROR("received wrong bchannel message type %d from remote\n", type);
1460 audio transmission procedure:
1461 -----------------------------
1464 three sources of audio transmission:
1465 - crypto-data high priority
1466 - tones high priority (also high)
1467 - remote-data low priority
1470 a variable that temporarily shows the number of samples elapsed since last transmission process.
1471 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1474 a variable that is increased whenever data is transmitted.
1475 it is decreased while time elapses. it stores the number of samples that
1476 are currently loaded to dsp module.
1477 since clock in dsp module is the same clock for user space process, these
1481 there are two levels:
1482 ISDN_LOAD will give the load that have to be kept in dsp.
1483 ISDN_MAXLOAD will give the maximum load before dropping.
1485 * procedure for low priority data
1486 see txfromup() for procedure
1487 in short: remote data is ignored during high priority tones
1489 * procedure for high priority data
1490 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1491 if no more data is available, load becomes empty again.
1494 0 ISDN_LOAD ISDN_MAXLOAD
1495 +--------------------+----------------------+
1497 +--------------------+----------------------+
1499 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1500 0 ISDN_LOAD ISDN_MAXLOAD
1501 +--------------------+----------------------+
1502 |TTTTTTTTTTTTTTTTTTTT| |
1503 +--------------------+----------------------+
1505 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1506 0 ISDN_LOAD ISDN_MAXLOAD
1507 +--------------------+----------------------+
1508 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1509 +--------------------+----------------------+
1512 int PmISDN::handler(void)
1514 struct lcr_msg *message;
1518 if ((ret = Port::handler()))
1522 if (p_m_last_tv_sec)
1524 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1525 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1528 /* set clock of first process ever in this instance */
1529 p_m_last_tv_sec = now_tv.tv_sec;
1530 p_m_last_tv_msec = now_tv.tv_usec/1000;
1532 /* process only if we have a minimum of samples, to make packets not too small */
1533 if (elapsed >= ISDN_TRANSMIT)
1535 /* set clock of last process! */
1536 p_m_last_tv_sec = now_tv.tv_sec;
1537 p_m_last_tv_msec = now_tv.tv_usec/1000;
1540 if (elapsed < p_m_load)
1541 p_m_load -= elapsed;
1545 /* to send data, tone must be active OR crypt messages must be on */
1546 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1547 && (p_m_load < ISDN_LOAD)
1548 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1550 int tosend = ISDN_LOAD - p_m_load, length;
1552 unsigned char buf[MISDN_HEADER_LEN+tosend];
1553 struct mISDNhead *frm = (struct mISDNhead *)buf;
1554 unsigned char *p = buf+MISDN_HEADER_LEN;
1556 unsigned char buf[mISDN_HEADER_LEN+tosend];
1557 iframe_t *frm = (iframe_t *)buf;
1558 unsigned char *p = buf+mISDN_HEADER_LEN;
1561 /* copy crypto loops */
1562 while (p_m_crypt_msg_loops && tosend)
1564 /* how much do we have to send */
1565 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1568 if (length > tosend)
1571 /* copy message (part) to buffer */
1572 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1575 p_m_crypt_msg_current += length;
1576 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1579 p_m_crypt_msg_current = 0;
1580 p_m_crypt_msg_loops--;
1581 // puts("eine loop weniger");
1589 if (p_tone_name[0] && tosend)
1591 tosend -= read_audio(p, tosend);
1596 frm->prim = DL_DATA_REQ;
1598 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1600 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
1602 frm->prim = DL_DATA | REQUEST;
1603 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1605 frm->len = ISDN_LOAD - p_m_load - tosend;
1607 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1609 p_m_load += ISDN_LOAD - p_m_load - tosend;
1613 // NOTE: deletion is done by the child class
1615 /* handle timeouts */
1618 if (p_m_timer+p_m_timeout < now_d)
1620 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1622 /* send timeout to endpoint */
1623 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1624 message->param.state = p_state;
1625 message_put(message);
1630 return(0); /* nothing done */
1635 * whenever we get audio data from bchannel, we process it here
1638 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1640 unsigned long cont = *((unsigned long *)data);
1642 void PmISDN::bchannel_receive(iframe_t *frm)
1645 unsigned long cont = *((unsigned long *)&frm->data.p);
1646 unsigned char *data =(unsigned char *)&frm->data.p;
1648 unsigned char *data_temp;
1649 unsigned long length_temp;
1650 struct lcr_msg *message;
1655 if (hh->prim == PH_CONTROL_IND)
1657 if (frm->prim == (PH_CONTROL | INDICATION))
1662 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1665 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1667 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1668 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1670 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1671 message->param.dtmf = cont & DTMF_TONE_MASK;
1672 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1673 message_put(message);
1683 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1684 add_trace("DSP-CRYPT", NULL, "error");
1686 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1687 message->param.crypt.type = CC_ERROR_IND;
1688 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1689 message_put(message);
1697 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1698 add_trace("DSP-CRYPT", NULL, "ok");
1700 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1701 message->param.crypt.type = CC_ACTBF_CONF;
1702 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1703 message_put(message);
1707 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1708 add_trace("unknown", NULL, "0x%x", cont);
1714 if (hh->prim == PH_CONTROL_IND)
1718 if (frm->prim == (PH_SIGNAL | INDICATION)
1719 || frm->prim == (PH_CONTROL | INDICATION))
1732 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1733 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1736 /* see below (same condition) */
1737 if (p_state!=PORT_STATE_CONNECT
1738 && !p_m_mISDNport->tones)
1740 // printf(".");fflush(stdout);return;
1742 record(data, len, 1); // from up
1747 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1749 add_trace("unknown", NULL, "0x%x", hh->id);
1751 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1758 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1760 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1762 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1764 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1768 /* calls will not process any audio data unless
1769 * the call is connected OR interface features audio during call setup.
1771 //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);
1772 #ifndef DEBUG_COREBRIDGE
1773 if (p_state!=PORT_STATE_CONNECT
1774 && !p_m_mISDNport->tones)
1778 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1781 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1787 record(data, len, 0); // from down
1789 /* randomize and listen to crypt message if enabled */
1790 if (p_m_crypt_listen)
1792 /* the noisy randomizer */
1796 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1798 cryptman_listen_bch(data, len);
1803 /* send data to epoint */
1804 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1810 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1811 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1812 memcpy(message->param.data.data, data_temp, message->param.data.len);
1813 message_put(message);
1814 if (length_temp <= sizeof(message->param.data.data))
1816 data_temp += sizeof(message->param.data.data);
1817 length_temp -= sizeof(message->param.data.data);
1826 void PmISDN::set_echotest(int echo)
1828 if (p_m_echo != echo)
1831 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1833 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1835 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1837 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);
1845 void PmISDN::set_tone(char *dir, char *tone)
1851 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1858 /* check if we NOT really have to use a dsp-tone */
1859 if (!options.dsptones)
1863 if (p_m_b_index > -1)
1864 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1866 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1868 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1870 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1874 Port::set_tone(dir, tone);
1880 /* now we USE dsp-tone, convert name */
1881 else if (!strcmp(tone, "dialtone"))
1883 switch(options.dsptones) {
1884 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1885 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1886 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1888 } else if (!strcmp(tone, "dialpbx"))
1890 switch(options.dsptones) {
1891 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1892 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1893 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1895 } else if (!strcmp(tone, "ringing"))
1897 switch(options.dsptones) {
1898 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1899 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1900 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1902 } else if (!strcmp(tone, "ringpbx"))
1904 switch(options.dsptones) {
1905 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1906 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1907 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1909 } else if (!strcmp(tone, "busy"))
1912 switch(options.dsptones) {
1913 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1914 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1915 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1917 } else if (!strcmp(tone, "release"))
1920 switch(options.dsptones) {
1921 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1922 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1923 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1925 } else if (!strcmp(tone, "cause_10"))
1927 else if (!strcmp(tone, "cause_11"))
1929 else if (!strcmp(tone, "cause_22"))
1931 switch(options.dsptones) {
1932 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1933 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1934 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1936 } else if (!strncmp(tone, "cause_", 6))
1937 id = TONE_SPECIAL_INFO;
1941 /* if we have a tone that is not supported by dsp */
1942 if (id==TONE_OFF && tone[0])
1950 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1951 if (p_m_b_index > -1)
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_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1956 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);
1959 /* turn user-space tones off in cases of no tone OR dsp tone */
1960 Port::set_tone("",NULL);
1964 /* MESSAGE_mISDNSIGNAL */
1965 //extern struct lcr_msg *dddebug;
1966 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1968 switch(param->mISDNsignal.message)
1970 case mISDNSIGNAL_VOLUME:
1971 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1973 p_m_tx_gain = param->mISDNsignal.tx_gain;
1974 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1975 if (p_m_b_index > -1)
1976 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1978 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1980 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);
1983 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1984 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1986 p_m_rx_gain = param->mISDNsignal.rx_gain;
1987 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1988 if (p_m_b_index > -1)
1989 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1991 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1993 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);
1996 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1999 case mISDNSIGNAL_CONF:
2000 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2001 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
2002 if (p_m_conf != param->mISDNsignal.conf)
2004 p_m_conf = param->mISDNsignal.conf;
2005 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
2006 if (p_m_b_index > -1)
2007 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2009 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (p_m_conf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
2011 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);
2014 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
2015 /* we must set, even if currently tone forbids conf */
2016 p_m_conf = param->mISDNsignal.conf;
2017 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2020 case mISDNSIGNAL_JOINDATA:
2021 if (p_m_joindata != param->mISDNsignal.joindata)
2023 p_m_joindata = param->mISDNsignal.joindata;
2024 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
2026 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
2029 case mISDNSIGNAL_DELAY:
2030 if (p_m_delay != param->mISDNsignal.delay)
2032 p_m_delay = param->mISDNsignal.delay;
2033 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
2035 if (p_m_b_index > -1)
2036 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2038 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
2040 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);
2044 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
2048 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
2053 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
2055 struct lcr_msg *message;
2057 switch(param->crypt.type)
2059 case CC_ACTBF_REQ: /* activate blowfish */
2061 p_m_crypt_key_len = param->crypt.len;
2062 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
2064 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
2065 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
2066 message->param.crypt.type = CC_ERROR_IND;
2067 message_put(message);
2070 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
2072 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
2073 if (p_m_b_index > -1)
2074 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2076 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
2078 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);
2082 case CC_DACT_REQ: /* deactivate session encryption */
2087 case CR_LISTEN_REQ: /* start listening to messages */
2088 p_m_crypt_listen = 1;
2089 p_m_crypt_listen_state = 0;
2092 case CR_UNLISTEN_REQ: /* stop listening to messages */
2093 p_m_crypt_listen = 0;
2096 case CR_MESSAGE_REQ: /* send message */
2097 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2098 if (!p_m_crypt_msg_len)
2100 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2103 p_m_crypt_msg_current = 0; /* reset */
2104 p_m_crypt_msg_loops = 6; /* enable */
2106 /* disable txmix, or we get corrupt data due to audio process */
2107 if (p_m_txmix && p_m_b_index>=0)
2109 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2111 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
2113 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2120 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2126 * endpoint sends messages to the port
2128 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2130 if (Port::message_epoint(epoint_id, message_id, param))
2135 case MESSAGE_DATA: /* tx-data from upper layer */
2136 txfromup(param->data.data, param->data.len);
2139 case MESSAGE_mISDNSIGNAL: /* user command */
2140 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2141 message_mISDNsignal(epoint_id, message_id, param);
2144 case MESSAGE_CRYPT: /* crypt control command */
2145 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2146 message_crypt(epoint_id, message_id, param);
2155 * main loop for processing messages from mISDN
2158 int mISDN_handler(void)
2161 struct mISDNport *mISDNport;
2162 class PmISDN *isdnport;
2164 unsigned char buffer[2048+MISDN_HEADER_LEN];
2165 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2169 /* process all ports */
2170 mISDNport = mISDNport_first;
2173 /* process all bchannels */
2175 while(i < mISDNport->b_num)
2177 /* process timer events for bchannel handling */
2178 if (mISDNport->b_timer[i])
2180 if (mISDNport->b_timer[i] <= now_d)
2181 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2183 /* handle port of bchannel */
2184 isdnport=mISDNport->b_port[i];
2187 /* call bridges in user space OR crypto OR recording */
2188 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2190 /* rx IS required */
2191 if (isdnport->p_m_rxoff)
2194 isdnport->p_m_rxoff = 0;
2195 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2196 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2197 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2202 /* rx NOT required */
2203 if (!isdnport->p_m_rxoff)
2206 isdnport->p_m_rxoff = 1;
2207 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2208 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2209 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2214 if (isdnport->p_record)
2216 /* txdata IS required */
2217 if (!isdnport->p_m_txdata)
2220 isdnport->p_m_txdata = 1;
2221 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2222 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2223 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
2228 /* txdata NOT required */
2229 if (isdnport->p_m_txdata)
2232 isdnport->p_m_txdata = 0;
2233 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2234 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2235 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2241 /* handle message from bchannel */
2242 if (mISDNport->b_socket[i] > -1)
2244 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
2245 if (ret >= (int)MISDN_HEADER_LEN)
2250 /* we don't care about confirms, we use rx data to sync tx */
2254 /* we receive audio data, we respond to it AND we send tones */
2257 case PH_CONTROL_IND:
2258 if (mISDNport->b_port[i])
2259 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2261 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
2264 case PH_ACTIVATE_IND:
2265 case DL_ESTABLISH_IND:
2266 case PH_ACTIVATE_CNF:
2267 case DL_ESTABLISH_CNF:
2268 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2269 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2272 case PH_DEACTIVATE_IND:
2273 case DL_RELEASE_IND:
2274 case PH_DEACTIVATE_CNF:
2275 case DL_RELEASE_CNF:
2276 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2277 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2281 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
2285 if (ret < 0 && errno != EWOULDBLOCK)
2286 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2293 /* handle queued up-messages (d-channel) */
2294 while ((mb = mdequeue(&mISDNport->upqueue)))
2299 #warning SOCKET TBD: Layer 1 indication
2302 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2304 mISDNport->l1link = 1;
2307 case MT_L1DEACTIVATE:
2308 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2310 mISDNport->l1link = 0;
2314 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2315 // special config commands for interface (ip-address/LOS/AIS/RDI/SLIP)
2319 case MT_L2ESTABLISH:
2320 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2322 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2324 if (mISDNport->l2establish)
2326 mISDNport->l2establish = 0;
2327 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2329 mISDNport->l2link = 1;
2334 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2336 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2338 mISDNport->l2link = 0;
2339 if (mISDNport->l2hold)
2341 time(&mISDNport->l2establish);
2342 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2348 /* l3-data is sent to LCR */
2349 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2357 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2359 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2360 mISDNport->l1timeout = 0;
2363 /* layer 2 establish timer */
2364 if (mISDNport->l2establish)
2366 if (now-mISDNport->l2establish > 5)
2368 mISDNport->l2establish = 0;
2369 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2372 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2373 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2374 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2376 time(&mISDNport->l2establish);
2383 mISDNport = mISDNport->next;
2386 /* if we received at least one b-frame, we will return 1 */
2390 int mISDN_handler(void)
2393 struct mISDNport *mISDNport;
2394 class PmISDN *isdnport;
2399 mISDNuser_head_t *hh;
2402 /* the que avoids loopbacks when replying to stack after receiving
2404 mISDNport = mISDNport_first;
2407 /* process turning on/off rx */
2409 while(i < mISDNport->b_num)
2411 /* process timer events for bchannel handling */
2412 if (mISDNport->b_timer[i])
2414 if (mISDNport->b_timer[i] <= now_d)
2415 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2417 isdnport=mISDNport->b_port[i];
2420 /* call bridges in user space OR crypto OR recording */
2421 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2423 /* rx IS required */
2424 if (isdnport->p_m_rxoff)
2427 isdnport->p_m_rxoff = 0;
2428 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2429 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2430 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2435 /* rx NOT required */
2436 if (!isdnport->p_m_rxoff)
2439 isdnport->p_m_rxoff = 1;
2440 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2441 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2442 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2447 if (isdnport->p_record)
2449 /* txdata IS required */
2450 if (!isdnport->p_m_txdata)
2453 isdnport->p_m_txdata = 1;
2454 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2456 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2457 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2463 /* txdata NOT required */
2464 if (isdnport->p_m_txdata)
2467 isdnport->p_m_txdata = 0;
2468 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2470 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2471 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2480 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2482 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2483 mISDNport->l1timeout = 0;
2486 if (mISDNport->l2establish)
2488 if (now-mISDNport->l2establish > 5)
2490 mISDNport->l2establish = 0;
2491 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2493 if (mISDNport->ntmode)
2495 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2496 time(&mISDNport->l2establish);
2498 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2499 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2504 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2505 time(&mISDNport->l2establish);
2507 act.prim = DL_ESTABLISH | REQUEST;
2508 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2511 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2513 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2515 time(&mISDNport->l2establish);
2520 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2522 if (mISDNport->ntmode)
2524 hh = (mISDNuser_head_t *)dmsg->data;
2525 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);
2526 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2530 frm = (iframe_t *)dmsg->data;
2531 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2532 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2533 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);
2534 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2539 mISDNport = mISDNport->next;
2542 /* no device, no read */
2543 if (mISDNdevice < 0)
2546 /* get message from kernel */
2547 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2549 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2553 if (errno == EAGAIN)
2555 FATAL("Failed to do mISDN_read()\n");
2560 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2564 frm = (iframe_t *)msg->data;
2569 case MGR_DELLAYER | CONFIRM:
2570 case MGR_INITTIMER | CONFIRM:
2571 case MGR_ADDTIMER | CONFIRM:
2572 case MGR_DELTIMER | CONFIRM:
2573 case MGR_REMOVETIMER | CONFIRM:
2578 /* handle timer events from mISDN for NT-stack
2579 * note: they do not associate with a stack */
2580 if (frm->prim == (MGR_TIMER | INDICATION))
2584 /* find mISDNport */
2585 mISDNport = mISDNport_first;
2589 if (mISDNport->ntmode)
2591 it = mISDNport->nst.tlist;
2595 if (it->id == (int)frm->addr)
2602 mISDNport = mISDNport->next;
2606 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2607 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2609 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2610 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2611 ret = it->function(it->data);
2614 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2619 /* find the mISDNport that belongs to the stack */
2620 mISDNport = mISDNport_first;
2623 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2625 mISDNport = mISDNport->next;
2629 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2630 // show a list of all mISDNports and their address
2632 mISDNport = mISDNport_first;
2635 PERROR(" port %s %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2636 mISDNport = mISDNport->next;
2643 if (!(frm->addr&FLG_CHILD_STACK))
2648 case MGR_SHORTSTATUS | INDICATION:
2649 case MGR_SHORTSTATUS | CONFIRM:
2650 switch(frm->dinfo) {
2651 case SSTATUS_L1_ACTIVATED:
2652 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2655 case SSTATUS_L1_DEACTIVATED:
2656 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2659 case SSTATUS_L2_ESTABLISHED:
2660 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2663 case SSTATUS_L2_RELEASED:
2664 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2670 case PH_ACTIVATE | CONFIRM:
2671 case PH_ACTIVATE | INDICATION:
2672 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2674 if (mISDNport->ntmode)
2676 mISDNport->l1link = 1;
2677 setup_queue(mISDNport, 1);
2681 mISDNport->l1link = 1;
2682 setup_queue(mISDNport, 1);
2685 case PH_DEACTIVATE | CONFIRM:
2686 case PH_DEACTIVATE | INDICATION:
2687 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2689 if (mISDNport->ntmode)
2691 mISDNport->l1link = 0;
2692 setup_queue(mISDNport, 0);
2696 mISDNport->l1link = 0;
2697 setup_queue(mISDNport, 0);
2700 case PH_CONTROL | CONFIRM:
2701 case PH_CONTROL | INDICATION:
2702 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2705 case DL_ESTABLISH | INDICATION:
2706 case DL_ESTABLISH | CONFIRM:
2707 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2709 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2711 if (!mISDNport->ntmode || mISDNport->ptp)
2713 if (mISDNport->l2establish)
2715 mISDNport->l2establish = 0;
2716 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2718 mISDNport->l2link = 1;
2722 case DL_RELEASE | INDICATION:
2723 case DL_RELEASE | CONFIRM:
2724 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2726 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2728 if (!mISDNport->ntmode || mISDNport->ptp)
2730 mISDNport->l2link = 0;
2731 if (mISDNport->l2hold)
2733 time(&mISDNport->l2establish);
2734 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2741 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);
2742 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2744 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2747 if (mISDNport->ntmode)
2749 /* l1-data enters the nt-mode library */
2750 nst = &mISDNport->nst;
2751 if (nst->l1_l2(nst, msg))
2756 /* l3-data is sent to pbx */
2757 if (stack2manager_te(mISDNport, msg))
2768 /* we don't care about confirms, we use rx data to sync tx */
2769 case PH_DATA | CONFIRM:
2770 case DL_DATA | CONFIRM:
2773 /* we receive audio data, we respond to it AND we send tones */
2774 case PH_DATA | INDICATION:
2775 case DL_DATA | INDICATION:
2776 case PH_CONTROL | INDICATION:
2777 case PH_SIGNAL | INDICATION:
2779 while(i < mISDNport->b_num)
2781 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2785 if (i == mISDNport->b_num)
2787 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2790 if (mISDNport->b_port[i])
2792 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2793 mISDNport->b_port[i]->bchannel_receive(frm);
2795 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2798 case PH_ACTIVATE | INDICATION:
2799 case DL_ESTABLISH | INDICATION:
2800 case PH_ACTIVATE | CONFIRM:
2801 case DL_ESTABLISH | CONFIRM:
2802 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2804 while(i < mISDNport->b_num)
2806 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2810 if (i == mISDNport->b_num)
2812 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2815 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2818 case PH_DEACTIVATE | INDICATION:
2819 case DL_RELEASE | INDICATION:
2820 case PH_DEACTIVATE | CONFIRM:
2821 case DL_RELEASE | CONFIRM:
2822 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2824 while(i < mISDNport->b_num)
2826 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2830 if (i == mISDNport->b_num)
2832 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2835 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2839 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2850 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2854 * l3m must be queued, except for MT_ASSIGN
2857 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2860 /* special MT_ASSIGN handling:
2862 * if we request a PID from mlayer, we always do it while lcr is locked.
2863 * therefore we must check the MT_ASSIGN reply first before we lock.
2864 * this is because the MT_ASSIGN reply is received with the requesting
2865 * process, not by the mlayer thread!
2866 * this means, that the reply is sent during call of the request.
2867 * we must check if we get a reply and we know that we lcr is currently
2870 if (cmd == MT_ASSIGN)
2872 /* let's do some checking if someone changes stack behaviour */
2873 if (mt_assign_pid != 0)
2874 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2875 if ((pid >> 16) != MISDN_CES_MASTER)
2876 FATAL("someone played with the mISDNuser stack. MT_ASSIGN is expected with master CES.\n");
2877 mt_assign_pid = pid;
2881 /* queue message, create, if required */
2884 l3m = alloc_l3_msg();
2886 FATAL("No memory for layer 3 message\n");
2888 mb = container_of(l3m, struct mbuffer, l3);
2891 mqueue_tail(&mISDNport->upqueue, mb);
2899 * global function to add a new card (port)
2901 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2904 struct mISDNport *mISDNport, **mISDNportp;
2909 // struct mlayer3 *ml3;
2910 struct mISDN_devinfo devinfo;
2911 unsigned int protocol, prop;
2913 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2916 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2920 unsigned char buff[1025];
2921 iframe_t *frm = (iframe_t *)buff;
2922 // interface_info_t ii;
2926 stack_info_t *stinf;
2928 /* query port's requirements */
2929 cnt = mISDN_get_stack_count(mISDNdevice);
2934 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2937 if (port>cnt || port<1)
2939 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2943 pri = bri = pots = nt = te = 0;
2945 devinfo.id = port - 1;
2946 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2949 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2952 /* output the port info */
2953 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2958 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2963 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2968 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2974 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2981 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2987 if (force_nt && !nt)
2989 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2994 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2997 if (pots && !bri && !pri)
2999 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
3004 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
3009 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
3012 /* set NT by turning off TE */
3015 /* if TE an NT is supported (and not forced to NT), turn off NT */
3019 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
3022 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
3025 stinf = (stack_info_t *)&frm->data.p;
3026 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3028 case ISDN_PID_L0_TE_S0:
3029 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
3031 case ISDN_PID_L0_NT_S0:
3032 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
3035 case ISDN_PID_L0_TE_E1:
3036 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
3039 case ISDN_PID_L0_NT_E1:
3040 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
3045 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
3051 if (stinf->pid.protocol[1] == 0)
3053 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
3056 if (stinf->pid.protocol[2])
3058 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
3065 if (stinf->pid.protocol[1] == 0)
3067 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
3070 if (stinf->pid.protocol[2] == 0)
3072 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
3075 if (stinf->pid.protocol[3] == 0)
3077 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
3081 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3083 case ISDN_PID_L3_DSS1USER:
3087 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
3091 if (stinf->pid.protocol[4])
3093 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3099 /* add mISDNport structure */
3100 mISDNportp = &mISDNport_first;
3102 mISDNportp = &((*mISDNportp)->next);
3103 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3105 *mISDNportp = mISDNport;
3107 /* if pri, set PTP */
3128 /* allocate ressources of port */
3131 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NET;
3133 if (ptp) // ptp forced
3134 prop |= (1 << MISDN_FLG_PTP);
3135 if (nt) // supports hold/retrieve on nt-mode
3136 prop |= (1 << MISDN_FLG_NET_HOLD);
3137 if (l2hold) // supports layer 2 hold
3138 prop |= (1 << MISDN_FLG_L2_HOLD);
3139 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
3140 if (!mISDNport->ml3)
3142 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3147 /* if ntmode, establish L1 to send the tei removal during start */
3148 if (mISDNport->ntmode)
3152 act.prim = PH_ACTIVATE | REQUEST;
3153 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3154 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3157 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3158 usleep(10000); /* to be sure, that l1 is up */
3162 SCPY(mISDNport->name, devinfo.name);
3163 mISDNport->b_num = devinfo.nrbchan;
3165 msg_queue_init(&mISDNport->downqueue);
3166 mISDNport->d_stid = stinf->id;
3167 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3169 /* create layer intance */
3170 memset(&li, 0, sizeof(li));
3171 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3174 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3175 li.pid.layermask = ISDN_LAYER((nt?2:4));
3176 li.st = mISDNport->d_stid;
3177 ret = mISDN_new_layer(mISDNdevice, &li);
3180 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3182 mISDNport_close(mISDNport);
3185 mISDNport->upper_id = li.id;
3186 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3189 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3192 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3193 if (mISDNport->lower_id < 0)
3195 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3198 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3199 if (mISDNport->upper_id < 0)
3201 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3204 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3206 /* if ntmode, establish L1 to send the tei removal during start */
3207 if (mISDNport->ntmode)
3211 act.prim = PH_ACTIVATE | REQUEST;
3212 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3213 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3216 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3217 usleep(10000); /* to be sure, that l1 is up */
3220 /* create nst (nt-mode only) */
3223 mgr = &mISDNport->mgr;
3224 nst = &mISDNport->nst;
3229 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3230 nst->device = mISDNdevice;
3232 nst->d_stid = mISDNport->d_stid;
3234 nst->feature = FEATURE_NET_HOLD;
3236 nst->feature |= FEATURE_NET_PTP;
3238 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3241 while(i < mISDNport->b_num)
3243 nst->b_stid[i] = mISDNport->b_stid[i];
3247 nst->l1_id = mISDNport->lower_id;
3248 nst->l2_id = mISDNport->upper_id;
3251 msg_queue_init(&nst->down_queue);
3257 mISDNport->b_num = stinf->childcnt;
3259 mISDNport->portnum = port;
3260 mISDNport->ntmode = nt;
3261 mISDNport->pri = pri;
3262 mISDNport->ptp = ptp;
3263 mISDNport->l2hold = l2hold;
3264 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3266 while(i < mISDNport->b_num)
3268 mISDNport->b_state[i] = B_STATE_IDLE;
3270 mISDNport->b_socket[i] = -1;
3272 mISDNport->b_stid[i] = stinf->child[i];
3273 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3279 /* if ptp, pull up the link */
3280 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
3282 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
3283 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3285 time(&mISDNport->l2establish);
3288 /* if te-mode, query state link */
3289 if (!mISDNport->ntmode)
3293 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3294 act.prim = MGR_SHORTSTATUS | REQUEST;
3295 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3296 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3298 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3300 /* if ptp AND te-mode, pull up the link */
3301 if (mISDNport->l2hold && !mISDNport->ntmode)
3305 act.prim = DL_ESTABLISH | REQUEST;
3306 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3309 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3311 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3313 time(&mISDNport->l2establish);
3315 /* if ptp AND nt-mode, pull up the link */
3316 if (mISDNport->l2hold && mISDNport->ntmode && mISDNport->ptp)
3320 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3321 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3323 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3325 time(&mISDNport->l2establish);
3330 /* init stack queue */
3331 mqueue_init(&mISDNport->upqueue);
3334 /* initially, we assume that the link is down, exept for nt-ptmp */
3335 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3337 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3339 start_trace(mISDNport->portnum,
3347 add_trace("channels", NULL, "%d", mISDNport->b_num);
3354 * function to free ALL cards (ports)
3356 void mISDNport_close_all(void)
3358 /* free all ports */
3359 while(mISDNport_first)
3360 mISDNport_close(mISDNport_first);
3364 * free only one port
3366 void mISDNport_close(struct mISDNport *mISDNport)
3368 struct mISDNport **mISDNportp;
3370 class PmISDN *isdnport;
3374 unsigned char buf[32];
3378 /* remove all port instance that are linked to this mISDNport */
3382 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3384 isdnport = (class PmISDN *)port;
3385 if (isdnport->p_m_mISDNport)
3387 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3394 /* only if we are already part of interface */
3395 if (mISDNport->ifport)
3397 start_trace(mISDNport->portnum,
3398 mISDNport->ifport->interface,
3408 /* free bchannels */
3410 while(i < mISDNport->b_num)
3413 if (mISDNport->b_socket[i] > -1)
3415 if (mISDNport->b_addr[i])
3418 _bchannel_destroy(mISDNport, i);
3419 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3425 close_layer3(mISDNport->ml3);
3426 mqueue_purge(&mISDNport->upqueue);
3428 /* free ressources of port */
3429 msg_queue_purge(&mISDNport->downqueue);
3432 if (mISDNport->ntmode)
3434 nst = &mISDNport->nst;
3435 if (nst->manager) /* to see if initialized */
3437 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");
3438 cleanup_Isdnl3(nst);
3439 cleanup_Isdnl2(nst);
3442 msg_queue_purge(&nst->down_queue);
3443 if (nst->phd_down_msg)
3444 FREE(nst->phd_down_msg, 0);
3448 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3449 if (mISDNport->d_stid)
3451 if (mISDNport->upper_id)
3452 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3456 /* remove from list */
3457 mISDNportp = &mISDNport_first;
3460 if (*mISDNportp == mISDNport)
3462 *mISDNportp = (*mISDNportp)->next;
3466 mISDNportp = &((*mISDNportp)->next);
3470 FATAL("mISDNport not in list\n");
3472 FREE(mISDNport, sizeof(struct mISDNport));
3479 * global function to show all available isdn ports
3481 void mISDN_port_info(void)
3485 int useable, nt, te, pri, bri, pots;
3487 struct mISDN_devinfo devinfo;
3491 sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3494 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3498 /* get number of stacks */
3500 ret = ioctl(sock, IMGETCOUNT, &ii);
3503 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3508 unsigned char buff[1025];
3509 iframe_t *frm = (iframe_t *)buff;
3510 stack_info_t *stinf;
3514 if ((device = mISDN_open()) < 0)
3516 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));
3520 /* get number of stacks */
3522 ii = mISDN_get_stack_count(device);
3527 printf("Found no card. Please be sure to load card drivers.\n");
3531 /* loop the number of cards and get their info */
3534 nt = te = bri = pri = pots = 0;
3539 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
3542 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3546 /* output the port info */
3547 printf("Port %2d name='%s': ", i, devinfo.name);
3548 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3553 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3558 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3563 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3569 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3576 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3582 if ((te || nt) && (bri || pri || pots))
3586 printf("TE-mode BRI S/T interface line (for phone lines)");
3588 printf("NT-mode BRI S/T interface port (for phones)");
3590 printf("TE-mode PRI E1 interface line (for phone lines)");
3592 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3594 printf("FXS POTS interface port (for analog lines)");
3596 printf("FXO POTS interface port (for analog phones)");
3600 printf("\n -> Analog interfaces are not supported.");
3604 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3608 printf(" - %d B-channels\n", devinfo.nrbchan);
3610 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3613 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3616 stinf = (stack_info_t *)&frm->data.p;
3618 /* output the port info */
3619 printf("Port %2d: ", i);
3620 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3622 case ISDN_PID_L0_TE_S0:
3626 printf("TE-mode BRI S/T interface line (for phone lines)");
3628 case ISDN_PID_L0_NT_S0:
3632 printf("NT-mode BRI S/T interface port (for phones)");
3634 case ISDN_PID_L0_TE_E1:
3638 printf("TE-mode PRI E1 interface line (for phone lines)");
3640 case ISDN_PID_L0_NT_E1:
3644 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3648 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3654 if (stinf->pid.protocol[1] == 0)
3657 printf(" -> Missing layer 1 NT-mode protocol.\n");
3660 while(p <= MAX_LAYER_NR) {
3661 if (stinf->pid.protocol[p])
3664 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3671 printf(" -> Interface is Point-To-Point (PRI).\n");
3673 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3678 if (stinf->pid.protocol[1] == 0)
3681 printf(" -> Missing layer 1 protocol.\n");
3683 if (stinf->pid.protocol[2] == 0)
3686 printf(" -> Missing layer 2 protocol.\n");
3688 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3690 printf(" -> Interface is Poin-To-Point.\n");
3692 if (stinf->pid.protocol[3] == 0)
3695 printf(" -> Missing layer 3 protocol.\n");
3698 printf(" -> Protocol: ");
3699 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3701 case ISDN_PID_L3_DSS1USER:
3702 printf("DSS1 (Euro ISDN)");
3707 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3712 while(p <= MAX_LAYER_NR) {
3713 if (stinf->pid.protocol[p])
3716 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3721 printf(" - %d B-channels\n", stinf->childcnt);
3725 printf(" * Port NOT useable for LCR\n");
3727 printf("--------\n");
3738 if ((ret = mISDN_close(device)))
3739 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3745 * enque data from upper buffer
3747 void PmISDN::txfromup(unsigned char *data, int length)
3750 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3751 struct mISDNhead *hh = (struct mISDNhead *)buf;
3754 if (p_m_b_index < 0)
3756 if (!p_m_mISDNport->b_socket[p_m_b_index])
3759 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3760 iframe_t *frm = (iframe_t *)buf;
3762 if (p_m_b_index < 0)
3764 if (!p_m_mISDNport->b_addr[p_m_b_index])
3768 /* check if high priority tones exist
3769 * ignore data in this case
3771 if (p_tone_name[0] || p_m_crypt_msg_loops)
3774 /* preload procedure
3775 * if transmit buffer in DSP module is empty,
3776 * preload it to DSP_LOAD to prevent jitter gaps.
3778 if (p_m_load==0 && ISDN_LOAD>0)
3781 hh->prim = DL_DATA_REQ;
3783 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3784 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
3786 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3788 frm->prim = DL_DATA | REQUEST;
3789 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3791 frm->len = ISDN_LOAD;
3792 memset(buf+mISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3793 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+ISDN_LOAD, TIMEOUT_1SEC);
3795 p_m_load += ISDN_LOAD;
3798 /* drop if load would exceed ISDN_MAXLOAD
3799 * this keeps the delay not too high
3801 if (p_m_load+length > ISDN_MAXLOAD)
3804 /* make and send frame */
3806 hh->prim = DL_DATA_REQ;
3808 memcpy(buf+MISDN_HEADER_LEN, data, length);
3809 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3811 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3813 frm->prim = DL_DATA | REQUEST;
3814 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3817 memcpy(buf+mISDN_HEADER_LEN, data, length);
3818 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);