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));
108 init_layer3(4); // buffer of 4
110 /* open debug, if enabled and not only stack debugging */
113 SPRINT(filename, "%s/debug.log", INSTALL_DATA);
114 debug_fp = fopen(filename, "a");
117 if (options.deb & DEBUG_STACK)
119 SPRINT(filename, "%s/debug_mISDN.log", INSTALL_DATA);
120 mISDN_debug_init(0xffffffff, filename, filename, filename);
122 mISDN_debug_init(0, NULL, NULL, NULL);
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?mISDNport->ifport->interface:NULL):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)
444 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long sock, 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);
454 ctrl->prim = PH_CONTROL_REQ;
458 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
460 PERROR("Failed to send to socket %d\n", sock);
462 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long addr, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
464 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
465 iframe_t *ctrl = (iframe_t *)buffer;
466 unsigned long *d = (unsigned long *)&ctrl->data.p;
471 ctrl->prim = PH_CONTROL | REQUEST;
472 ctrl->addr = addr | FLG_MSG_DOWN;
474 ctrl->len = sizeof(int)*2;
477 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
479 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
481 if (c1 == DSP_CONF_JOIN)
483 if (c1 == CMX_CONF_JOIN)
485 add_trace(trace_name, NULL, "0x%08x", trace_value);
487 add_trace(trace_name, NULL, "%d", trace_value);
492 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
494 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
495 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
496 unsigned long *d = (unsigned long *)(buffer+MISDN_HEADER_LEN);
502 ctrl->prim = PH_CONTROL_REQ;
505 memcpy(d, c2, c2_len);
506 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
508 PERROR("Failed to send to socket %d\n", sock);
510 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long addr, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
512 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
513 iframe_t *ctrl = (iframe_t *)buffer;
514 unsigned long *d = (unsigned long *)&ctrl->data.p;
519 ctrl->prim = PH_CONTROL | REQUEST;
520 ctrl->addr = addr | FLG_MSG_DOWN;
522 ctrl->len = sizeof(int)+c2_len;
524 memcpy(d, c2, c2_len);
525 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
527 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
528 add_trace(trace_name, NULL, "%d", trace_value);
534 * subfunction for bchannel_event
537 static int _bchannel_create(struct mISDNport *mISDNport, int i)
541 unsigned long on = 1;
542 struct sockaddr_mISDN addr;
544 if (mISDNport->b_socket[i] > -1)
546 PERROR("Error: Socket already created for index %d\n", i);
551 //#warning testing without DSP
552 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_RAW);
553 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
554 if (mISDNport->b_socket[i] < 0)
556 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
560 /* set nonblocking io */
561 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
564 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
565 close(mISDNport->b_socket[i]);
566 mISDNport->b_socket[i] = -1;
570 /* bind socket to bchannel */
571 addr.family = AF_ISDN;
572 addr.dev = mISDNport->portnum-1;
573 addr.channel = i+1+(i>=15);
574 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
577 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
578 close(mISDNport->b_socket[i]);
579 mISDNport->b_socket[i] = -1;
583 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
584 add_trace("channel", NULL, "%d", i+1+(i>=15));
585 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
590 unsigned char buff[1024];
594 if (!mISDNport->b_stid[i])
596 PERROR("Error: no stack for index %d\n", i);
599 if (mISDNport->b_addr[i])
601 PERROR("Error: stack already created for index %d\n", i);
605 /* create new layer */
606 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
607 memset(&li, 0, sizeof(li));
608 memset(&pid, 0, sizeof(pid));
611 li.st = mISDNport->b_stid[i];
612 UCPY(li.name, "B L4");
613 li.pid.layermask = ISDN_LAYER((4));
614 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
615 ret = mISDN_new_layer(mISDNdevice, &li);
619 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
622 mISDNport->b_addr[i] = li.id;
625 goto failed_new_layer;
627 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
629 /* create new stack */
630 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
631 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
632 pid.protocol[3] = ISDN_PID_L3_B_DSP;
633 pid.protocol[4] = ISDN_PID_L4_B_USER;
634 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
635 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
639 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
640 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
643 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
648 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
649 if (!mISDNport->b_addr[i])
651 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
652 add_trace("channel", NULL, "%d", i+1+(i>=15));
653 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
654 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
660 mISDNport->b_addr[i] = 0;
667 * subfunction for bchannel_event
668 * activate / deactivate request
670 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
673 struct mISDNhead act;
676 if (mISDNport->b_socket[i] < 0)
678 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
680 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
682 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
686 /* activate bchannel */
687 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
688 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
691 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
695 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
696 add_trace("channel", NULL, "%d", i+1+(i>=15));
697 if (mISDNport->b_timer[i])
698 add_trace("event", NULL, "timeout recovery");
704 * subfunction for bchannel_event
707 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
713 if (mISDNport->b_socket[i] < 0)
715 handle = mISDNport->b_socket[i];
716 port = mISDNport->b_port[i];
719 PERROR("bchannel index i=%d not associated with a port object\n", i);
723 /* set dsp features */
724 if (port->p_m_txdata)
725 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
727 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
728 if (port->p_m_tx_gain)
729 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
730 if (port->p_m_rx_gain)
731 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
732 if (port->p_m_pipeline[0])
733 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
735 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
737 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
739 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
741 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
742 // if (port->p_m_txmix)
743 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
745 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
747 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);
749 unsigned long handle;
751 handle = mISDNport->b_addr[i];
752 port = mISDNport->b_port[i];
755 PERROR("bchannel index i=%d not associated with a port object\n", i);
759 /* set dsp features */
761 if (port->p_m_txdata)
762 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
764 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
766 if (port->p_m_tx_gain)
767 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
768 if (port->p_m_rx_gain)
769 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
771 if (port->p_m_pipeline[0])
772 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
775 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
777 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
779 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
781 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
782 // if (port->p_m_txmix)
783 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
785 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
787 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);
792 * subfunction for bchannel_event
795 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
798 if (mISDNport->b_socket[i] < 0)
800 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
801 add_trace("channel", NULL, "%d", i+1+(i>=15));
802 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
804 close(mISDNport->b_socket[i]);
805 mISDNport->b_socket[i] = -1;
807 unsigned char buff[1024];
809 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
810 add_trace("channel", NULL, "%d", i+1+(i>=15));
811 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
812 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
814 /* remove our stack only if set */
815 if (mISDNport->b_addr[i])
817 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
818 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
819 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
820 mISDNport->b_addr[i] = 0;
830 A bchannel goes through the following states in this order:
833 No one is using the bchannel.
834 It is available and not linked to Port class, nor reserved.
837 The bchannel stack is created and an activation request is sent.
838 It MAY be linked to Port class, but already unlinked due to Port class removal.
841 The bchannel is active and cofigured to the Port class needs.
842 Also it is linked to a Port class, otherwhise it would be deactivated.
844 - B_STATE_DEACTIVATING
845 The bchannel is in deactivating state, due to deactivation request.
846 It may be linked to a Port class, that likes to reactivate it.
850 After deactivating bchannel, and if not used, the bchannel becomes idle again.
852 Also the bchannel may be exported, but only if the state is or becomes idle:
855 The bchannel assignment has been sent to the remove application.
858 The bchannel assignment is acknowledged by the remote application.
861 The bchannel is re-imported by mISDN port object.
865 After re-importing bchannel, and if not used, the bchannel becomes idle again.
868 A bchannel can have the following events:
871 A bchannel is required by a Port class.
872 The bchannel shall be exported to the remote application.
875 The bchannel beomes active.
878 The bchannel is not required by Port class anymore
880 - B_EVENT_DEACTIVATED
881 The bchannel becomes inactive.
884 The bchannel is now used by remote application.
887 The bchannel is not used by remote application.
889 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
891 if an export request is receive by remote application, p_m_remote_* is set.
892 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.)
893 - set on export request from remote application (if port is assigned)
894 - set on channel use, if requested by remote application (p_m_remote_*)
895 - cleared on drop request
897 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
898 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
899 the bchannel import/export is acknowledged with stack given.
901 if exporting, b_remote_*[index] is set to the remote socket id.
902 if importing has been acknowledged. b_remote_*[index] is cleared.
907 * process bchannel events
908 * - mISDNport is a pointer to the port's structure
909 * - i is the index of the bchannel
910 * - event is the B_EVENT_* value
911 * - port is the PmISDN class pointer
913 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
915 class PmISDN *b_port = mISDNport->b_port[i];
916 int state = mISDNport->b_state[i];
917 double timer = mISDNport->b_timer[i];
918 unsigned long p_m_remote_ref = 0;
919 unsigned long p_m_remote_id = 0;
922 char *p_m_pipeline = NULL;
923 unsigned char *p_m_crypt_key = NULL;
924 int p_m_crypt_key_len = 0;
925 int p_m_crypt_key_type = 0;
927 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
929 unsigned long portid = mISDNport->b_stid[i];
934 p_m_remote_id = b_port->p_m_remote_id;
935 p_m_remote_ref = b_port->p_m_remote_ref;
936 p_m_tx_gain = b_port->p_m_tx_gain;
937 p_m_rx_gain = b_port->p_m_rx_gain;
938 p_m_pipeline = b_port->p_m_pipeline;
939 p_m_crypt_key = b_port->p_m_crypt_key;
940 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
941 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
947 /* port must be linked in order to allow activation */
949 FATAL("bchannel must be linked to a Port class\n");
955 /* export bchannel */
956 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);
957 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
958 add_trace("type", NULL, "assign");
960 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
962 add_trace("socket", "id", "%d", portid);
965 state = B_STATE_EXPORTING;
966 mISDNport->b_remote_id[i] = p_m_remote_id;
967 mISDNport->b_remote_ref[i] = p_m_remote_ref;
970 /* create stack and send activation request */
971 if (_bchannel_create(mISDNport, i))
973 _bchannel_activate(mISDNport, i, 1);
974 state = B_STATE_ACTIVATING;
975 timer = now_d + B_TIMER_ACTIVATING;
980 case B_STATE_ACTIVATING:
981 case B_STATE_EXPORTING:
982 /* do nothing, because it is already activating */
985 case B_STATE_DEACTIVATING:
986 case B_STATE_IMPORTING:
987 /* do nothing, because we must wait until we can reactivate */
991 /* problems that might ocurr:
992 * B_EVENT_USE is received when channel already in use.
993 * bchannel exported, but not freed by other port
995 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
999 case B_EVENT_EXPORTREQUEST:
1000 /* special case where the bchannel is requested by remote */
1001 if (!p_m_remote_ref)
1003 PERROR("export request without remote channel set, please correct.\n");
1009 /* in case, the bchannel is exported right after seize_bchannel */
1010 /* export bchannel */
1011 /* p_m_remote_id is set, when this event happens. */
1012 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);
1013 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1014 add_trace("type", NULL, "assign");
1016 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1018 add_trace("socket", "id", "%d", portid);
1021 state = B_STATE_EXPORTING;
1022 mISDNport->b_remote_id[i] = p_m_remote_id;
1023 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1026 case B_STATE_ACTIVATING:
1027 case B_STATE_EXPORTING:
1028 /* do nothing, because it is already activating */
1031 case B_STATE_DEACTIVATING:
1032 case B_STATE_IMPORTING:
1033 /* do nothing, because we must wait until we can reactivate */
1036 case B_STATE_ACTIVE:
1037 /* bchannel is active, so we deactivate */
1038 _bchannel_activate(mISDNport, i, 0);
1039 state = B_STATE_DEACTIVATING;
1040 timer = now_d + B_TIMER_DEACTIVATING;
1044 /* problems that might ocurr:
1045 * ... when channel already in use.
1046 * bchannel exported, but not freed by other port
1048 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1052 case B_EVENT_ACTIVATED:
1056 case B_STATE_ACTIVATING:
1057 if (b_port && !p_m_remote_id)
1059 /* bchannel is active and used by Port class, so we configure bchannel */
1060 _bchannel_configure(mISDNport, i);
1061 state = B_STATE_ACTIVE;
1064 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
1065 _bchannel_activate(mISDNport, i, 0);
1066 state = B_STATE_DEACTIVATING;
1067 timer = now_d + B_TIMER_DEACTIVATING;
1072 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1076 case B_EVENT_EXPORTED:
1079 case B_STATE_EXPORTING:
1080 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
1082 /* remote export done */
1083 state = B_STATE_REMOTE;
1086 /* bchannel is now exported, but we need bchannel back
1087 * OR bchannel is not used anymore
1088 * OR bchannel has been exported to an obsolete ref,
1089 * so reimport, to later export to new remote */
1090 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1091 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1092 add_trace("type", NULL, "remove");
1094 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1096 add_trace("socket", "id", "%d", portid);
1099 state = B_STATE_IMPORTING;
1104 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1110 FATAL("bchannel must be linked to a Port class\n");
1114 /* bchannel is idle due to an error, so we do nothing */
1117 case B_STATE_ACTIVATING:
1118 case B_STATE_EXPORTING:
1119 /* do nothing because we must wait until bchanenl is active before deactivating */
1122 case B_STATE_ACTIVE:
1123 /* bchannel is active, so we deactivate */
1124 _bchannel_activate(mISDNport, i, 0);
1125 state = B_STATE_DEACTIVATING;
1126 timer = now_d + B_TIMER_DEACTIVATING;
1129 case B_STATE_REMOTE:
1130 /* bchannel is exported, so we re-import */
1131 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1132 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1133 add_trace("type", NULL, "remove");
1135 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1137 add_trace("socket", "id", "%d", portid);
1140 state = B_STATE_IMPORTING;
1143 case B_STATE_DEACTIVATING:
1144 case B_STATE_IMPORTING:
1145 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1149 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1153 case B_EVENT_DEACTIVATED:
1158 /* ignore due to deactivation confirm after unloading */
1161 case B_STATE_DEACTIVATING:
1162 _bchannel_destroy(mISDNport, i);
1163 state = B_STATE_IDLE;
1166 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1169 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);
1170 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1171 add_trace("type", NULL, "assign");
1173 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1175 add_trace("socket", "id", "%d", portid);
1178 state = B_STATE_EXPORTING;
1179 mISDNport->b_remote_id[i] = p_m_remote_id;
1180 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1183 if (_bchannel_create(mISDNport, i))
1185 _bchannel_activate(mISDNport, i, 1);
1186 state = B_STATE_ACTIVATING;
1187 timer = now_d + B_TIMER_ACTIVATING;
1194 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1198 case B_EVENT_IMPORTED:
1201 case B_STATE_IMPORTING:
1202 state = B_STATE_IDLE;
1203 mISDNport->b_remote_id[i] = 0;
1204 mISDNport->b_remote_ref[i] = 0;
1207 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1210 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);
1211 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1212 add_trace("type", NULL, "assign");
1214 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1216 add_trace("socket", "id", "%d", portid);
1219 state = B_STATE_EXPORTING;
1220 mISDNport->b_remote_id[i] = p_m_remote_id;
1221 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1224 if (_bchannel_create(mISDNport, i))
1226 _bchannel_activate(mISDNport, i, 1);
1227 state = B_STATE_ACTIVATING;
1228 timer = now_d + B_TIMER_ACTIVATING;
1235 /* ignore, because not assigned */
1240 case B_EVENT_TIMEOUT:
1245 /* ignore due to deactivation confirm after unloading */
1248 case B_STATE_ACTIVATING:
1249 _bchannel_activate(mISDNport, i, 1);
1250 timer = now_d + B_TIMER_ACTIVATING;
1253 case B_STATE_DEACTIVATING:
1254 _bchannel_activate(mISDNport, i, 0);
1255 timer = now_d + B_TIMER_DEACTIVATING;
1259 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1264 PERROR("Illegal event %d, please correct.\n", event);
1267 mISDNport->b_state[i] = state;
1268 mISDNport->b_timer[i] = timer;
1275 * check for available channel and reserve+set it.
1276 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1277 * give exclusiv flag
1278 * returns -(cause value) or x = channel x or 0 = no channel
1279 * NOTE: no activation is done here
1281 int PmISDN::seize_bchannel(int channel, int exclusive)
1285 /* the channel is what we have */
1286 if (p_m_b_channel == channel)
1289 /* if channel already in use, release it */
1294 if (channel==CHANNEL_NO || channel==0)
1297 /* is channel in range ? */
1299 || (channel>p_m_mISDNport->b_num && channel<16)
1300 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1301 return(-6); /* channel unacceptable */
1303 /* request exclusive channel */
1304 if (exclusive && channel>0)
1306 i = channel-1-(channel>16);
1307 if (p_m_mISDNport->b_port[i])
1308 return(-44); /* requested channel not available */
1312 /* ask for channel */
1315 i = channel-1-(channel>16);
1316 if (p_m_mISDNport->b_port[i] == NULL)
1320 /* search for channel */
1322 while(i < p_m_mISDNport->b_num)
1324 if (!p_m_mISDNport->b_port[i])
1326 channel = i+1+(i>=15);
1331 return(-34); /* no free channel */
1334 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1337 p_m_mISDNport->b_port[i] = this;
1339 p_m_b_channel = channel;
1340 p_m_b_exclusive = exclusive;
1342 /* reserve channel */
1346 p_m_mISDNport->b_reserved++;
1353 * drop reserved channel and unset it.
1354 * deactivation is also done
1356 void PmISDN::drop_bchannel(void)
1358 /* unreserve channel */
1360 p_m_mISDNport->b_reserved--;
1364 if (p_m_b_index < 0)
1369 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1371 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1372 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1373 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1376 p_m_b_exclusive = 0;
1379 /* process bchannel export/import message from join */
1380 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1382 class Endpoint *epoint;
1384 class PmISDN *isdnport;
1385 struct mISDNport *mISDNport;
1390 case BCHANNEL_REQUEST:
1391 /* find the port object for the join object ref */
1392 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1394 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1397 if (!epoint->ep_portlist)
1399 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1402 if (epoint->ep_portlist->next)
1404 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);
1406 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1408 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1411 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1413 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1415 isdnport = (class PmISDN *)port;
1418 if (isdnport->p_m_remote_id)
1420 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1423 mISDNport = isdnport->p_m_mISDNport;
1424 i = isdnport->p_m_b_index;
1425 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1426 add_trace("type", NULL, "export request");
1427 isdnport->p_m_remote_ref = joinremote->j_serial;
1428 isdnport->p_m_remote_id = joinremote->j_remote_id;
1429 if (mISDNport && i>=0)
1431 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1436 case BCHANNEL_ASSIGN_ACK:
1437 case BCHANNEL_REMOVE_ACK:
1438 /* find mISDNport for stack ID */
1439 mISDNport = mISDNport_first;
1443 ii = mISDNport->b_num;
1447 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1449 if (mISDNport->b_addr[i] == handle)
1456 mISDNport = mISDNport->next;
1460 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1463 /* mISDNport may now be set or NULL */
1466 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1467 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1468 if (mISDNport && i>=0)
1469 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1473 PERROR("received wrong bchannel message type %d from remote\n", type);
1481 audio transmission procedure:
1482 -----------------------------
1485 three sources of audio transmission:
1486 - crypto-data high priority
1487 - tones high priority (also high)
1488 - remote-data low priority
1491 a variable that temporarily shows the number of samples elapsed since last transmission process.
1492 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1495 a variable that is increased whenever data is transmitted.
1496 it is decreased while time elapses. it stores the number of samples that
1497 are currently loaded to dsp module.
1498 since clock in dsp module is the same clock for user space process, these
1502 there are two levels:
1503 ISDN_LOAD will give the load that have to be kept in dsp.
1504 ISDN_MAXLOAD will give the maximum load before dropping.
1506 * procedure for low priority data
1507 see txfromup() for procedure
1508 in short: remote data is ignored during high priority tones
1510 * procedure for high priority data
1511 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1512 if no more data is available, load becomes empty again.
1515 0 ISDN_LOAD ISDN_MAXLOAD
1516 +--------------------+----------------------+
1518 +--------------------+----------------------+
1520 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1521 0 ISDN_LOAD ISDN_MAXLOAD
1522 +--------------------+----------------------+
1523 |TTTTTTTTTTTTTTTTTTTT| |
1524 +--------------------+----------------------+
1526 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1527 0 ISDN_LOAD ISDN_MAXLOAD
1528 +--------------------+----------------------+
1529 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1530 +--------------------+----------------------+
1533 int PmISDN::handler(void)
1535 struct lcr_msg *message;
1539 if ((ret = Port::handler()))
1543 if (p_m_last_tv_sec)
1545 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1546 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1549 /* set clock of first process ever in this instance */
1550 p_m_last_tv_sec = now_tv.tv_sec;
1551 p_m_last_tv_msec = now_tv.tv_usec/1000;
1553 /* process only if we have a minimum of samples, to make packets not too small */
1554 if (elapsed >= ISDN_TRANSMIT)
1556 /* set clock of last process! */
1557 p_m_last_tv_sec = now_tv.tv_sec;
1558 p_m_last_tv_msec = now_tv.tv_usec/1000;
1561 if (elapsed < p_m_load)
1562 p_m_load -= elapsed;
1566 /* to send data, tone must be active OR crypt messages must be on */
1567 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1568 && (p_m_load < ISDN_LOAD)
1569 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1571 int tosend = ISDN_LOAD - p_m_load, length;
1573 unsigned char buf[MISDN_HEADER_LEN+tosend];
1574 struct mISDNhead *frm = (struct mISDNhead *)buf;
1575 unsigned char *p = buf+MISDN_HEADER_LEN;
1577 unsigned char buf[mISDN_HEADER_LEN+tosend];
1578 iframe_t *frm = (iframe_t *)buf;
1579 unsigned char *p = buf+mISDN_HEADER_LEN;
1582 /* copy crypto loops */
1583 while (p_m_crypt_msg_loops && tosend)
1585 /* how much do we have to send */
1586 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1589 if (length > tosend)
1592 /* copy message (part) to buffer */
1593 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1596 p_m_crypt_msg_current += length;
1597 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1600 p_m_crypt_msg_current = 0;
1601 p_m_crypt_msg_loops--;
1602 // puts("eine loop weniger");
1610 if (p_tone_name[0] && tosend)
1612 tosend -= read_audio(p, tosend);
1616 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && ISDN_LOAD-p_m_load-tosend > 0)
1619 frm->prim = PH_DATA_REQ;
1621 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1623 PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_socket[p_m_b_index], ISDN_LOAD-p_m_load-tosend);
1625 frm->prim = DL_DATA | REQUEST;
1626 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1628 frm->len = ISDN_LOAD - p_m_load - tosend;
1630 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1633 p_m_load += ISDN_LOAD - p_m_load - tosend;
1637 // NOTE: deletion is done by the child class
1639 /* handle timeouts */
1642 if (p_m_timer+p_m_timeout < now_d)
1644 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1646 /* send timeout to endpoint */
1647 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1648 message->param.state = p_state;
1649 message_put(message);
1654 return(0); /* nothing done */
1659 * whenever we get audio data from bchannel, we process it here
1662 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1664 unsigned long cont = *((unsigned long *)data);
1666 void PmISDN::bchannel_receive(iframe_t *frm)
1669 unsigned long cont = *((unsigned long *)&frm->data.p);
1670 unsigned char *data =(unsigned char *)&frm->data.p;
1672 unsigned char *data_temp;
1673 unsigned long length_temp;
1674 struct lcr_msg *message;
1679 if (hh->prim == PH_CONTROL_IND)
1681 if (frm->prim == (PH_CONTROL | INDICATION))
1686 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1689 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1691 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1692 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1694 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1695 message->param.dtmf = cont & DTMF_TONE_MASK;
1696 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1697 message_put(message);
1707 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1708 add_trace("DSP-CRYPT", NULL, "error");
1710 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1711 message->param.crypt.type = CC_ERROR_IND;
1712 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1713 message_put(message);
1721 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1722 add_trace("DSP-CRYPT", NULL, "ok");
1724 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1725 message->param.crypt.type = CC_ACTBF_CONF;
1726 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1727 message_put(message);
1731 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1732 add_trace("unknown", NULL, "0x%x", cont);
1738 if (hh->prim == PH_CONTROL_IND)
1742 if (frm->prim == (PH_SIGNAL | INDICATION)
1743 || frm->prim == (PH_CONTROL | INDICATION))
1749 #ifndef SOCKET_MISDN
1753 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1754 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1757 /* see below (same condition) */
1758 if (p_state!=PORT_STATE_CONNECT
1759 && !p_m_mISDNport->tones)
1761 // printf(".");fflush(stdout);return;
1763 record(data, len, 1); // from up
1769 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1771 add_trace("unknown", NULL, "0x%x", hh->id);
1773 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1780 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1784 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1785 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1788 /* see below (same condition) */
1789 if (p_state!=PORT_STATE_CONNECT
1790 && !p_m_mISDNport->tones)
1792 // printf(".");fflush(stdout);return;
1794 record(data, len, 1); // from up
1797 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1799 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1801 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1803 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1807 /* calls will not process any audio data unless
1808 * the call is connected OR interface features audio during call setup.
1810 //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);
1811 #ifndef DEBUG_COREBRIDGE
1812 if (p_state!=PORT_STATE_CONNECT
1813 && !p_m_mISDNport->tones)
1817 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1820 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1826 record(data, len, 0); // from down
1828 /* randomize and listen to crypt message if enabled */
1829 if (p_m_crypt_listen)
1831 /* the noisy randomizer */
1835 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1837 cryptman_listen_bch(data, len);
1842 /* send data to epoint */
1843 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1849 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1850 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1851 memcpy(message->param.data.data, data_temp, message->param.data.len);
1852 message_put(message);
1853 if (length_temp <= sizeof(message->param.data.data))
1855 data_temp += sizeof(message->param.data.data);
1856 length_temp -= sizeof(message->param.data.data);
1865 void PmISDN::set_echotest(int echo)
1867 if (p_m_echo != echo)
1870 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1872 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1874 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);
1876 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);
1884 void PmISDN::set_tone(char *dir, char *tone)
1890 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1897 /* check if we NOT really have to use a dsp-tone */
1898 if (!options.dsptones)
1902 if (p_m_b_index > -1)
1903 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1905 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1907 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1909 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1913 Port::set_tone(dir, tone);
1919 /* now we USE dsp-tone, convert name */
1920 else if (!strcmp(tone, "dialtone"))
1922 switch(options.dsptones) {
1923 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1924 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1925 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1927 } else if (!strcmp(tone, "dialpbx"))
1929 switch(options.dsptones) {
1930 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1931 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1932 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1934 } else if (!strcmp(tone, "ringing"))
1936 switch(options.dsptones) {
1937 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1938 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1939 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1941 } else if (!strcmp(tone, "ringpbx"))
1943 switch(options.dsptones) {
1944 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1945 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1946 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1948 } else if (!strcmp(tone, "busy"))
1951 switch(options.dsptones) {
1952 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1953 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1954 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1956 } else if (!strcmp(tone, "release"))
1959 switch(options.dsptones) {
1960 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1961 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1962 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1964 } else if (!strcmp(tone, "cause_10"))
1966 else if (!strcmp(tone, "cause_11"))
1968 else if (!strcmp(tone, "cause_22"))
1970 switch(options.dsptones) {
1971 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1972 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1973 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1975 } else if (!strncmp(tone, "cause_", 6))
1976 id = TONE_SPECIAL_INFO;
1980 /* if we have a tone that is not supported by dsp */
1981 if (id==TONE_OFF && tone[0])
1989 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1990 if (p_m_b_index > -1)
1991 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1993 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);
1995 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);
1998 /* turn user-space tones off in cases of no tone OR dsp tone */
1999 Port::set_tone("",NULL);
2003 /* MESSAGE_mISDNSIGNAL */
2004 //extern struct lcr_msg *dddebug;
2005 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
2007 switch(param->mISDNsignal.message)
2009 case mISDNSIGNAL_VOLUME:
2010 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
2012 p_m_tx_gain = param->mISDNsignal.tx_gain;
2013 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
2014 if (p_m_b_index > -1)
2015 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2017 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);
2019 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);
2022 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
2023 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
2025 p_m_rx_gain = param->mISDNsignal.rx_gain;
2026 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
2027 if (p_m_b_index > -1)
2028 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2030 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);
2032 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);
2035 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
2038 case mISDNSIGNAL_CONF:
2039 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2040 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
2041 if (p_m_conf != param->mISDNsignal.conf)
2043 p_m_conf = param->mISDNsignal.conf;
2044 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
2045 if (p_m_b_index > -1)
2046 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2048 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);
2050 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);
2053 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
2054 /* we must set, even if currently tone forbids conf */
2055 p_m_conf = param->mISDNsignal.conf;
2056 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
2059 case mISDNSIGNAL_JOINDATA:
2060 if (p_m_joindata != param->mISDNsignal.joindata)
2062 p_m_joindata = param->mISDNsignal.joindata;
2063 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
2065 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
2068 case mISDNSIGNAL_DELAY:
2069 if (p_m_delay != param->mISDNsignal.delay)
2071 p_m_delay = param->mISDNsignal.delay;
2072 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
2074 if (p_m_b_index > -1)
2075 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2077 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);
2079 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);
2083 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
2087 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
2092 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
2094 struct lcr_msg *message;
2096 switch(param->crypt.type)
2098 case CC_ACTBF_REQ: /* activate blowfish */
2100 p_m_crypt_key_len = param->crypt.len;
2101 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
2103 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
2104 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
2105 message->param.crypt.type = CC_ERROR_IND;
2106 message_put(message);
2109 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
2111 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
2112 if (p_m_b_index > -1)
2113 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
2115 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);
2117 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);
2121 case CC_DACT_REQ: /* deactivate session encryption */
2126 case CR_LISTEN_REQ: /* start listening to messages */
2127 p_m_crypt_listen = 1;
2128 p_m_crypt_listen_state = 0;
2131 case CR_UNLISTEN_REQ: /* stop listening to messages */
2132 p_m_crypt_listen = 0;
2135 case CR_MESSAGE_REQ: /* send message */
2136 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2137 if (!p_m_crypt_msg_len)
2139 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2142 p_m_crypt_msg_current = 0; /* reset */
2143 p_m_crypt_msg_loops = 6; /* enable */
2145 /* disable txmix, or we get corrupt data due to audio process */
2146 if (p_m_txmix && p_m_b_index>=0)
2148 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2150 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
2152 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2159 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2165 * endpoint sends messages to the port
2167 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2169 if (Port::message_epoint(epoint_id, message_id, param))
2174 case MESSAGE_DATA: /* tx-data from upper layer */
2175 txfromup(param->data.data, param->data.len);
2178 case MESSAGE_mISDNSIGNAL: /* user command */
2179 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2180 message_mISDNsignal(epoint_id, message_id, param);
2183 case MESSAGE_CRYPT: /* crypt control command */
2184 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2185 message_crypt(epoint_id, message_id, param);
2194 * main loop for processing messages from mISDN
2197 int mISDN_handler(void)
2200 struct mISDNport *mISDNport;
2201 class PmISDN *isdnport;
2203 unsigned char buffer[2048+MISDN_HEADER_LEN];
2204 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2208 /* process all ports */
2209 mISDNport = mISDNport_first;
2212 /* process all bchannels */
2214 while(i < mISDNport->b_num)
2216 /* process timer events for bchannel handling */
2217 if (mISDNport->b_timer[i])
2219 if (mISDNport->b_timer[i] <= now_d)
2220 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2222 /* handle port of bchannel */
2223 isdnport=mISDNport->b_port[i];
2226 /* call bridges in user space OR crypto OR recording */
2227 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2229 /* rx IS required */
2230 if (isdnport->p_m_rxoff)
2233 isdnport->p_m_rxoff = 0;
2234 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
2235 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2236 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2241 /* rx NOT required */
2242 if (!isdnport->p_m_rxoff)
2245 isdnport->p_m_rxoff = 1;
2246 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
2247 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2248 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2253 if (isdnport->p_record)
2255 /* txdata IS required */
2256 if (!isdnport->p_m_txdata)
2259 isdnport->p_m_txdata = 1;
2260 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
2261 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2262 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
2267 /* txdata NOT required */
2268 if (isdnport->p_m_txdata)
2271 isdnport->p_m_txdata = 0;
2272 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
2273 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2274 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2280 /* handle message from bchannel */
2281 if (mISDNport->b_socket[i] > -1)
2283 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
2284 if (ret >= (int)MISDN_HEADER_LEN)
2289 /* we don't care about confirms, we use rx data to sync tx */
2293 /* we receive audio data, we respond to it AND we send tones */
2296 case PH_CONTROL_IND:
2297 if (mISDNport->b_port[i])
2298 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2300 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
2303 case PH_ACTIVATE_IND:
2304 case DL_ESTABLISH_IND:
2305 case PH_ACTIVATE_CNF:
2306 case DL_ESTABLISH_CNF:
2307 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2308 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2311 case PH_DEACTIVATE_IND:
2312 case DL_RELEASE_IND:
2313 case PH_DEACTIVATE_CNF:
2314 case DL_RELEASE_CNF:
2315 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2316 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2320 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
2324 if (ret < 0 && errno != EWOULDBLOCK)
2325 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2332 /* handle queued up-messages (d-channel) */
2333 while ((mb = mdequeue(&mISDNport->upqueue)))
2338 case MPH_ACTIVATE_IND:
2339 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
2341 mISDNport->l1link = 1;
2344 case MPH_DEACTIVATE_IND:
2345 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
2347 mISDNport->l1link = 0;
2350 case MPH_INFORMATION_IND:
2351 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2354 case L1_SIGNAL_LOS_ON:
2357 case L1_SIGNAL_LOS_OFF:
2360 case L1_SIGNAL_AIS_ON:
2363 case L1_SIGNAL_AIS_OFF:
2366 case L1_SIGNAL_RDI_ON:
2369 case L1_SIGNAL_RDI_OFF:
2372 case L1_SIGNAL_SLIP_TX:
2373 mISDNport->slip_tx++;
2375 case L1_SIGNAL_SLIP_RX:
2376 mISDNport->slip_rx++;
2381 case MT_L2ESTABLISH:
2382 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2383 add_trace("tei", NULL, "%d", l3m->pid);
2385 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2387 if (mISDNport->l2establish)
2389 mISDNport->l2establish = 0;
2390 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2392 mISDNport->l2link = 1;
2397 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2398 add_trace("tei", NULL, "%d", l3m->pid);
2400 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2402 mISDNport->l2link = 0;
2403 if (mISDNport->l2hold)
2405 time(&mISDNport->l2establish);
2406 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2412 /* l3-data is sent to LCR */
2413 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2420 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2422 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2423 mISDNport->l1timeout = 0;
2426 /* layer 2 establish timer */
2427 if (mISDNport->l2establish)
2429 if (now-mISDNport->l2establish > 5)
2431 mISDNport->l2establish = 0;
2432 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2435 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2436 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2437 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2438 add_trace("tei", NULL, "%d", 0);
2440 time(&mISDNport->l2establish);
2447 mISDNport = mISDNport->next;
2450 /* if we received at least one b-frame, we will return 1 */
2454 int mISDN_handler(void)
2457 struct mISDNport *mISDNport;
2458 class PmISDN *isdnport;
2463 mISDNuser_head_t *hh;
2466 /* the que avoids loopbacks when replying to stack after receiving
2468 mISDNport = mISDNport_first;
2471 /* process turning on/off rx */
2473 while(i < mISDNport->b_num)
2475 /* process timer events for bchannel handling */
2476 if (mISDNport->b_timer[i])
2478 if (mISDNport->b_timer[i] <= now_d)
2479 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2481 isdnport=mISDNport->b_port[i];
2484 /* call bridges in user space OR crypto OR recording */
2485 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2487 /* rx IS required */
2488 if (isdnport->p_m_rxoff)
2491 isdnport->p_m_rxoff = 0;
2492 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
2493 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2494 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2499 /* rx NOT required */
2500 if (!isdnport->p_m_rxoff)
2503 isdnport->p_m_rxoff = 1;
2504 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
2505 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2506 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2511 if (isdnport->p_record)
2513 /* txdata IS required */
2514 if (!isdnport->p_m_txdata)
2517 isdnport->p_m_txdata = 1;
2518 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
2520 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2521 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2527 /* txdata NOT required */
2528 if (isdnport->p_m_txdata)
2531 isdnport->p_m_txdata = 0;
2532 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
2534 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2535 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2544 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2546 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2547 mISDNport->l1timeout = 0;
2550 if (mISDNport->l2establish)
2552 if (now-mISDNport->l2establish > 5)
2554 mISDNport->l2establish = 0;
2555 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2557 if (mISDNport->ntmode)
2559 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2560 time(&mISDNport->l2establish);
2562 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2563 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2568 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2569 time(&mISDNport->l2establish);
2571 act.prim = DL_ESTABLISH | REQUEST;
2572 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2575 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2577 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2578 add_trace("tei", NULL, "%d", 0);
2580 time(&mISDNport->l2establish);
2585 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2587 if (mISDNport->ntmode)
2589 hh = (mISDNuser_head_t *)dmsg->data;
2590 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);
2591 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2595 frm = (iframe_t *)dmsg->data;
2596 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2597 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2598 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);
2599 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2604 mISDNport = mISDNport->next;
2607 /* no device, no read */
2608 if (mISDNdevice < 0)
2611 /* get message from kernel */
2612 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2614 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2618 if (errno == EAGAIN)
2620 FATAL("Failed to do mISDN_read()\n");
2625 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2629 frm = (iframe_t *)msg->data;
2634 case MGR_DELLAYER | CONFIRM:
2635 case MGR_INITTIMER | CONFIRM:
2636 case MGR_ADDTIMER | CONFIRM:
2637 case MGR_DELTIMER | CONFIRM:
2638 case MGR_REMOVETIMER | CONFIRM:
2643 /* handle timer events from mISDN for NT-stack
2644 * note: they do not associate with a stack */
2645 if (frm->prim == (MGR_TIMER | INDICATION))
2649 /* find mISDNport */
2650 mISDNport = mISDNport_first;
2654 if (mISDNport->ntmode)
2656 it = mISDNport->nst.tlist;
2660 if (it->id == (int)frm->addr)
2667 mISDNport = mISDNport->next;
2671 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2672 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2674 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2675 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2676 ret = it->function(it->data);
2679 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2684 /* find the mISDNport that belongs to the stack */
2685 mISDNport = mISDNport_first;
2688 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2690 mISDNport = mISDNport->next;
2694 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2695 // show a list of all mISDNports and their address
2697 mISDNport = mISDNport_first;
2700 PERROR(" port %s %x -> %x\n", mISDNport->name, (frm->addr&MASTER_ID_MASK), (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK));
2701 mISDNport = mISDNport->next;
2708 if (!(frm->addr&FLG_CHILD_STACK))
2713 case MGR_SHORTSTATUS | INDICATION:
2714 case MGR_SHORTSTATUS | CONFIRM:
2715 switch(frm->dinfo) {
2716 case SSTATUS_L1_ACTIVATED:
2717 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2720 case SSTATUS_L1_DEACTIVATED:
2721 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2724 case SSTATUS_L2_ESTABLISHED:
2725 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2728 case SSTATUS_L2_RELEASED:
2729 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2735 case PH_ACTIVATE | CONFIRM:
2736 case PH_ACTIVATE | INDICATION:
2737 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2739 if (mISDNport->ntmode)
2741 mISDNport->l1link = 1;
2742 setup_queue(mISDNport, 1);
2746 mISDNport->l1link = 1;
2747 setup_queue(mISDNport, 1);
2750 case PH_DEACTIVATE | CONFIRM:
2751 case PH_DEACTIVATE | INDICATION:
2752 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2754 if (mISDNport->ntmode)
2756 mISDNport->l1link = 0;
2757 setup_queue(mISDNport, 0);
2761 mISDNport->l1link = 0;
2762 setup_queue(mISDNport, 0);
2765 case PH_CONTROL | CONFIRM:
2766 case PH_CONTROL | INDICATION:
2767 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2770 case DL_ESTABLISH | INDICATION:
2771 case DL_ESTABLISH | CONFIRM:
2772 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ | (frm->prim & 0x3), DIRECTION_IN);
2774 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2776 if (!mISDNport->ntmode || mISDNport->ptp)
2778 if (mISDNport->l2establish)
2780 mISDNport->l2establish = 0;
2781 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2783 mISDNport->l2link = 1;
2787 case DL_RELEASE | INDICATION:
2788 case DL_RELEASE | CONFIRM:
2789 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_REQ | (frm->prim & 0x3), DIRECTION_IN);
2791 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2793 if (!mISDNport->ntmode || mISDNport->ptp)
2795 mISDNport->l2link = 0;
2796 if (mISDNport->l2hold)
2798 time(&mISDNport->l2establish);
2799 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2806 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);
2807 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2809 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2812 if (mISDNport->ntmode)
2814 /* l1-data enters the nt-mode library */
2815 nst = &mISDNport->nst;
2816 if (nst->l1_l2(nst, msg))
2821 /* l3-data is sent to pbx */
2822 if (stack2manager_te(mISDNport, msg))
2833 /* we don't care about confirms, we use rx data to sync tx */
2834 case PH_DATA | CONFIRM:
2835 case DL_DATA | CONFIRM:
2838 /* we receive audio data, we respond to it AND we send tones */
2839 case PH_DATA | INDICATION:
2840 case DL_DATA | INDICATION:
2841 case PH_CONTROL | INDICATION:
2842 case PH_SIGNAL | INDICATION:
2844 while(i < mISDNport->b_num)
2846 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2850 if (i == mISDNport->b_num)
2852 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2855 if (mISDNport->b_port[i])
2857 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2858 mISDNport->b_port[i]->bchannel_receive(frm);
2860 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2863 case PH_ACTIVATE | INDICATION:
2864 case DL_ESTABLISH | INDICATION:
2865 case PH_ACTIVATE | CONFIRM:
2866 case DL_ESTABLISH | CONFIRM:
2867 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2869 while(i < mISDNport->b_num)
2871 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2875 if (i == mISDNport->b_num)
2877 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2880 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2883 case PH_DEACTIVATE | INDICATION:
2884 case DL_RELEASE | INDICATION:
2885 case PH_DEACTIVATE | CONFIRM:
2886 case DL_RELEASE | CONFIRM:
2887 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2889 while(i < mISDNport->b_num)
2891 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2895 if (i == mISDNport->b_num)
2897 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2900 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2904 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2915 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2919 * l3m must be queued, except for MT_ASSIGN
2922 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2925 /* special MT_ASSIGN handling:
2927 * if we request a PID from mlayer, we always do it while lcr is locked.
2928 * therefore we must check the MT_ASSIGN reply first before we lock.
2929 * this is because the MT_ASSIGN reply is received with the requesting
2930 * process, not by the mlayer thread!
2931 * this means, that the reply is sent during call of the request.
2932 * we must check if we get a reply and we know that we lcr is currently
2935 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2937 /* let's do some checking if someone changes stack behaviour */
2938 if (mt_assign_pid != 0)
2939 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2940 mt_assign_pid = pid;
2944 /* queue message, create, if required */
2947 l3m = alloc_l3_msg();
2949 FATAL("No memory for layer 3 message\n");
2951 mb = container_of(l3m, struct mbuffer, l3);
2954 mqueue_tail(&mISDNport->upqueue, mb);
2962 * global function to add a new card (port)
2964 struct mISDNport *mISDNport_open(int port, int ptp, int force_nt, int l2hold, struct interface *interface)
2967 struct mISDNport *mISDNport, **mISDNportp;
2972 // struct mlayer3 *ml3;
2973 struct mISDN_devinfo devinfo;
2974 unsigned int protocol, prop;
2976 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2979 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2983 unsigned char buff[1025];
2984 iframe_t *frm = (iframe_t *)buff;
2985 // interface_info_t ii;
2989 stack_info_t *stinf;
2991 /* query port's requirements */
2992 cnt = mISDN_get_stack_count(mISDNdevice);
2997 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
3000 if (port>cnt || port<1)
3002 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
3006 pri = bri = pots = nt = te = 0;
3008 devinfo.id = port - 1;
3009 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
3012 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3015 /* output the port info */
3016 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3021 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3026 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3031 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3037 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3044 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3050 if (force_nt && !nt)
3052 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
3057 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
3060 if (pots && !bri && !pri)
3062 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
3067 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
3072 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
3075 /* set NT by turning off TE */
3078 /* if TE an NT is supported (and not forced to NT), turn off NT */
3082 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
3085 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
3088 stinf = (stack_info_t *)&frm->data.p;
3089 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3091 case ISDN_PID_L0_TE_S0:
3092 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
3094 case ISDN_PID_L0_NT_S0:
3095 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
3098 case ISDN_PID_L0_TE_E1:
3099 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
3102 case ISDN_PID_L0_NT_E1:
3103 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
3108 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
3114 if (stinf->pid.protocol[1] == 0)
3116 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
3119 if (stinf->pid.protocol[2])
3121 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
3128 if (stinf->pid.protocol[1] == 0)
3130 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
3133 if (stinf->pid.protocol[2] == 0)
3135 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
3138 if (stinf->pid.protocol[3] == 0)
3140 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
3144 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3146 case ISDN_PID_L3_DSS1USER:
3150 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
3154 if (stinf->pid.protocol[4])
3156 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
3162 /* add mISDNport structure */
3163 mISDNportp = &mISDNport_first;
3165 mISDNportp = &((*mISDNportp)->next);
3166 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3168 *mISDNportp = mISDNport;
3170 /* if pri, must set PTP */
3191 /* allocate ressources of port */
3193 /* open layer 3 and init upqueue */
3194 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
3195 prop = (1 << MISDN_FLG_L2_CLEAN);
3196 if (ptp) // ptp forced
3197 prop |= (1 << MISDN_FLG_PTP);
3198 if (nt) // supports hold/retrieve on nt-mode
3199 prop |= (1 << MISDN_FLG_NET_HOLD);
3200 if (l2hold) // supports layer 2 hold
3201 prop |= (1 << MISDN_FLG_L2_HOLD);
3202 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
3203 mqueue_init(&mISDNport->upqueue);
3204 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_layer3, mISDNport);
3205 if (!mISDNport->ml3)
3207 mqueue_purge(&mISDNport->upqueue);
3208 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
3216 "PORT (open failed)");
3218 mISDNport_close(mISDNport);
3223 /* if ntmode, establish L1 to send the tei removal during start */
3224 if (mISDNport->ntmode)
3228 act.prim = PH_ACTIVATE | REQUEST;
3229 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3230 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3233 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3234 usleep(10000); /* to be sure, that l1 is up */
3238 SCPY(mISDNport->name, devinfo.name);
3239 mISDNport->b_num = devinfo.nrbchan;
3241 msg_queue_init(&mISDNport->downqueue);
3242 mISDNport->d_stid = stinf->id;
3243 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3245 /* create layer intance */
3246 memset(&li, 0, sizeof(li));
3247 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3250 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3251 li.pid.layermask = ISDN_LAYER((nt?2:4));
3252 li.st = mISDNport->d_stid;
3253 ret = mISDN_new_layer(mISDNdevice, &li);
3256 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3258 mISDNport_close(mISDNport);
3261 mISDNport->upper_id = li.id;
3262 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3265 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3268 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3269 if (mISDNport->lower_id < 0)
3271 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3274 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3275 if (mISDNport->upper_id < 0)
3277 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3280 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3282 /* if ntmode, establish L1 to send the tei removal during start */
3283 if (mISDNport->ntmode)
3287 act.prim = PH_ACTIVATE | REQUEST;
3288 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3289 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3292 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3293 usleep(10000); /* to be sure, that l1 is up */
3296 /* create nst (nt-mode only) */
3299 mgr = &mISDNport->mgr;
3300 nst = &mISDNport->nst;
3305 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3306 nst->device = mISDNdevice;
3308 nst->d_stid = mISDNport->d_stid;
3310 nst->feature = FEATURE_NET_HOLD;
3312 nst->feature |= FEATURE_NET_PTP;
3314 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3317 while(i < mISDNport->b_num)
3319 nst->b_stid[i] = mISDNport->b_stid[i];
3323 nst->l1_id = mISDNport->lower_id;
3324 nst->l2_id = mISDNport->upper_id;
3327 msg_queue_init(&nst->down_queue);
3333 mISDNport->b_num = stinf->childcnt;
3335 mISDNport->portnum = port;
3336 mISDNport->ntmode = nt;
3337 mISDNport->pri = pri;
3338 mISDNport->ptp = ptp;
3339 mISDNport->l2hold = l2hold;
3340 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3342 while(i < mISDNport->b_num)
3344 mISDNport->b_state[i] = B_STATE_IDLE;
3346 mISDNport->b_socket[i] = -1;
3348 mISDNport->b_stid[i] = stinf->child[i];
3349 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3355 /* if ptp, pull up the link */
3356 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
3358 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
3359 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3360 add_trace("tei", NULL, "%d", 0);
3362 time(&mISDNport->l2establish);
3365 /* if te-mode, query state link */
3366 if (!mISDNport->ntmode)
3370 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3371 act.prim = MGR_SHORTSTATUS | REQUEST;
3372 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3373 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3375 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3377 /* if ptp AND te-mode, pull up the link */
3378 if (mISDNport->l2hold && !mISDNport->ntmode)
3382 act.prim = DL_ESTABLISH | REQUEST;
3383 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3386 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3388 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3390 time(&mISDNport->l2establish);
3392 /* if ptp AND nt-mode, pull up the link */
3393 if (mISDNport->l2hold && mISDNport->ntmode && mISDNport->ptp)
3397 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3398 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3400 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
3402 time(&mISDNport->l2establish);
3406 /* initially, we assume that the link is down, exept for nt-ptmp */
3407 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3409 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3411 start_trace(mISDNport->portnum,
3419 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
3420 add_trace("channels", NULL, "%d", mISDNport->b_num);
3427 * function to free ALL cards (ports)
3429 void mISDNport_close_all(void)
3431 /* free all ports */
3432 while(mISDNport_first)
3433 mISDNport_close(mISDNport_first);
3437 * free only one port
3439 void mISDNport_close(struct mISDNport *mISDNport)
3441 struct mISDNport **mISDNportp;
3443 class PmISDN *isdnport;
3447 unsigned char buf[32];
3451 /* remove all port instance that are linked to this mISDNport */
3455 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3457 isdnport = (class PmISDN *)port;
3458 if (isdnport->p_m_mISDNport)
3460 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3467 /* only if we are already part of interface */
3468 if (mISDNport->ifport)
3470 start_trace(mISDNport->portnum,
3471 mISDNport->ifport->interface,
3481 /* free bchannels */
3483 while(i < mISDNport->b_num)
3486 if (mISDNport->b_socket[i] > -1)
3488 if (mISDNport->b_addr[i])
3491 _bchannel_destroy(mISDNport, i);
3492 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3498 /* close layer 3, if open and purge upqueue */
3501 close_layer3(mISDNport->ml3);
3502 mqueue_purge(&mISDNport->upqueue);
3505 /* free ressources of port */
3506 msg_queue_purge(&mISDNport->downqueue);
3509 if (mISDNport->ntmode)
3511 nst = &mISDNport->nst;
3512 if (nst->manager) /* to see if initialized */
3514 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");
3515 cleanup_Isdnl3(nst);
3516 cleanup_Isdnl2(nst);
3519 msg_queue_purge(&nst->down_queue);
3520 if (nst->phd_down_msg)
3521 FREE(nst->phd_down_msg, 0);
3525 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3526 if (mISDNport->d_stid)
3528 if (mISDNport->upper_id)
3529 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3533 /* remove from list */
3534 mISDNportp = &mISDNport_first;
3537 if (*mISDNportp == mISDNport)
3539 *mISDNportp = (*mISDNportp)->next;
3543 mISDNportp = &((*mISDNportp)->next);
3547 FATAL("mISDNport not in list\n");
3549 FREE(mISDNport, sizeof(struct mISDNport));
3556 * global function to show all available isdn ports
3558 void mISDN_port_info(void)
3562 int useable, nt, te, pri, bri, pots;
3564 struct mISDN_devinfo devinfo;
3568 sock = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3571 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3575 /* get number of stacks */
3577 ret = ioctl(sock, IMGETCOUNT, &ii);
3580 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3585 unsigned char buff[1025];
3586 iframe_t *frm = (iframe_t *)buff;
3587 stack_info_t *stinf;
3591 if ((device = mISDN_open()) < 0)
3593 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));
3597 /* get number of stacks */
3599 ii = mISDN_get_stack_count(device);
3604 printf("Found no card. Please be sure to load card drivers.\n");
3608 /* loop the number of cards and get their info */
3611 nt = te = bri = pri = pots = 0;
3616 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
3619 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3623 /* output the port info */
3624 printf("Port %2d name='%s': ", i, devinfo.name);
3625 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3630 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3635 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3640 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3646 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3653 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3659 if ((te || nt) && (bri || pri || pots))
3662 if (te && nt && bri)
3663 printf("TE/NT-mode BRI S/T (for phone lines & phones)");
3664 if (te && !nt && bri)
3665 printf("TE-mode BRI S/T (for phone lines)");
3666 if (nt && !te && bri)
3667 printf("NT-mode BRI S/T (for phones)");
3668 if (te && nt && pri)
3669 printf("TE/NT-mode PRI E1 (for phone lines & E1 devices)");
3670 if (te && !nt && pri)
3671 printf("TE-mode PRI E1 (for phone lines)");
3672 if (nt && !te && pri)
3673 printf("NT-mode PRI E1 (for E1 devices)");
3674 if (te && nt && pots)
3675 printf("FXS/FXO POTS (for analog lines & phones)");
3676 if (te && !nt && pots)
3677 printf("FXS POTS (for analog lines)");
3678 if (nt && !te && pots)
3679 printf("FXO POTS (for analog phones)");
3683 printf("\n -> Analog interfaces are not supported.");
3687 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3691 printf(" - %d B-channels\n", devinfo.nrbchan);
3693 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3696 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3699 stinf = (stack_info_t *)&frm->data.p;
3701 /* output the port info */
3702 printf("Port %2d: ", i);
3703 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3705 case ISDN_PID_L0_TE_S0:
3709 printf("TE-mode BRI S/T interface line (for phone lines)");
3711 case ISDN_PID_L0_NT_S0:
3715 printf("NT-mode BRI S/T interface port (for phones)");
3717 case ISDN_PID_L0_TE_E1:
3721 printf("TE-mode PRI E1 interface line (for phone lines)");
3723 case ISDN_PID_L0_NT_E1:
3727 printf("NT-mode PRI E1 interface port (for E1 devices)");
3731 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3737 if (stinf->pid.protocol[1] == 0)
3740 printf(" -> Missing layer 1 NT-mode protocol.\n");
3743 while(p <= MAX_LAYER_NR) {
3744 if (stinf->pid.protocol[p])
3747 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3754 printf(" -> Interface is Point-To-Point (PRI).\n");
3756 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3761 if (stinf->pid.protocol[1] == 0)
3764 printf(" -> Missing layer 1 protocol.\n");
3766 if (stinf->pid.protocol[2] == 0)
3769 printf(" -> Missing layer 2 protocol.\n");
3771 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3773 printf(" -> Interface is Poin-To-Point.\n");
3775 if (stinf->pid.protocol[3] == 0)
3778 printf(" -> Missing layer 3 protocol.\n");
3781 printf(" -> Protocol: ");
3782 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3784 case ISDN_PID_L3_DSS1USER:
3785 printf("DSS1 (Euro ISDN)");
3790 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3795 while(p <= MAX_LAYER_NR) {
3796 if (stinf->pid.protocol[p])
3799 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3804 printf(" - %d B-channels\n", stinf->childcnt);
3808 printf(" * Port NOT useable for LCR\n");
3810 printf("--------\n");
3821 if ((ret = mISDN_close(device)))
3822 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3828 * enque data from upper buffer
3830 void PmISDN::txfromup(unsigned char *data, int length)
3833 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3834 struct mISDNhead *hh = (struct mISDNhead *)buf;
3837 if (p_m_b_index < 0)
3839 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
3842 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3843 iframe_t *frm = (iframe_t *)buf;
3845 if (p_m_b_index < 0)
3847 if (!p_m_mISDNport->b_addr[p_m_b_index])
3851 /* check if high priority tones exist
3852 * ignore data in this case
3854 if (p_tone_name[0] || p_m_crypt_msg_loops)
3857 /* preload procedure
3858 * if transmit buffer in DSP module is empty,
3859 * preload it to DSP_LOAD to prevent jitter gaps.
3861 if (p_m_load==0 && ISDN_LOAD>0)
3864 hh->prim = PH_DATA_REQ;
3866 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3867 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
3869 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3871 frm->prim = DL_DATA | REQUEST;
3872 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3874 frm->len = ISDN_LOAD;
3875 memset(buf+mISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
3876 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+ISDN_LOAD, TIMEOUT_1SEC);
3878 p_m_load += ISDN_LOAD;
3881 /* drop if load would exceed ISDN_MAXLOAD
3882 * this keeps the delay not too high
3884 if (p_m_load+length > ISDN_MAXLOAD)
3887 /* make and send frame */
3889 hh->prim = PH_DATA_REQ;
3891 memcpy(buf+MISDN_HEADER_LEN, data, length);
3892 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3894 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
3896 frm->prim = DL_DATA | REQUEST;
3897 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3900 memcpy(buf+mISDN_HEADER_LEN, data, length);
3901 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);