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 #warning testing without bchannel
537 #warning testing without DSP
538 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW/*ISDN_P_B_L2DSP*/);
539 if (mISDNport->b_socket[i] < 0)
541 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
545 /* set nonblocking io */
546 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
549 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
550 close(mISDNport->b_socket[i]);
551 mISDNport->b_socket[i] = -1;
555 /* bind socket to bchannel */
556 addr.family = AF_ISDN;
557 addr.dev = mISDNport->portnum-1;
558 addr.channel = i+1+(i>=15);
559 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
562 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
563 close(mISDNport->b_socket[i]);
564 mISDNport->b_socket[i] = -1;
568 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
569 add_trace("channel", NULL, "%d", i+1+(i>=15));
570 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
575 unsigned char buff[1024];
579 if (!mISDNport->b_stid[i])
581 PERROR("Error: no stack for index %d\n", i);
584 if (mISDNport->b_addr[i])
586 PERROR("Error: stack already created for index %d\n", i);
590 /* create new layer */
591 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
592 memset(&li, 0, sizeof(li));
593 memset(&pid, 0, sizeof(pid));
596 li.st = mISDNport->b_stid[i];
597 UCPY(li.name, "B L4");
598 li.pid.layermask = ISDN_LAYER((4));
599 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
600 ret = mISDN_new_layer(mISDNdevice, &li);
604 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
607 mISDNport->b_addr[i] = li.id;
610 goto failed_new_layer;
612 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
614 /* create new stack */
615 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
616 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
617 pid.protocol[3] = ISDN_PID_L3_B_DSP;
618 pid.protocol[4] = ISDN_PID_L4_B_USER;
619 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
620 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
624 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
625 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
628 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
633 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
634 if (!mISDNport->b_addr[i])
636 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
637 add_trace("channel", NULL, "%d", i+1+(i>=15));
638 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
639 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
645 mISDNport->b_addr[i] = 0;
652 * subfunction for bchannel_event
653 * activate / deactivate request
655 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
658 struct mISDNhead act;
661 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
663 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
665 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
669 /* activate bchannel */
670 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
671 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
674 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
678 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
679 add_trace("channel", NULL, "%d", i+1+(i>=15));
680 if (mISDNport->b_timer[i])
681 add_trace("event", NULL, "timeout recovery");
687 * subfunction for bchannel_event
690 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
696 handle = mISDNport->b_socket[i];
697 port = mISDNport->b_port[i];
700 PERROR("bchannel index i=%d not associated with a port object\n", i);
704 /* set dsp features */
705 if (port->p_m_txdata)
706 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
708 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
709 if (port->p_m_tx_gain)
710 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
711 if (port->p_m_rx_gain)
712 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
713 if (port->p_m_pipeline[0])
714 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
716 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
718 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
720 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
722 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
723 // if (port->p_m_txmix)
724 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
726 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
728 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);
730 unsigned long handle;
732 handle = mISDNport->b_addr[i];
733 port = mISDNport->b_port[i];
736 PERROR("bchannel index i=%d not associated with a port object\n", i);
740 /* set dsp features */
742 if (port->p_m_txdata)
743 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
745 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
747 if (port->p_m_tx_gain)
748 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
749 if (port->p_m_rx_gain)
750 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
752 if (port->p_m_pipeline[0])
753 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
756 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
758 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
760 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
762 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
763 // if (port->p_m_txmix)
764 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
766 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
768 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);
773 * subfunction for bchannel_event
776 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
779 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
780 add_trace("channel", NULL, "%d", i+1+(i>=15));
781 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
783 if (mISDNport->b_socket[i] > -1)
785 close(mISDNport->b_socket[i]);
786 mISDNport->b_socket[i] = -1;
789 unsigned char buff[1024];
791 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
792 add_trace("channel", NULL, "%d", i+1+(i>=15));
793 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
794 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
796 /* remove our stack only if set */
797 if (mISDNport->b_addr[i])
799 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
800 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
801 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
802 mISDNport->b_addr[i] = 0;
812 A bchannel goes through the following states in this order:
815 No one is using the bchannel.
816 It is available and not linked to Port class, nor reserved.
819 The bchannel stack is created and an activation request is sent.
820 It MAY be linked to Port class, but already unlinked due to Port class removal.
823 The bchannel is active and cofigured to the Port class needs.
824 Also it is linked to a Port class, otherwhise it would be deactivated.
826 - B_STATE_DEACTIVATING
827 The bchannel is in deactivating state, due to deactivation request.
828 It may be linked to a Port class, that likes to reactivate it.
832 After deactivating bchannel, and if not used, the bchannel becomes idle again.
834 Also the bchannel may be exported, but only if the state is or becomes idle:
837 The bchannel assignment has been sent to the remove application.
840 The bchannel assignment is acknowledged by the remote application.
843 The bchannel is re-imported by mISDN port object.
847 After re-importing bchannel, and if not used, the bchannel becomes idle again.
850 A bchannel can have the following events:
853 A bchannel is required by a Port class.
854 The bchannel shall be exported to the remote application.
857 The bchannel beomes active.
860 The bchannel is not required by Port class anymore
862 - B_EVENT_DEACTIVATED
863 The bchannel becomes inactive.
866 The bchannel is now used by remote application.
869 The bchannel is not used by remote application.
871 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
873 if an export request is receive by remote application, p_m_remote_* is set.
874 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.)
875 - set on export request from remote application (if port is assigned)
876 - set on channel use, if requested by remote application (p_m_remote_*)
877 - cleared on drop request
879 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
880 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
881 the bchannel import/export is acknowledged with stack given.
883 if exporting, b_remote_*[index] is set to the remote socket id.
884 if importing has been acknowledged. b_remote_*[index] is cleared.
889 * process bchannel events
890 * - mISDNport is a pointer to the port's structure
891 * - i is the index of the bchannel
892 * - event is the B_EVENT_* value
893 * - port is the PmISDN class pointer
895 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
897 class PmISDN *b_port = mISDNport->b_port[i];
898 int state = mISDNport->b_state[i];
899 double timer = mISDNport->b_timer[i];
900 unsigned long p_m_remote_ref = 0;
901 unsigned long p_m_remote_id = 0;
904 char *p_m_pipeline = NULL;
905 unsigned char *p_m_crypt_key = NULL;
906 int p_m_crypt_key_len = 0;
907 int p_m_crypt_key_type = 0;
909 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
911 unsigned long portid = mISDNport->b_stid[i];
916 p_m_remote_id = b_port->p_m_remote_id;
917 p_m_remote_ref = b_port->p_m_remote_ref;
918 p_m_tx_gain = b_port->p_m_tx_gain;
919 p_m_rx_gain = b_port->p_m_rx_gain;
920 p_m_pipeline = b_port->p_m_pipeline;
921 p_m_crypt_key = b_port->p_m_crypt_key;
922 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
923 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
929 /* port must be linked in order to allow activation */
931 FATAL("bchannel must be linked to a Port class\n");
937 /* export bchannel */
938 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);
939 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
940 add_trace("type", NULL, "assign");
942 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
944 add_trace("socket", "id", "%d", portid);
947 state = B_STATE_EXPORTING;
948 mISDNport->b_remote_id[i] = p_m_remote_id;
949 mISDNport->b_remote_ref[i] = p_m_remote_ref;
952 /* create stack and send activation request */
953 if (_bchannel_create(mISDNport, i))
955 _bchannel_activate(mISDNport, i, 1);
956 state = B_STATE_ACTIVATING;
957 timer = now_d + B_TIMER_ACTIVATING;
962 case B_STATE_ACTIVATING:
963 case B_STATE_EXPORTING:
964 /* do nothing, because it is already activating */
967 case B_STATE_DEACTIVATING:
968 case B_STATE_IMPORTING:
969 /* do nothing, because we must wait until we can reactivate */
973 /* problems that might ocurr:
974 * B_EVENT_USE is received when channel already in use.
975 * bchannel exported, but not freed by other port
977 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
981 case B_EVENT_EXPORTREQUEST:
982 /* special case where the bchannel is requested by remote */
985 PERROR("export request without remote channel set, please correct.\n");
991 /* in case, the bchannel is exported right after seize_bchannel */
992 /* export bchannel */
993 /* p_m_remote_id is set, when this event happens. */
994 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);
995 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
996 add_trace("type", NULL, "assign");
998 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1000 add_trace("socket", "id", "%d", portid);
1003 state = B_STATE_EXPORTING;
1004 mISDNport->b_remote_id[i] = p_m_remote_id;
1005 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1008 case B_STATE_ACTIVATING:
1009 case B_STATE_EXPORTING:
1010 /* do nothing, because it is already activating */
1013 case B_STATE_DEACTIVATING:
1014 case B_STATE_IMPORTING:
1015 /* do nothing, because we must wait until we can reactivate */
1018 case B_STATE_ACTIVE:
1019 /* bchannel is active, so we deactivate */
1020 _bchannel_activate(mISDNport, i, 0);
1021 state = B_STATE_DEACTIVATING;
1022 timer = now_d + B_TIMER_DEACTIVATING;
1026 /* problems that might ocurr:
1027 * ... when channel already in use.
1028 * bchannel exported, but not freed by other port
1030 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1034 case B_EVENT_ACTIVATED:
1038 case B_STATE_ACTIVATING:
1039 if (b_port && !p_m_remote_id)
1041 /* bchannel is active and used by Port class, so we configure bchannel */
1042 _bchannel_configure(mISDNport, i);
1043 state = B_STATE_ACTIVE;
1046 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
1047 _bchannel_activate(mISDNport, i, 0);
1048 state = B_STATE_DEACTIVATING;
1049 timer = now_d + B_TIMER_DEACTIVATING;
1054 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1058 case B_EVENT_EXPORTED:
1061 case B_STATE_EXPORTING:
1062 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
1064 /* remote export done */
1065 state = B_STATE_REMOTE;
1068 /* bchannel is now exported, but we need bchannel back
1069 * OR bchannel is not used anymore
1070 * OR bchannel has been exported to an obsolete ref,
1071 * so reimport, to later export to new remote */
1072 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1073 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1074 add_trace("type", NULL, "remove");
1076 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1078 add_trace("socket", "id", "%d", portid);
1081 state = B_STATE_IMPORTING;
1086 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1092 FATAL("bchannel must be linked to a Port class\n");
1096 /* bchannel is idle due to an error, so we do nothing */
1099 case B_STATE_ACTIVATING:
1100 case B_STATE_EXPORTING:
1101 /* do nothing because we must wait until bchanenl is active before deactivating */
1104 case B_STATE_ACTIVE:
1105 /* bchannel is active, so we deactivate */
1106 _bchannel_activate(mISDNport, i, 0);
1107 state = B_STATE_DEACTIVATING;
1108 timer = now_d + B_TIMER_DEACTIVATING;
1111 case B_STATE_REMOTE:
1112 /* bchannel is exported, so we re-import */
1113 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1114 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1115 add_trace("type", NULL, "remove");
1117 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1119 add_trace("socket", "id", "%d", portid);
1122 state = B_STATE_IMPORTING;
1125 case B_STATE_DEACTIVATING:
1126 case B_STATE_IMPORTING:
1127 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1131 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1135 case B_EVENT_DEACTIVATED:
1140 /* ignore due to deactivation confirm after unloading */
1143 case B_STATE_DEACTIVATING:
1144 _bchannel_destroy(mISDNport, i);
1145 state = B_STATE_IDLE;
1148 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1151 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);
1152 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1153 add_trace("type", NULL, "assign");
1155 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1157 add_trace("socket", "id", "%d", portid);
1160 state = B_STATE_EXPORTING;
1161 mISDNport->b_remote_id[i] = p_m_remote_id;
1162 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1165 if (_bchannel_create(mISDNport, i))
1167 _bchannel_activate(mISDNport, i, 1);
1168 state = B_STATE_ACTIVATING;
1169 timer = now_d + B_TIMER_ACTIVATING;
1176 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1180 case B_EVENT_IMPORTED:
1183 case B_STATE_IMPORTING:
1184 state = B_STATE_IDLE;
1185 mISDNport->b_remote_id[i] = 0;
1186 mISDNport->b_remote_ref[i] = 0;
1189 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1192 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);
1193 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1194 add_trace("type", NULL, "assign");
1196 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1198 add_trace("socket", "id", "%d", portid);
1201 state = B_STATE_EXPORTING;
1202 mISDNport->b_remote_id[i] = p_m_remote_id;
1203 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1206 if (_bchannel_create(mISDNport, i))
1208 _bchannel_activate(mISDNport, i, 1);
1209 state = B_STATE_ACTIVATING;
1210 timer = now_d + B_TIMER_ACTIVATING;
1217 /* ignore, because not assigned */
1222 case B_EVENT_TIMEOUT:
1227 /* ignore due to deactivation confirm after unloading */
1230 case B_STATE_ACTIVATING:
1231 _bchannel_activate(mISDNport, i, 1);
1232 timer = now_d + B_TIMER_ACTIVATING;
1235 case B_STATE_DEACTIVATING:
1236 _bchannel_activate(mISDNport, i, 0);
1237 timer = now_d + B_TIMER_DEACTIVATING;
1241 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1246 PERROR("Illegal event %d, please correct.\n", event);
1249 mISDNport->b_state[i] = state;
1250 mISDNport->b_timer[i] = timer;
1257 * check for available channel and reserve+set it.
1258 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1259 * give exclusiv flag
1260 * returns -(cause value) or x = channel x or 0 = no channel
1261 * NOTE: no activation is done here
1263 int PmISDN::seize_bchannel(int channel, int exclusive)
1267 /* the channel is what we have */
1268 if (p_m_b_channel == channel)
1271 /* if channel already in use, release it */
1276 if (channel==CHANNEL_NO || channel==0)
1279 /* is channel in range ? */
1281 || (channel>p_m_mISDNport->b_num && channel<16)
1282 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1283 return(-6); /* channel unacceptable */
1285 /* request exclusive channel */
1286 if (exclusive && channel>0)
1288 i = channel-1-(channel>16);
1289 if (p_m_mISDNport->b_port[i])
1290 return(-44); /* requested channel not available */
1294 /* ask for channel */
1297 i = channel-1-(channel>16);
1298 if (p_m_mISDNport->b_port[i] == NULL)
1302 /* search for channel */
1304 while(i < p_m_mISDNport->b_num)
1306 if (!p_m_mISDNport->b_port[i])
1308 channel = i+1+(i>=15);
1313 return(-34); /* no free channel */
1316 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1319 p_m_mISDNport->b_port[i] = this;
1321 p_m_b_channel = channel;
1322 p_m_b_exclusive = exclusive;
1324 /* reserve channel */
1328 p_m_mISDNport->b_reserved++;
1335 * drop reserved channel and unset it.
1336 * deactivation is also done
1338 void PmISDN::drop_bchannel(void)
1340 /* unreserve channel */
1342 p_m_mISDNport->b_reserved--;
1346 if (p_m_b_index < 0)
1351 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1353 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1354 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1355 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1358 p_m_b_exclusive = 0;
1361 /* process bchannel export/import message from join */
1362 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1364 class Endpoint *epoint;
1366 class PmISDN *isdnport;
1367 struct mISDNport *mISDNport;
1372 case BCHANNEL_REQUEST:
1373 /* find the port object for the join object ref */
1374 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1376 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1379 if (!epoint->ep_portlist)
1381 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1384 if (epoint->ep_portlist->next)
1386 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);
1388 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1390 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1393 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1395 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1397 isdnport = (class PmISDN *)port;
1400 if (isdnport->p_m_remote_id)
1402 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1405 mISDNport = isdnport->p_m_mISDNport;
1406 i = isdnport->p_m_b_index;
1407 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1408 add_trace("type", NULL, "export request");
1409 isdnport->p_m_remote_ref = joinremote->j_serial;
1410 isdnport->p_m_remote_id = joinremote->j_remote_id;
1411 if (mISDNport && i>=0)
1413 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1418 case BCHANNEL_ASSIGN_ACK:
1419 case BCHANNEL_REMOVE_ACK:
1420 /* find mISDNport for stack ID */
1421 mISDNport = mISDNport_first;
1425 ii = mISDNport->b_num;
1429 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1431 if (mISDNport->b_addr[i] == handle)
1438 mISDNport = mISDNport->next;
1442 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1445 /* mISDNport may now be set or NULL */
1448 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1449 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1450 if (mISDNport && i>=0)
1451 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1455 PERROR("received wrong bchannel message type %d from remote\n", type);
1463 audio transmission procedure:
1464 -----------------------------
1467 three sources of audio transmission:
1468 - crypto-data high priority
1469 - tones high priority (also high)
1470 - remote-data low priority
1473 a variable that temporarily shows the number of samples elapsed since last transmission process.
1474 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1477 a variable that is increased whenever data is transmitted.
1478 it is decreased while time elapses. it stores the number of samples that
1479 are currently loaded to dsp module.
1480 since clock in dsp module is the same clock for user space process, these
1484 there are two levels:
1485 ISDN_LOAD will give the load that have to be kept in dsp.
1486 ISDN_MAXLOAD will give the maximum load before dropping.
1488 * procedure for low priority data
1489 see txfromup() for procedure
1490 in short: remote data is ignored during high priority tones
1492 * procedure for high priority data
1493 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1494 if no more data is available, load becomes empty again.
1497 0 ISDN_LOAD ISDN_MAXLOAD
1498 +--------------------+----------------------+
1500 +--------------------+----------------------+
1502 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1503 0 ISDN_LOAD ISDN_MAXLOAD
1504 +--------------------+----------------------+
1505 |TTTTTTTTTTTTTTTTTTTT| |
1506 +--------------------+----------------------+
1508 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1509 0 ISDN_LOAD ISDN_MAXLOAD
1510 +--------------------+----------------------+
1511 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1512 +--------------------+----------------------+
1515 int PmISDN::handler(void)
1517 struct lcr_msg *message;
1521 if ((ret = Port::handler()))
1525 if (p_m_last_tv_sec)
1527 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1528 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1531 /* set clock of first process ever in this instance */
1532 p_m_last_tv_sec = now_tv.tv_sec;
1533 p_m_last_tv_msec = now_tv.tv_usec/1000;
1535 /* process only if we have a minimum of samples, to make packets not too small */
1536 if (elapsed >= ISDN_TRANSMIT)
1538 /* set clock of last process! */
1539 p_m_last_tv_sec = now_tv.tv_sec;
1540 p_m_last_tv_msec = now_tv.tv_usec/1000;
1543 if (elapsed < p_m_load)
1544 p_m_load -= elapsed;
1548 /* to send data, tone must be active OR crypt messages must be on */
1549 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1550 && (p_m_load < ISDN_LOAD)
1551 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1553 int tosend = ISDN_LOAD - p_m_load, length;
1555 unsigned char buf[MISDN_HEADER_LEN+tosend];
1556 struct mISDNhead *frm = (struct mISDNhead *)buf;
1557 unsigned char *p = buf+MISDN_HEADER_LEN;
1559 unsigned char buf[mISDN_HEADER_LEN+tosend];
1560 iframe_t *frm = (iframe_t *)buf;
1561 unsigned char *p = buf+mISDN_HEADER_LEN;
1564 /* copy crypto loops */
1565 while (p_m_crypt_msg_loops && tosend)
1567 /* how much do we have to send */
1568 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1571 if (length > tosend)
1574 /* copy message (part) to buffer */
1575 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1578 p_m_crypt_msg_current += length;
1579 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1582 p_m_crypt_msg_current = 0;
1583 p_m_crypt_msg_loops--;
1584 // puts("eine loop weniger");
1592 if (p_tone_name[0] && tosend)
1594 tosend -= read_audio(p, tosend);
1599 frm->prim = DL_DATA_REQ;
1601 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1603 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
1605 frm->prim = DL_DATA | REQUEST;
1606 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1608 frm->len = ISDN_LOAD - p_m_load - tosend;
1610 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1612 p_m_load += ISDN_LOAD - p_m_load - tosend;
1616 // NOTE: deletion is done by the child class
1618 /* handle timeouts */
1621 if (p_m_timer+p_m_timeout < now_d)
1623 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1625 /* send timeout to endpoint */
1626 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1627 message->param.state = p_state;
1628 message_put(message);
1633 return(0); /* nothing done */
1638 * whenever we get audio data from bchannel, we process it here
1641 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1643 unsigned long cont = *((unsigned long *)data);
1645 void PmISDN::bchannel_receive(iframe_t *frm)
1648 unsigned long cont = *((unsigned long *)&frm->data.p);
1649 unsigned char *data =(unsigned char *)&frm->data.p;
1651 unsigned char *data_temp;
1652 unsigned long length_temp;
1653 struct lcr_msg *message;
1658 if (hh->prim == PH_CONTROL_IND)
1660 if (frm->prim == (PH_CONTROL | INDICATION))
1665 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1668 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1670 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1671 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1673 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1674 message->param.dtmf = cont & DTMF_TONE_MASK;
1675 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1676 message_put(message);
1686 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1687 add_trace("DSP-CRYPT", NULL, "error");
1689 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1690 message->param.crypt.type = CC_ERROR_IND;
1691 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1692 message_put(message);
1700 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1701 add_trace("DSP-CRYPT", NULL, "ok");
1703 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1704 message->param.crypt.type = CC_ACTBF_CONF;
1705 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1706 message_put(message);
1710 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1711 add_trace("unknown", NULL, "0x%x", cont);
1717 if (hh->prim == PH_CONTROL_IND)
1721 if (frm->prim == (PH_SIGNAL | INDICATION)
1722 || frm->prim == (PH_CONTROL | INDICATION))
1735 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1736 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1739 /* see below (same condition) */
1740 if (p_state!=PORT_STATE_CONNECT
1741 && !p_m_mISDNport->tones)
1743 // printf(".");fflush(stdout);return;
1745 record(data, len, 1); // from up
1750 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1752 add_trace("unknown", NULL, "0x%x", hh->id);
1754 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1761 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1763 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1765 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1767 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1771 /* calls will not process any audio data unless
1772 * the call is connected OR interface features audio during call setup.
1774 //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);
1775 #ifndef DEBUG_COREBRIDGE
1776 if (p_state!=PORT_STATE_CONNECT
1777 && !p_m_mISDNport->tones)
1781 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1784 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1790 record(data, len, 0); // from down
1792 /* randomize and listen to crypt message if enabled */
1793 if (p_m_crypt_listen)
1795 /* the noisy randomizer */
1799 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1801 cryptman_listen_bch(data, len);
1806 /* send data to epoint */
1807 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1813 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1814 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1815 memcpy(message->param.data.data, data_temp, message->param.data.len);
1816 message_put(message);
1817 if (length_temp <= sizeof(message->param.data.data))
1819 data_temp += sizeof(message->param.data.data);
1820 length_temp -= sizeof(message->param.data.data);
1829 void PmISDN::set_echotest(int echo)
1831 if (p_m_echo != echo)
1834 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1836 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1838 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);
1840 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);
1848 void PmISDN::set_tone(char *dir, char *tone)
1854 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1861 /* check if we NOT really have to use a dsp-tone */
1862 if (!options.dsptones)
1866 if (p_m_b_index > -1)
1867 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1869 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1871 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1873 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1877 Port::set_tone(dir, tone);
1883 /* now we USE dsp-tone, convert name */
1884 else if (!strcmp(tone, "dialtone"))
1886 switch(options.dsptones) {
1887 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1888 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1889 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1891 } else if (!strcmp(tone, "dialpbx"))
1893 switch(options.dsptones) {
1894 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1895 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1896 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1898 } else if (!strcmp(tone, "ringing"))
1900 switch(options.dsptones) {
1901 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1902 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1903 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1905 } else if (!strcmp(tone, "ringpbx"))
1907 switch(options.dsptones) {
1908 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1909 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1910 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1912 } else if (!strcmp(tone, "busy"))
1915 switch(options.dsptones) {
1916 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1917 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1918 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1920 } else if (!strcmp(tone, "release"))
1923 switch(options.dsptones) {
1924 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1925 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1926 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1928 } else if (!strcmp(tone, "cause_10"))
1930 else if (!strcmp(tone, "cause_11"))
1932 else if (!strcmp(tone, "cause_22"))
1934 switch(options.dsptones) {
1935 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1936 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1937 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1939 } else if (!strncmp(tone, "cause_", 6))
1940 id = TONE_SPECIAL_INFO;
1944 /* if we have a tone that is not supported by dsp */
1945 if (id==TONE_OFF && tone[0])
1953 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1954 if (p_m_b_index > -1)
1955 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1957 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);
1959 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);
1962 /* turn user-space tones off in cases of no tone OR dsp tone */
1963 Port::set_tone("",NULL);
1967 /* MESSAGE_mISDNSIGNAL */
1968 //extern struct lcr_msg *dddebug;
1969 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1971 switch(param->mISDNsignal.message)
1973 case mISDNSIGNAL_VOLUME:
1974 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1976 p_m_tx_gain = param->mISDNsignal.tx_gain;
1977 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1978 if (p_m_b_index > -1)
1979 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1981 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);
1983 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);
1986 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1987 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1989 p_m_rx_gain = param->mISDNsignal.rx_gain;
1990 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1991 if (p_m_b_index > -1)
1992 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1994 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);
1996 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);
1999 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
2002 case mISDNSIGNAL_CONF:
2003 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2004 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
2005 if (p_m_conf != param->mISDNsignal.conf)
2007 p_m_conf = param->mISDNsignal.conf;
2008 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
2009 if (p_m_b_index > -1)
2010 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2012 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);
2014 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);
2017 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
2018 /* we must set, even if currently tone forbids conf */
2019 p_m_conf = param->mISDNsignal.conf;
2020 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2023 case mISDNSIGNAL_JOINDATA:
2024 if (p_m_joindata != param->mISDNsignal.joindata)
2026 p_m_joindata = param->mISDNsignal.joindata;
2027 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
2029 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
2032 case mISDNSIGNAL_DELAY:
2033 if (p_m_delay != param->mISDNsignal.delay)
2035 p_m_delay = param->mISDNsignal.delay;
2036 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
2038 if (p_m_b_index > -1)
2039 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2041 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);
2043 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);
2047 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
2051 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
2056 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
2058 struct lcr_msg *message;
2060 switch(param->crypt.type)
2062 case CC_ACTBF_REQ: /* activate blowfish */
2064 p_m_crypt_key_len = param->crypt.len;
2065 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
2067 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
2068 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
2069 message->param.crypt.type = CC_ERROR_IND;
2070 message_put(message);
2073 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
2075 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
2076 if (p_m_b_index > -1)
2077 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2079 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);
2081 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);
2085 case CC_DACT_REQ: /* deactivate session encryption */
2090 case CR_LISTEN_REQ: /* start listening to messages */
2091 p_m_crypt_listen = 1;
2092 p_m_crypt_listen_state = 0;
2095 case CR_UNLISTEN_REQ: /* stop listening to messages */
2096 p_m_crypt_listen = 0;
2099 case CR_MESSAGE_REQ: /* send message */
2100 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2101 if (!p_m_crypt_msg_len)
2103 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2106 p_m_crypt_msg_current = 0; /* reset */
2107 p_m_crypt_msg_loops = 6; /* enable */
2109 /* disable txmix, or we get corrupt data due to audio process */
2110 if (p_m_txmix && p_m_b_index>=0)
2112 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2114 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
2116 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2123 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2129 * endpoint sends messages to the port
2131 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2133 if (Port::message_epoint(epoint_id, message_id, param))
2138 case MESSAGE_DATA: /* tx-data from upper layer */
2139 txfromup(param->data.data, param->data.len);
2142 case MESSAGE_mISDNSIGNAL: /* user command */
2143 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2144 message_mISDNsignal(epoint_id, message_id, param);
2147 case MESSAGE_CRYPT: /* crypt control command */
2148 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2149 message_crypt(epoint_id, message_id, param);
2158 * main loop for processing messages from mISDN
2161 int mISDN_handler(void)
2164 struct mISDNport *mISDNport;
2165 class PmISDN *isdnport;
2167 unsigned char buffer[2048+MISDN_HEADER_LEN];
2168 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2172 /* process all ports */
2173 mISDNport = mISDNport_first;
2176 /* process all bchannels */
2178 while(i < mISDNport->b_num)
2180 /* process timer events for bchannel handling */
2181 if (mISDNport->b_timer[i])
2183 if (mISDNport->b_timer[i] <= now_d)
2184 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2186 /* handle port of bchannel */
2187 isdnport=mISDNport->b_port[i];
2190 /* call bridges in user space OR crypto OR recording */
2191 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2193 /* rx IS required */
2194 if (isdnport->p_m_rxoff)
2197 isdnport->p_m_rxoff = 0;
2198 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2199 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2200 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2205 /* rx NOT required */
2206 if (!isdnport->p_m_rxoff)
2209 isdnport->p_m_rxoff = 1;
2210 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2211 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2212 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2217 if (isdnport->p_record)
2219 /* txdata IS required */
2220 if (!isdnport->p_m_txdata)
2223 isdnport->p_m_txdata = 1;
2224 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2225 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2226 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
2231 /* txdata NOT required */
2232 if (isdnport->p_m_txdata)
2235 isdnport->p_m_txdata = 0;
2236 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2237 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2238 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2244 /* handle message from bchannel */
2245 if (mISDNport->b_socket[i] > -1)
2247 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
2248 if (ret >= (int)MISDN_HEADER_LEN)
2253 /* we don't care about confirms, we use rx data to sync tx */
2257 /* we receive audio data, we respond to it AND we send tones */
2260 case PH_CONTROL_IND:
2261 if (mISDNport->b_port[i])
2262 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2264 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
2267 case PH_ACTIVATE_IND:
2268 case DL_ESTABLISH_IND:
2269 case PH_ACTIVATE_CNF:
2270 case DL_ESTABLISH_CNF:
2271 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2272 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2275 case PH_DEACTIVATE_IND:
2276 case DL_RELEASE_IND:
2277 case PH_DEACTIVATE_CNF:
2278 case DL_RELEASE_CNF:
2279 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2280 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2284 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
2288 if (ret < 0 && errno != EWOULDBLOCK)
2289 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2296 /* handle queued up-messages (d-channel) */
2297 while ((mb = mdequeue(&mISDNport->upqueue)))
2302 case MPH_ACTIVATE_IND:
2303 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2305 mISDNport->l1link = 1;
2308 case MPH_DEACTIVATE_IND:
2309 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2311 mISDNport->l1link = 0;
2314 case MPH_INFORMATION_IND:
2315 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2318 case L1_SIGNAL_LOS_ON:
2321 case L1_SIGNAL_LOS_OFF:
2324 case L1_SIGNAL_AIS_ON:
2327 case L1_SIGNAL_AIS_OFF:
2330 case L1_SIGNAL_RDI_ON:
2333 case L1_SIGNAL_RDI_OFF:
2336 case L1_SIGNAL_SLIP_TX:
2337 mISDNport->slip_tx++;
2339 case L1_SIGNAL_SLIP_RX:
2340 mISDNport->slip_rx++;
2345 case MT_L2ESTABLISH:
2346 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2348 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2350 if (mISDNport->l2establish)
2352 mISDNport->l2establish = 0;
2353 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2355 mISDNport->l2link = 1;
2360 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2362 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2364 mISDNport->l2link = 0;
2365 if (mISDNport->l2hold)
2367 time(&mISDNport->l2establish);
2368 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2374 /* l3-data is sent to LCR */
2375 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2383 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2385 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2386 mISDNport->l1timeout = 0;
2389 /* layer 2 establish timer */
2390 if (mISDNport->l2establish)
2392 if (now-mISDNport->l2establish > 5)
2394 mISDNport->l2establish = 0;
2395 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2398 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2399 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2400 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2402 time(&mISDNport->l2establish);
2409 mISDNport = mISDNport->next;
2412 /* if we received at least one b-frame, we will return 1 */
2416 int mISDN_handler(void)
2419 struct mISDNport *mISDNport;
2420 class PmISDN *isdnport;
2425 mISDNuser_head_t *hh;
2428 /* the que avoids loopbacks when replying to stack after receiving
2430 mISDNport = mISDNport_first;
2433 /* process turning on/off rx */
2435 while(i < mISDNport->b_num)
2437 /* process timer events for bchannel handling */
2438 if (mISDNport->b_timer[i])
2440 if (mISDNport->b_timer[i] <= now_d)
2441 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2443 isdnport=mISDNport->b_port[i];
2446 /* call bridges in user space OR crypto OR recording */
2447 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2449 /* rx IS required */
2450 if (isdnport->p_m_rxoff)
2453 isdnport->p_m_rxoff = 0;
2454 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2455 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2456 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2461 /* rx NOT required */
2462 if (!isdnport->p_m_rxoff)
2465 isdnport->p_m_rxoff = 1;
2466 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2467 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2468 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2473 if (isdnport->p_record)
2475 /* txdata IS required */
2476 if (!isdnport->p_m_txdata)
2479 isdnport->p_m_txdata = 1;
2480 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2482 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2483 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2489 /* txdata NOT required */
2490 if (isdnport->p_m_txdata)
2493 isdnport->p_m_txdata = 0;
2494 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2496 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2497 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2506 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2508 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2509 mISDNport->l1timeout = 0;
2512 if (mISDNport->l2establish)
2514 if (now-mISDNport->l2establish > 5)
2516 mISDNport->l2establish = 0;
2517 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2519 if (mISDNport->ntmode)
2521 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2522 time(&mISDNport->l2establish);
2524 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2525 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2530 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2531 time(&mISDNport->l2establish);
2533 act.prim = DL_ESTABLISH | REQUEST;
2534 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2537 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2539 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2541 time(&mISDNport->l2establish);
2546 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2548 if (mISDNport->ntmode)
2550 hh = (mISDNuser_head_t *)dmsg->data;
2551 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);
2552 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2556 frm = (iframe_t *)dmsg->data;
2557 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2558 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2559 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);
2560 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2565 mISDNport = mISDNport->next;
2568 /* no device, no read */
2569 if (mISDNdevice < 0)
2572 /* get message from kernel */
2573 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2575 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2579 if (errno == EAGAIN)
2581 FATAL("Failed to do mISDN_read()\n");
2586 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2590 frm = (iframe_t *)msg->data;
2595 case MGR_DELLAYER | CONFIRM:
2596 case MGR_INITTIMER | CONFIRM:
2597 case MGR_ADDTIMER | CONFIRM:
2598 case MGR_DELTIMER | CONFIRM:
2599 case MGR_REMOVETIMER | CONFIRM:
2604 /* handle timer events from mISDN for NT-stack
2605 * note: they do not associate with a stack */
2606 if (frm->prim == (MGR_TIMER | INDICATION))
2610 /* find mISDNport */
2611 mISDNport = mISDNport_first;
2615 if (mISDNport->ntmode)
2617 it = mISDNport->nst.tlist;
2621 if (it->id == (int)frm->addr)
2628 mISDNport = mISDNport->next;
2632 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2633 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2635 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2636 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2637 ret = it->function(it->data);
2640 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2645 /* find the mISDNport that belongs to the stack */
2646 mISDNport = mISDNport_first;
2649 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2651 mISDNport = mISDNport->next;
2655 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2656 // show a list of all mISDNports and their address
2658 mISDNport = mISDNport_first;
2661 PERROR(" port %s %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2662 mISDNport = mISDNport->next;
2669 if (!(frm->addr&FLG_CHILD_STACK))
2674 case MGR_SHORTSTATUS | INDICATION:
2675 case MGR_SHORTSTATUS | CONFIRM:
2676 switch(frm->dinfo) {
2677 case SSTATUS_L1_ACTIVATED:
2678 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2681 case SSTATUS_L1_DEACTIVATED:
2682 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2685 case SSTATUS_L2_ESTABLISHED:
2686 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2689 case SSTATUS_L2_RELEASED:
2690 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2696 case PH_ACTIVATE | CONFIRM:
2697 case PH_ACTIVATE | INDICATION:
2698 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2700 if (mISDNport->ntmode)
2702 mISDNport->l1link = 1;
2703 setup_queue(mISDNport, 1);
2707 mISDNport->l1link = 1;
2708 setup_queue(mISDNport, 1);
2711 case PH_DEACTIVATE | CONFIRM:
2712 case PH_DEACTIVATE | INDICATION:
2713 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2715 if (mISDNport->ntmode)
2717 mISDNport->l1link = 0;
2718 setup_queue(mISDNport, 0);
2722 mISDNport->l1link = 0;
2723 setup_queue(mISDNport, 0);
2726 case PH_CONTROL | CONFIRM:
2727 case PH_CONTROL | INDICATION:
2728 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2731 case DL_ESTABLISH | INDICATION:
2732 case DL_ESTABLISH | CONFIRM:
2733 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2735 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2737 if (!mISDNport->ntmode || mISDNport->ptp)
2739 if (mISDNport->l2establish)
2741 mISDNport->l2establish = 0;
2742 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2744 mISDNport->l2link = 1;
2748 case DL_RELEASE | INDICATION:
2749 case DL_RELEASE | CONFIRM:
2750 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2752 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2754 if (!mISDNport->ntmode || mISDNport->ptp)
2756 mISDNport->l2link = 0;
2757 if (mISDNport->l2hold)
2759 time(&mISDNport->l2establish);
2760 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2767 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);
2768 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2770 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2773 if (mISDNport->ntmode)
2775 /* l1-data enters the nt-mode library */
2776 nst = &mISDNport->nst;
2777 if (nst->l1_l2(nst, msg))
2782 /* l3-data is sent to pbx */
2783 if (stack2manager_te(mISDNport, msg))
2794 /* we don't care about confirms, we use rx data to sync tx */
2795 case PH_DATA | CONFIRM:
2796 case DL_DATA | CONFIRM:
2799 /* we receive audio data, we respond to it AND we send tones */
2800 case PH_DATA | INDICATION:
2801 case DL_DATA | INDICATION:
2802 case PH_CONTROL | INDICATION:
2803 case PH_SIGNAL | INDICATION:
2805 while(i < mISDNport->b_num)
2807 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2811 if (i == mISDNport->b_num)
2813 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2816 if (mISDNport->b_port[i])
2818 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2819 mISDNport->b_port[i]->bchannel_receive(frm);
2821 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2824 case PH_ACTIVATE | INDICATION:
2825 case DL_ESTABLISH | INDICATION:
2826 case PH_ACTIVATE | CONFIRM:
2827 case DL_ESTABLISH | CONFIRM:
2828 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2830 while(i < mISDNport->b_num)
2832 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2836 if (i == mISDNport->b_num)
2838 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2841 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2844 case PH_DEACTIVATE | INDICATION:
2845 case DL_RELEASE | INDICATION:
2846 case PH_DEACTIVATE | CONFIRM:
2847 case DL_RELEASE | CONFIRM:
2848 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2850 while(i < mISDNport->b_num)
2852 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2856 if (i == mISDNport->b_num)
2858 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2861 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2865 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2876 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2880 * l3m must be queued, except for MT_ASSIGN
2883 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2886 /* special MT_ASSIGN handling:
2888 * if we request a PID from mlayer, we always do it while lcr is locked.
2889 * therefore we must check the MT_ASSIGN reply first before we lock.
2890 * this is because the MT_ASSIGN reply is received with the requesting
2891 * process, not by the mlayer thread!
2892 * this means, that the reply is sent during call of the request.
2893 * we must check if we get a reply and we know that we lcr is currently
2896 if (cmd == MT_ASSIGN)
2898 /* let's do some checking if someone changes stack behaviour */
2899 if (mt_assign_pid != 0)
2900 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2901 if ((pid >> 16) != MISDN_CES_MASTER)
2902 FATAL("someone played with the mISDNuser stack. MT_ASSIGN is expected with master CES.\n");
2903 mt_assign_pid = pid;
2907 /* queue message, create, if required */
2910 l3m = alloc_l3_msg();
2912 FATAL("No memory for layer 3 message\n");
2914 mb = container_of(l3m, struct mbuffer, l3);
2917 mqueue_tail(&mISDNport->upqueue, mb);
2925 * global function to add a new card (port)
2927 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2930 struct mISDNport *mISDNport, **mISDNportp;
2935 // struct mlayer3 *ml3;
2936 struct mISDN_devinfo devinfo;
2937 unsigned int protocol, prop;
2939 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2942 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2946 unsigned char buff[1025];
2947 iframe_t *frm = (iframe_t *)buff;
2948 // interface_info_t ii;
2952 stack_info_t *stinf;
2954 /* query port's requirements */
2955 cnt = mISDN_get_stack_count(mISDNdevice);
2960 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2963 if (port>cnt || port<1)
2965 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2969 pri = bri = pots = nt = te = 0;
2971 devinfo.id = port - 1;
2972 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2975 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2978 /* output the port info */
2979 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2984 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2989 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2994 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3000 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3007 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3013 if (force_nt && !nt)
3015 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
3020 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
3023 if (pots && !bri && !pri)
3025 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
3030 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
3035 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
3038 /* set NT by turning off TE */
3041 /* if TE an NT is supported (and not forced to NT), turn off NT */
3045 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
3048 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
3051 stinf = (stack_info_t *)&frm->data.p;
3052 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3054 case ISDN_PID_L0_TE_S0:
3055 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
3057 case ISDN_PID_L0_NT_S0:
3058 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
3061 case ISDN_PID_L0_TE_E1:
3062 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
3065 case ISDN_PID_L0_NT_E1:
3066 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
3071 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
3077 if (stinf->pid.protocol[1] == 0)
3079 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
3082 if (stinf->pid.protocol[2])
3084 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
3091 if (stinf->pid.protocol[1] == 0)
3093 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
3096 if (stinf->pid.protocol[2] == 0)
3098 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
3101 if (stinf->pid.protocol[3] == 0)
3103 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
3107 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3109 case ISDN_PID_L3_DSS1USER:
3113 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
3117 if (stinf->pid.protocol[4])
3119 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3125 /* add mISDNport structure */
3126 mISDNportp = &mISDNport_first;
3128 mISDNportp = &((*mISDNportp)->next);
3129 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3131 *mISDNportp = mISDNport;
3133 /* if pri, set PTP */
3154 /* allocate ressources of port */
3156 /* open layer 3 and init upqueue */
3157 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NET;
3159 if (ptp) // ptp forced
3160 prop |= (1 << MISDN_FLG_PTP);
3161 if (nt) // supports hold/retrieve on nt-mode
3162 prop |= (1 << MISDN_FLG_NET_HOLD);
3163 if (l2hold) // supports layer 2 hold
3164 prop |= (1 << MISDN_FLG_L2_HOLD);
3165 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
3166 if (!mISDNport->ml3)
3168 PERROR_RUNTIME("oper_layer3() failed for port %d\n", port);
3169 mISDNport_close(mISDNport);
3172 mqueue_init(&mISDNport->upqueue);
3175 /* if ntmode, establish L1 to send the tei removal during start */
3176 if (mISDNport->ntmode)
3180 act.prim = PH_ACTIVATE | REQUEST;
3181 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3182 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3185 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3186 usleep(10000); /* to be sure, that l1 is up */
3190 SCPY(mISDNport->name, devinfo.name);
3191 mISDNport->b_num = devinfo.nrbchan;
3193 msg_queue_init(&mISDNport->downqueue);
3194 mISDNport->d_stid = stinf->id;
3195 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3197 /* create layer intance */
3198 memset(&li, 0, sizeof(li));
3199 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3202 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3203 li.pid.layermask = ISDN_LAYER((nt?2:4));
3204 li.st = mISDNport->d_stid;
3205 ret = mISDN_new_layer(mISDNdevice, &li);
3208 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3210 mISDNport_close(mISDNport);
3213 mISDNport->upper_id = li.id;
3214 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3217 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3220 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3221 if (mISDNport->lower_id < 0)
3223 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3226 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3227 if (mISDNport->upper_id < 0)
3229 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3232 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3234 /* if ntmode, establish L1 to send the tei removal during start */
3235 if (mISDNport->ntmode)
3239 act.prim = PH_ACTIVATE | REQUEST;
3240 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3241 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3244 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3245 usleep(10000); /* to be sure, that l1 is up */
3248 /* create nst (nt-mode only) */
3251 mgr = &mISDNport->mgr;
3252 nst = &mISDNport->nst;
3257 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3258 nst->device = mISDNdevice;
3260 nst->d_stid = mISDNport->d_stid;
3262 nst->feature = FEATURE_NET_HOLD;
3264 nst->feature |= FEATURE_NET_PTP;
3266 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3269 while(i < mISDNport->b_num)
3271 nst->b_stid[i] = mISDNport->b_stid[i];
3275 nst->l1_id = mISDNport->lower_id;
3276 nst->l2_id = mISDNport->upper_id;
3279 msg_queue_init(&nst->down_queue);
3285 mISDNport->b_num = stinf->childcnt;
3287 mISDNport->portnum = port;
3288 mISDNport->ntmode = nt;
3289 mISDNport->pri = pri;
3290 mISDNport->ptp = ptp;
3291 mISDNport->l2hold = l2hold;
3292 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3294 while(i < mISDNport->b_num)
3296 mISDNport->b_state[i] = B_STATE_IDLE;
3298 mISDNport->b_socket[i] = -1;
3300 mISDNport->b_stid[i] = stinf->child[i];
3301 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3307 /* if ptp, pull up the link */
3308 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
3310 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
3311 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3313 time(&mISDNport->l2establish);
3316 /* if te-mode, query state link */
3317 if (!mISDNport->ntmode)
3321 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3322 act.prim = MGR_SHORTSTATUS | REQUEST;
3323 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3324 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3326 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3328 /* if ptp AND te-mode, pull up the link */
3329 if (mISDNport->l2hold && !mISDNport->ntmode)
3333 act.prim = DL_ESTABLISH | REQUEST;
3334 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3337 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3339 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3341 time(&mISDNport->l2establish);
3343 /* if ptp AND nt-mode, pull up the link */
3344 if (mISDNport->l2hold && mISDNport->ntmode && mISDNport->ptp)
3348 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3349 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3351 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3353 time(&mISDNport->l2establish);
3357 /* initially, we assume that the link is down, exept for nt-ptmp */
3358 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3360 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3362 start_trace(mISDNport->portnum,
3370 add_trace("channels", NULL, "%d", mISDNport->b_num);
3377 * function to free ALL cards (ports)
3379 void mISDNport_close_all(void)
3381 /* free all ports */
3382 while(mISDNport_first)
3383 mISDNport_close(mISDNport_first);
3387 * free only one port
3389 void mISDNport_close(struct mISDNport *mISDNport)
3391 struct mISDNport **mISDNportp;
3393 class PmISDN *isdnport;
3397 unsigned char buf[32];
3401 /* remove all port instance that are linked to this mISDNport */
3405 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3407 isdnport = (class PmISDN *)port;
3408 if (isdnport->p_m_mISDNport)
3410 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3417 /* only if we are already part of interface */
3418 if (mISDNport->ifport)
3420 start_trace(mISDNport->portnum,
3421 mISDNport->ifport->interface,
3431 /* free bchannels */
3433 while(i < mISDNport->b_num)
3436 if (mISDNport->b_socket[i] > -1)
3438 if (mISDNport->b_addr[i])
3441 _bchannel_destroy(mISDNport, i);
3442 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3448 /* close layer 3, if open and purge upqueue */
3451 close_layer3(mISDNport->ml3);
3452 mqueue_purge(&mISDNport->upqueue);
3455 /* free ressources of port */
3456 msg_queue_purge(&mISDNport->downqueue);
3459 if (mISDNport->ntmode)
3461 nst = &mISDNport->nst;
3462 if (nst->manager) /* to see if initialized */
3464 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");
3465 cleanup_Isdnl3(nst);
3466 cleanup_Isdnl2(nst);
3469 msg_queue_purge(&nst->down_queue);
3470 if (nst->phd_down_msg)
3471 FREE(nst->phd_down_msg, 0);
3475 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3476 if (mISDNport->d_stid)
3478 if (mISDNport->upper_id)
3479 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3483 /* remove from list */
3484 mISDNportp = &mISDNport_first;
3487 if (*mISDNportp == mISDNport)
3489 *mISDNportp = (*mISDNportp)->next;
3493 mISDNportp = &((*mISDNportp)->next);
3497 FATAL("mISDNport not in list\n");
3499 FREE(mISDNport, sizeof(struct mISDNport));
3506 * global function to show all available isdn ports
3508 void mISDN_port_info(void)
3512 int useable, nt, te, pri, bri, pots;
3514 struct mISDN_devinfo devinfo;
3518 sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3521 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3525 /* get number of stacks */
3527 ret = ioctl(sock, IMGETCOUNT, &ii);
3530 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3535 unsigned char buff[1025];
3536 iframe_t *frm = (iframe_t *)buff;
3537 stack_info_t *stinf;
3541 if ((device = mISDN_open()) < 0)
3543 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));
3547 /* get number of stacks */
3549 ii = mISDN_get_stack_count(device);
3554 printf("Found no card. Please be sure to load card drivers.\n");
3558 /* loop the number of cards and get their info */
3561 nt = te = bri = pri = pots = 0;
3566 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
3569 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3573 /* output the port info */
3574 printf("Port %2d name='%s': ", i, devinfo.name);
3575 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3580 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3585 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3590 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3596 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3603 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3609 if ((te || nt) && (bri || pri || pots))
3612 if (te && nt && bri)
3613 printf("TE/NT-mode BRI S/T (for phone lines & phones)");
3614 if (te && !nt && bri)
3615 printf("TE-mode BRI S/T (for phone lines)");
3616 if (nt && !te && bri)
3617 printf("NT-mode BRI S/T (for phones)");
3618 if (te && nt && pri)
3619 printf("TE/NT-mode PRI E1 (for phone lines & E1 devices)");
3620 if (te && !nt && pri)
3621 printf("TE-mode PRI E1 (for phone lines)");
3622 if (nt && !te && pri)
3623 printf("NT-mode PRI E1 (for E1 devices)");
3624 if (te && nt && pots)
3625 printf("FXS/FXO POTS (for analog lines & phones)");
3626 if (te && !nt && pots)
3627 printf("FXS POTS (for analog lines)");
3628 if (nt && !te && pots)
3629 printf("FXO POTS (for analog phones)");
3633 printf("\n -> Analog interfaces are not supported.");
3637 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3641 printf(" - %d B-channels\n", devinfo.nrbchan);
3643 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3646 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3649 stinf = (stack_info_t *)&frm->data.p;
3651 /* output the port info */
3652 printf("Port %2d: ", i);
3653 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3655 case ISDN_PID_L0_TE_S0:
3659 printf("TE-mode BRI S/T interface line (for phone lines)");
3661 case ISDN_PID_L0_NT_S0:
3665 printf("NT-mode BRI S/T interface port (for phones)");
3667 case ISDN_PID_L0_TE_E1:
3671 printf("TE-mode PRI E1 interface line (for phone lines)");
3673 case ISDN_PID_L0_NT_E1:
3677 printf("NT-mode PRI E1 interface port (for E1 devices)");
3681 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3687 if (stinf->pid.protocol[1] == 0)
3690 printf(" -> Missing layer 1 NT-mode protocol.\n");
3693 while(p <= MAX_LAYER_NR) {
3694 if (stinf->pid.protocol[p])
3697 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3704 printf(" -> Interface is Point-To-Point (PRI).\n");
3706 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3711 if (stinf->pid.protocol[1] == 0)
3714 printf(" -> Missing layer 1 protocol.\n");
3716 if (stinf->pid.protocol[2] == 0)
3719 printf(" -> Missing layer 2 protocol.\n");
3721 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3723 printf(" -> Interface is Poin-To-Point.\n");
3725 if (stinf->pid.protocol[3] == 0)
3728 printf(" -> Missing layer 3 protocol.\n");
3731 printf(" -> Protocol: ");
3732 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3734 case ISDN_PID_L3_DSS1USER:
3735 printf("DSS1 (Euro ISDN)");
3740 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3745 while(p <= MAX_LAYER_NR) {
3746 if (stinf->pid.protocol[p])
3749 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3754 printf(" - %d B-channels\n", stinf->childcnt);
3758 printf(" * Port NOT useable for LCR\n");
3760 printf("--------\n");
3771 if ((ret = mISDN_close(device)))
3772 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3778 * enque data from upper buffer
3780 void PmISDN::txfromup(unsigned char *data, int length)
3783 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3784 struct mISDNhead *hh = (struct mISDNhead *)buf;
3787 if (p_m_b_index < 0)
3789 if (!p_m_mISDNport->b_socket[p_m_b_index])
3792 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3793 iframe_t *frm = (iframe_t *)buf;
3795 if (p_m_b_index < 0)
3797 if (!p_m_mISDNport->b_addr[p_m_b_index])
3801 /* check if high priority tones exist
3802 * ignore data in this case
3804 if (p_tone_name[0] || p_m_crypt_msg_loops)
3807 /* preload procedure
3808 * if transmit buffer in DSP module is empty,
3809 * preload it to DSP_LOAD to prevent jitter gaps.
3811 if (p_m_load==0 && ISDN_LOAD>0)
3814 hh->prim = DL_DATA_REQ;
3816 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3817 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
3819 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3821 frm->prim = DL_DATA | REQUEST;
3822 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3824 frm->len = ISDN_LOAD;
3825 memset(buf+mISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3826 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+ISDN_LOAD, TIMEOUT_1SEC);
3828 p_m_load += ISDN_LOAD;
3831 /* drop if load would exceed ISDN_MAXLOAD
3832 * this keeps the delay not too high
3834 if (p_m_load+length > ISDN_MAXLOAD)
3837 /* make and send frame */
3839 hh->prim = DL_DATA_REQ;
3841 memcpy(buf+MISDN_HEADER_LEN, data, length);
3842 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3844 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3846 frm->prim = DL_DATA | REQUEST;
3847 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3850 memcpy(buf+mISDN_HEADER_LEN, data, length);
3851 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);