1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
16 #include <sys/ioctl.h>
17 #include <sys/types.h>
21 #include <netinet/udp.h>
22 #include <netinet/in.h>
24 #include <sys/socket.h>
26 #include <linux/mISDNif.h>
35 #ifndef ISDN_PID_L4_B_USER
36 #define ISDN_PID_L4_B_USER 0x440000ff
39 /* list of mISDN ports */
40 struct mISDNport *mISDNport_first;
42 /* noise randomizer */
43 unsigned char mISDN_rand[256];
44 int mISDN_rand_count = 0;
49 int mISDN_initialize(void)
51 /* try to open raw socket to check kernel */
52 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
55 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
59 /* initialize stuff of the NT lib */
60 if (options.deb & DEBUG_STACK)
62 global_debug = 0xffffffff & ~DBGM_MSG;
63 // global_debug = DBGM_L3DATA;
65 global_debug = DBGM_MAN;
66 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
67 if (options.deb & DEBUG_LOG)
68 mISDN_debug_init(global_debug, debug_log, debug_log, debug_log);
70 mISDN_debug_init(global_debug, NULL, NULL, NULL);
73 init_layer3(4); // buffer of 4
78 void mISDN_deinitialize(void)
88 int entity = 0; /* used for udevice */
89 int mISDNdevice = -1; /* the device handler and port list */
91 int mISDN_initialize(void)
94 unsigned char buff[1025];
95 iframe_t *frm = (iframe_t *)buff;
98 /* initialize stuff of the NT lib */
99 if (options.deb & DEBUG_STACK)
101 global_debug = 0xffffffff & ~DBGM_MSG;
102 // global_debug = DBGM_L3DATA;
104 global_debug = DBGM_MAN;
105 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
106 if (options.deb & DEBUG_LOG)
107 debug_init(global_debug, debug_log, debug_log, debug_log);
109 debug_init(global_debug, NULL, NULL, NULL);
112 /* open mISDNdevice if not already open */
118 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));
122 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
124 /* create entity for layer 3 TE-mode */
125 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
126 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
127 if (ret < (int)mISDN_HEADER_LEN)
130 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
132 entity = frm->dinfo & 0xffff;
135 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
140 void mISDN_deinitialize(void)
142 unsigned char buff[1025];
146 if (mISDNdevice >= 0)
149 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
151 mISDN_close(mISDNdevice);
153 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
161 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
163 p_m_mISDNport = mISDNport;
164 p_m_portnum = mISDNport->portnum;
171 p_m_txvol = p_m_rxvol = 0;
179 p_m_dtmf = !mISDNport->ifport->nodtmf;
182 p_m_remote_ref = 0; /* channel shall be exported to given remote */
183 p_m_remote_id = 0; /* channel shall be exported to given remote */
191 p_m_crypt_listen = 0;
192 p_m_crypt_msg_loops = 0;
193 p_m_crypt_msg_loops = 0;
194 p_m_crypt_msg_len = 0;
195 p_m_crypt_msg[0] = '\0';
196 p_m_crypt_msg_current = 0;
197 p_m_crypt_key[0] = '\0';
198 p_m_crypt_key_len = 0;
199 p_m_crypt_listen = 0;
200 p_m_crypt_listen_state = 0;
201 p_m_crypt_listen_len = 0;
202 p_m_crypt_listen_msg[0] = '\0';
203 p_m_crypt_listen_crc = 0;
205 /* if any channel requested by constructor */
206 if (channel == CHANNEL_ANY)
208 /* reserve channel */
210 mISDNport->b_reserved++;
213 /* reserve channel */
214 if (channel > 0) // only if constructor was called with a channel resevation
215 seize_bchannel(channel, exclusive);
217 /* we increase the number of objects: */
219 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
228 struct message *message;
230 /* remove bchannel relation */
236 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
237 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
238 message->param.disconnectinfo.cause = 16;
239 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
240 message_put(message);
241 /* remove from list */
242 free_epointlist(p_epointlist);
245 /* we decrease the number of objects: */
246 p_m_mISDNport->use--;
247 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
254 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
256 /* init trace with given values */
257 start_trace(mISDNport?mISDNport->portnum:0,
258 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
259 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
260 port?port->p_dialinginfo.id:NULL,
263 port?port->p_serial:0,
271 static struct isdn_message {
275 {"TIMEOUT", CC_TIMEOUT},
277 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
278 {"PROCEEDING", CC_PROCEEDING},
279 {"ALERTING", CC_ALERTING},
280 {"CONNECT", CC_CONNECT},
281 {"CONNECT RES", CC_CONNECT},
282 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
283 {"DISCONNECT", CC_DISCONNECT},
284 {"RELEASE", CC_RELEASE},
285 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
286 {"INFORMATION", CC_INFORMATION},
287 {"PROGRESS", CC_PROGRESS},
288 {"NOTIFY", CC_NOTIFY},
289 {"SUSPEND", CC_SUSPEND},
290 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
291 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
292 {"RESUME", CC_RESUME},
293 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
294 {"RESUME_REJ", CC_RESUME_REJECT},
296 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
297 {"HOLD_REJ", CC_HOLD_REJECT},
298 {"RETRIEVE", CC_RETRIEVE},
299 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
300 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
301 {"FACILITY", CC_FACILITY},
302 {"STATUS", CC_STATUS},
303 {"RESTART", CC_RESTART},
304 {"RELEASE_CR", CC_RELEASE_CR},
305 {"NEW_CR", CC_NEW_CR},
306 {"DL_ESTABLISH", DL_ESTABLISH},
307 {"DL_RELEASE", DL_RELEASE},
308 {"PH_ACTIVATE", PH_ACTIVATE},
309 {"PH_DEACTIVATE", PH_DEACTIVATE},
313 static char *isdn_prim[4] = {
319 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
322 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
324 /* select message and primitive text */
326 while(isdn_message[i].name)
328 if (isdn_message[i].value == (prim&0xffffff00))
330 SCPY(msgtext, isdn_message[i].name);
335 SCAT(msgtext, isdn_prim[prim&0x00000003]);
338 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
342 if (mISDNport->ntmode)
344 if (direction == DIRECTION_OUT)
345 SCAT(msgtext, " N->U");
347 SCAT(msgtext, " N<-U");
350 if (direction == DIRECTION_OUT)
351 SCAT(msgtext, " U->N");
353 SCAT(msgtext, " U<-N");
358 /* init trace with given values */
359 start_trace(mISDNport?mISDNport->portnum:0,
360 mISDNport?mISDNport->ifport->interface:NULL,
361 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
362 port?port->p_dialinginfo.id:NULL,
365 port?port->p_serial:0,
371 * send control information to the channel (dsp-module)
373 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
376 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
377 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
378 unsigned long *d = buffer+MISDN_HEADER_LEN;
381 ctrl->prim = PH_CONTROL_REQ;
385 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
387 PERROR("Failed to send to socket %d\n", handle);
389 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
390 iframe_t *ctrl = (iframe_t *)buffer;
391 unsigned long *d = (unsigned long *)&ctrl->data.p;
393 ctrl->prim = PH_CONTROL | REQUEST;
394 ctrl->addr = handle | FLG_MSG_DOWN;
396 ctrl->len = sizeof(int)*2;
399 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
401 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
402 if (c1 == CMX_CONF_JOIN)
403 add_trace(trace_name, NULL, "0x%08x", trace_value);
405 add_trace(trace_name, NULL, "%d", trace_value);
409 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
412 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
413 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
414 unsigned long *d = buffer+MISDN_HEADER_LEN;
417 ctrl->prim = PH_CONTROL_REQ;
420 memcpy(d, c2, c2_len);
421 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
423 PERROR("Failed to send to socket %d\n", handle);
425 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
426 iframe_t *ctrl = (iframe_t *)buffer;
427 unsigned long *d = (unsigned long *)&ctrl->data.p;
429 ctrl->prim = PH_CONTROL | REQUEST;
430 ctrl->addr = handle | FLG_MSG_DOWN;
432 ctrl->len = sizeof(int)+c2_len;
434 memcpy(d, c2, c2_len);
435 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
437 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
438 add_trace(trace_name, NULL, "%d", trace_value);
444 * subfunction for bchannel_event
447 static int _bchannel_create(struct mISDNport *mISDNport, int i)
449 unsigned char buff[1024];
452 unsigned long on = 1;
453 struct sockadd_mISDN addr;
455 if (mISDNport->b_socket[i])
457 PERROR("Error: Socket already created for index %d\n", i);
462 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
463 if (mISDNport->b_socket[i])
465 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
469 /* set nonblocking io */
470 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
473 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
474 close(mISDNport->b_socket[i]);
475 mISDNport->b_socket[i] = -1;
479 /* bind socket to bchannel */
480 addr.family = AF_ISDN;
481 addr.dev = mISDNport->port-1;
482 addr.channel = i+1+(i>=15);
483 ret = bind(di->bchan, (struct sockaddr *)&addr, sizeof(addr));
486 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
487 close(mISDNport->b_socket[i]);
488 mISDNport->b_socket[i] = -1;
492 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
493 add_trace("channel", NULL, "%d", i+1+(i>=15));
494 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
500 if (!mISDNport->b_stid[i])
502 PERROR("Error: no stack for index %d\n", i);
505 if (mISDNport->b_addr[i])
507 PERROR("Error: stack already created for index %d\n", i);
511 /* create new layer */
512 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
513 memset(&li, 0, sizeof(li));
514 memset(&pid, 0, sizeof(pid));
517 li.st = mISDNport->b_stid[i];
518 UCPY(li.name, "B L4");
519 li.pid.layermask = ISDN_LAYER((4));
520 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
521 ret = mISDN_new_layer(mISDNdevice, &li);
525 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
528 mISDNport->b_addr[i] = li.id;
531 goto failed_new_layer;
533 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
535 /* create new stack */
536 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
537 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
538 pid.protocol[3] = ISDN_PID_L3_B_DSP;
539 pid.protocol[4] = ISDN_PID_L4_B_USER;
540 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
541 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
545 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
546 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
549 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
554 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
555 if (!mISDNport->b_addr[i])
557 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
558 add_trace("channel", NULL, "%d", i+1+(i>=15));
559 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
560 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
567 mISDNport->b_addr[i] = 0;
573 * subfunction for bchannel_event
574 * activate / deactivate request
576 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
579 struct mISDNhead act;
582 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
584 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
586 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
590 /* activate bchannel */
591 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
592 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
595 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
599 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
600 add_trace("channel", NULL, "%d", i+1+(i>=15));
606 * subfunction for bchannel_event
609 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
615 handle = mISDNport->b_socket[i];
617 unsigned long handle;
619 handle = mISDNport->b_addr[i];
621 port = mISDNport->b_port[i];
624 PERROR("bchannel index i=%d not associated with a port object\n", i);
628 /* set dsp features */
629 if (port->p_m_txdata)
630 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
632 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
634 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
636 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
638 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
640 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
642 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
644 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
645 // if (port->p_m_txmix)
646 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
648 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
650 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);
654 * subfunction for bchannel_event
657 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
660 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
661 add_trace("channel", NULL, "%d", i+1+(i>=15));
662 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
664 if (mISDNport->b_socket[i] > -1)
666 close(mISDNport->b_socket[i]);
667 mISDNport->b_socket[i] = -1;
670 unsigned char buff[1024];
672 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
673 add_trace("channel", NULL, "%d", i+1+(i>=15));
674 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
675 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
677 /* remove our stack only if set */
678 if (mISDNport->b_addr[i])
680 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
681 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
682 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
683 mISDNport->b_addr[i] = 0;
693 A bchannel goes through the following states in this order:
696 No one is using the bchannel.
697 It is available and not linked to Port class, nor reserved.
700 The bchannel stack is created and an activation request is sent.
701 It MAY be linked to Port class, but already unlinked due to Port class removal.
704 The bchannel is active and cofigured to the Port class needs.
705 Also it is linked to a Port class, otherwhise it would be deactivated.
707 - B_STATE_DEACTIVATING
708 The bchannel is in deactivating state, due to deactivation request.
709 It may be linked to a Port class, that likes to reactivate it.
713 After deactivating bchannel, and if not used, the bchannel becomes idle again.
715 Also the bchannel may be exported, but only if the state is or becomes idle:
718 The bchannel assignment has been sent to the remove application.
721 The bchannel assignment is acknowledged by the remote application.
724 The bchannel is re-imported by mISDN port object.
728 After re-importing bchannel, and if not used, the bchannel becomes idle again.
731 A bchannel can have the following events:
734 A bchannel is required by a Port class.
735 The bchannel shall be exported to the remote application.
738 The bchannel beomes active.
741 The bchannel is not required by Port class anymore
743 - B_EVENT_DEACTIVATED
744 The bchannel becomes inactive.
747 The bchannel is now used by remote application.
750 The bchannel is not used by remote application.
752 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
754 if an export request is receive by remote application, p_m_remote_* is set.
755 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.)
756 - set on export request from remote application (if port is assigned)
757 - set on channel use, if requested by remote application (p_m_remote_*)
758 - cleared on drop request
760 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
761 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
762 the bchannel import/export is acknowledged with stack given.
764 if exporting, b_remote_*[index] is set to the remote socket id.
765 if importing has been acknowledged. b_remote_*[index] is cleared.
770 * process bchannel events
771 * - mISDNport is a pointer to the port's structure
772 * - i is the index of the bchannel
773 * - event is the B_EVENT_* value
774 * - port is the PmISDN class pointer
776 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
778 class PmISDN *b_port = mISDNport->b_port[i];
779 int state = mISDNport->b_state[i];
780 unsigned long p_m_remote_ref = 0;
781 unsigned long p_m_remote_id = 0;
783 unsigned long handle = mISDNport->b_addr[i];
785 int handle = mISDNport->b_addr[i];
790 p_m_remote_id = b_port->p_m_remote_id;
791 p_m_remote_ref = b_port->p_m_remote_ref;
797 /* port must be linked in order to allow activation */
799 FATAL("bchannel must be linked to a Port class\n");
805 /* export bchannel */
806 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, handle);
807 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
808 add_trace("type", NULL, "assign");
810 add_trace("stack", "address", "%x", handle);
812 add_trace("socket", "id", "%d", handle);
815 state = B_STATE_EXPORTING;
816 mISDNport->b_remote_id[i] = p_m_remote_id;
817 mISDNport->b_remote_ref[i] = p_m_remote_ref;
820 /* create stack and send activation request */
821 if (_bchannel_create(mISDNport, i))
823 _bchannel_activate(mISDNport, i, 1);
824 state = B_STATE_ACTIVATING;
829 case B_STATE_ACTIVATING:
830 case B_STATE_EXPORTING:
831 /* do nothing, because it is already activating */
834 case B_STATE_DEACTIVATING:
835 case B_STATE_IMPORTING:
836 /* do nothing, because we must wait until we can reactivate */
840 /* problems that might ocurr:
841 * B_EVENT_USE is received when channel already in use.
842 * bchannel exported, but not freed by other port
844 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
848 case B_EVENT_EXPORTREQUEST:
849 /* special case where the bchannel is requested by remote */
852 PERROR("export request without remote channel set, please correct.\n");
858 /* in case, the bchannel is exported right after seize_bchannel */
859 /* export bchannel */
860 /* p_m_remote_id is set, when this event happens. */
861 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, handle);
862 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
863 add_trace("type", NULL, "assign");
865 add_trace("stack", "address", "%x", handle);
867 add_trace("socket", "id", "%d", handle);
870 state = B_STATE_EXPORTING;
871 mISDNport->b_remote_id[i] = p_m_remote_id;
872 mISDNport->b_remote_ref[i] = p_m_remote_ref;
875 case B_STATE_ACTIVATING:
876 case B_STATE_EXPORTING:
877 /* do nothing, because it is already activating */
880 case B_STATE_DEACTIVATING:
881 case B_STATE_IMPORTING:
882 /* do nothing, because we must wait until we can reactivate */
886 /* bchannel is active, so we deactivate */
887 _bchannel_activate(mISDNport, i, 0);
888 state = B_STATE_DEACTIVATING;
892 /* problems that might ocurr:
893 * ... when channel already in use.
894 * bchannel exported, but not freed by other port
896 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
900 case B_EVENT_ACTIVATED:
903 case B_STATE_ACTIVATING:
904 if (b_port && !p_m_remote_id)
906 /* bchannel is active and used by Port class, so we configure bchannel */
907 _bchannel_configure(mISDNport, i);
908 state = B_STATE_ACTIVE;
911 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
912 _bchannel_activate(mISDNport, i, 0);
913 state = B_STATE_DEACTIVATING;
918 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
922 case B_EVENT_EXPORTED:
925 case B_STATE_EXPORTING:
926 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
928 /* remote export done */
929 state = B_STATE_REMOTE;
932 /* bchannel is now exported, but we need bchannel back
933 * OR bchannel is not used anymore
934 * OR bchannel has been exported to an obsolete ref,
935 * so reimport, to later export to new remote */
936 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, handle);
937 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
938 add_trace("type", NULL, "remove");
940 add_trace("stack", "address", "%x", handle);
942 add_trace("socket", "id", "%d", handle);
945 state = B_STATE_IMPORTING;
950 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
956 FATAL("bchannel must be linked to a Port class\n");
960 /* bchannel is idle due to an error, so we do nothing */
963 case B_STATE_ACTIVATING:
964 case B_STATE_EXPORTING:
965 /* do nothing because we must wait until bchanenl is active before deactivating */
969 /* bchannel is active, so we deactivate */
970 _bchannel_activate(mISDNport, i, 0);
971 state = B_STATE_DEACTIVATING;
975 /* bchannel is exported, so we re-import */
976 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, handle);
977 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
978 add_trace("type", NULL, "remove");
980 add_trace("stack", "address", "%x", handle);
982 add_trace("socket", "id", "%d", handle);
985 state = B_STATE_IMPORTING;
988 case B_STATE_DEACTIVATING:
989 case B_STATE_IMPORTING:
990 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
994 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
998 case B_EVENT_DEACTIVATED:
1002 /* ignore due to deactivation confirm after unloading */
1005 case B_STATE_DEACTIVATING:
1006 _bchannel_destroy(mISDNport, i);
1007 state = B_STATE_IDLE;
1010 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1013 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, handle);
1014 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1015 add_trace("type", NULL, "assign");
1017 add_trace("stack", "address", "%x", handle);
1019 add_trace("socket", "id", "%d", handle);
1022 state = B_STATE_EXPORTING;
1023 mISDNport->b_remote_id[i] = p_m_remote_id;
1024 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1027 if (_bchannel_create(mISDNport, i))
1029 _bchannel_activate(mISDNport, i, 1);
1030 state = B_STATE_ACTIVATING;
1037 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1041 case B_EVENT_IMPORTED:
1044 case B_STATE_IMPORTING:
1045 state = B_STATE_IDLE;
1046 mISDNport->b_remote_id[i] = 0;
1047 mISDNport->b_remote_ref[i] = 0;
1050 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1053 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, handle);
1054 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1055 add_trace("type", NULL, "assign");
1057 add_trace("stack", "address", "%x", handle);
1059 add_trace("socket", "id", "%d", handle);
1062 state = B_STATE_EXPORTING;
1063 mISDNport->b_remote_id[i] = p_m_remote_id;
1064 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1067 if (_bchannel_create(mISDNport, i))
1069 _bchannel_activate(mISDNport, i, 1);
1070 state = B_STATE_ACTIVATING;
1077 /* ignore, because not assigned */
1083 PERROR("Illegal event %d, please correct.\n", event);
1086 mISDNport->b_state[i] = state;
1093 * check for available channel and reserve+set it.
1094 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1095 * give exclusiv flag
1096 * returns -(cause value) or x = channel x or 0 = no channel
1097 * NOTE: no activation is done here
1099 int PmISDN::seize_bchannel(int channel, int exclusive)
1103 /* the channel is what we have */
1104 if (p_m_b_channel == channel)
1107 /* if channel already in use, release it */
1112 if (channel==CHANNEL_NO || channel==0)
1115 /* is channel in range ? */
1117 || (channel>p_m_mISDNport->b_num && channel<16)
1118 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1119 return(-6); /* channel unacceptable */
1121 /* request exclusive channel */
1122 if (exclusive && channel>0)
1124 i = channel-1-(channel>16);
1125 if (p_m_mISDNport->b_port[i])
1126 return(-44); /* requested channel not available */
1130 /* ask for channel */
1133 i = channel-1-(channel>16);
1134 if (p_m_mISDNport->b_port[i] == NULL)
1138 /* search for channel */
1140 while(i < p_m_mISDNport->b_num)
1142 if (!p_m_mISDNport->b_port[i])
1144 channel = i+1+(i>=15);
1149 return(-34); /* no free channel */
1152 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1155 p_m_mISDNport->b_port[i] = this;
1157 p_m_b_channel = channel;
1158 p_m_b_exclusive = exclusive;
1160 /* reserve channel */
1164 p_m_mISDNport->b_reserved++;
1171 * drop reserved channel and unset it.
1172 * deactivation is also done
1174 void PmISDN::drop_bchannel(void)
1176 if (p_m_b_index < 0)
1179 /* unreserve channel */
1181 p_m_mISDNport->b_reserved--;
1188 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1190 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1191 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1192 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1195 p_m_b_exclusive = 0;
1198 /* process bchannel export/import message from join */
1199 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1201 class Endpoint *epoint;
1203 class PmISDN *isdnport;
1204 struct mISDNport *mISDNport;
1209 case BCHANNEL_REQUEST:
1210 /* find the port object for the join object ref */
1211 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1213 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1216 if (!epoint->ep_portlist)
1218 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1221 if (epoint->ep_portlist->next)
1223 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);
1225 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1227 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1230 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1232 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1234 isdnport = (class PmISDN *)port;
1237 if (isdnport->p_m_remote_id)
1239 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1242 mISDNport = isdnport->p_m_mISDNport;
1243 i = isdnport->p_m_b_index;
1244 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1245 add_trace("type", NULL, "export request");
1246 isdnport->p_m_remote_ref = joinremote->j_serial;
1247 isdnport->p_m_remote_id = joinremote->j_remote_id;
1248 if (mISDNport && i>=0)
1250 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1255 case BCHANNEL_ASSIGN_ACK:
1256 case BCHANNEL_REMOVE_ACK:
1257 /* find mISDNport for stack ID */
1258 mISDNport = mISDNport_first;
1262 ii = mISDNport->b_num;
1266 if (mISDNport->b_socket[i] == handle)
1268 if (mISDNport->b_addr[i] == handle)
1275 mISDNport = mISDNport->next;
1279 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1282 /* mISDNport may now be set or NULL */
1285 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1286 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1287 if (mISDNport && i>=0)
1288 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1292 PERROR("received wrong bchannel message type %d from remote\n", type);
1300 audio transmission procedure:
1301 -----------------------------
1304 three sources of audio transmission:
1305 - crypto-data high priority
1306 - tones high priority (also high)
1307 - remote-data low priority
1310 a variable that temporarily shows the number of samples elapsed since last transmission process.
1311 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1314 a variable that is increased whenever data is transmitted.
1315 it is decreased while time elapses. it stores the number of samples that
1316 are currently loaded to dsp module.
1317 since clock in dsp module is the same clock for user space process, these
1321 there are two levels:
1322 ISDN_LOAD will give the load that have to be kept in dsp.
1323 ISDN_MAXLOAD will give the maximum load before dropping.
1325 * procedure for low priority data
1326 see txfromup() for procedure
1327 in short: remote data is ignored during high priority tones
1329 * procedure for high priority data
1330 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1331 if no more data is available, load becomes empty again.
1334 0 ISDN_LOAD ISDN_MAXLOAD
1335 +--------------------+----------------------+
1337 +--------------------+----------------------+
1339 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1340 0 ISDN_LOAD ISDN_MAXLOAD
1341 +--------------------+----------------------+
1342 |TTTTTTTTTTTTTTTTTTTT| |
1343 +--------------------+----------------------+
1345 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1346 0 ISDN_LOAD ISDN_MAXLOAD
1347 +--------------------+----------------------+
1348 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1349 +--------------------+----------------------+
1352 int PmISDN::handler(void)
1354 struct message *message;
1358 if ((ret = Port::handler()))
1362 if (p_m_last_tv_sec)
1364 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1365 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1368 /* set clock of first process ever in this instance */
1369 p_m_last_tv_sec = now_tv.tv_sec;
1370 p_m_last_tv_msec = now_tv.tv_usec/1000;
1372 /* process only if we have a minimum of samples, to make packets not too small */
1373 if (elapsed >= ISDN_TRANSMIT)
1375 /* set clock of last process! */
1376 p_m_last_tv_sec = now_tv.tv_sec;
1377 p_m_last_tv_msec = now_tv.tv_usec/1000;
1380 if (elapsed < p_m_load)
1381 p_m_load -= elapsed;
1385 /* to send data, tone must be active OR crypt messages must be on */
1386 if ((p_tone_name[0] || p_m_crypt_msg_loops) && p_m_load < ISDN_LOAD)
1388 int tosend = ISDN_LOAD - p_m_load, length;
1390 unsigned char buf[MISDN_HEADER_LEN+tosend];
1391 struct mISDNhead *frm = (struct mISDNhead *)buf;
1392 unsigned long *d = buf+MISDN_HEADER_LEN;
1394 unsigned char buf[mISDN_HEADER_LEN+tosend];
1395 iframe_t *frm = (iframe_t *)buf;
1396 unsigned char *p = buf+mISDN_HEADER_LEN;
1399 /* copy crypto loops */
1400 while (p_m_crypt_msg_loops && tosend)
1402 /* how much do we have to send */
1403 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1406 if (length > tosend)
1409 /* copy message (part) to buffer */
1410 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1413 p_m_crypt_msg_current += length;
1414 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1417 p_m_crypt_msg_current = 0;
1418 p_m_crypt_msg_loops--;
1426 if (p_tone_name[0] && tosend)
1428 tosend -= read_audio(p, tosend);
1433 frm->prim = DL_DATA_REQ;
1435 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1437 PERROR("Failed to send to socket %d\n", handle);
1439 frm->prim = DL_DATA | REQUEST;
1440 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1442 frm->len = ISDN_LOAD - p_m_load - tosend;
1445 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1446 p_m_load += frm->len;
1450 // NOTE: deletion is done by the child class
1452 /* handle timeouts */
1455 if (p_m_timer+p_m_timeout < now_d)
1457 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1459 /* send timeout to endpoint */
1460 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1461 message->param.state = p_state;
1462 message_put(message);
1467 return(0); /* nothing done */
1472 * whenever we get audio data from bchannel, we process it here
1475 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1477 unsigned long cont = *((unsigned long *)data);
1479 void PmISDN::bchannel_receive(iframe_t *frm)
1482 unsigned long cont = *((unsigned long *)&frm->data.p);
1483 unsigned char *data =(unsigned char *)&frm->data.p;
1485 unsigned char *data_temp;
1486 unsigned long length_temp;
1487 struct message *message;
1492 if (hh->prim == PH_CONTROL_IND)
1494 if (frm->prim == (PH_CONTROL | INDICATION))
1499 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1502 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1504 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1505 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1507 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1508 message->param.dtmf = cont & DTMF_TONE_MASK;
1509 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1510 message_put(message);
1516 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1517 add_trace("DSP-CRYPT", NULL, "error");
1519 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1520 message->param.crypt.type = CC_ERROR_IND;
1521 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1522 message_put(message);
1526 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1527 add_trace("DSP-CRYPT", NULL, "ok");
1529 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1530 message->param.crypt.type = CC_ACTBF_CONF;
1531 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1532 message_put(message);
1538 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1539 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1543 record((unsigned char *)(cont+1), len - 4, 1); // from up
1547 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1548 add_trace("unknown", NULL, "0x%x", cont);
1554 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1556 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1558 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1560 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1565 /* calls will not process any audio data unless
1566 * the call is connected OR interface features audio during call setup.
1568 //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);
1569 #ifndef DEBUG_COREBRIDGE
1570 if (p_state!=PORT_STATE_CONNECT
1571 && !p_m_mISDNport->earlyb)
1575 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1578 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1584 record(data, len, 0); // from down
1586 /* randomize and listen to crypt message if enabled */
1587 if (p_m_crypt_listen)
1589 /* the noisy randomizer */
1593 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1595 cryptman_listen_bch(data, len);
1600 /* send data to epoint */
1601 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1607 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1608 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1609 memcpy(message->param.data.data, data_temp, message->param.data.len);
1610 message_put(message);
1611 if (length_temp <= sizeof(message->param.data.data))
1613 data_temp += sizeof(message->param.data.data);
1614 length_temp -= sizeof(message->param.data.data);
1623 void PmISDN::set_echotest(int echo)
1625 if (p_m_echo != echo)
1628 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1630 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1632 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_echo?CMX_ECHO_ON:CMX_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1634 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);
1642 void PmISDN::set_tone(char *dir, char *tone)
1648 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1655 /* check if we NOT really have to use a dsp-tone */
1656 if (!options.dsptones)
1660 if (p_m_b_index >= 0)
1661 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1663 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1665 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1667 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1671 Port::set_tone(dir, tone);
1677 /* now we USE dsp-tone, convert name */
1678 else if (!strcmp(tone, "dialtone"))
1680 switch(options.dsptones) {
1681 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1682 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1683 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1685 } else if (!strcmp(tone, "dialpbx"))
1687 switch(options.dsptones) {
1688 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1689 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1690 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1692 } else if (!strcmp(tone, "ringing"))
1694 switch(options.dsptones) {
1695 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1696 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1697 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1699 } else if (!strcmp(tone, "ringpbx"))
1701 switch(options.dsptones) {
1702 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1703 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1704 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1706 } else if (!strcmp(tone, "busy"))
1709 switch(options.dsptones) {
1710 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1711 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1712 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1714 } else if (!strcmp(tone, "release"))
1717 switch(options.dsptones) {
1718 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1719 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1720 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1722 } else if (!strcmp(tone, "cause_10"))
1724 else if (!strcmp(tone, "cause_11"))
1726 else if (!strcmp(tone, "cause_22"))
1728 switch(options.dsptones) {
1729 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1730 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1731 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1733 } else if (!strncmp(tone, "cause_", 6))
1734 id = TONE_SPECIAL_INFO;
1738 /* if we have a tone that is not supported by dsp */
1739 if (id==TONE_OFF && tone[0])
1747 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1748 if (p_m_b_index >= 0)
1749 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1751 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1753 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);
1756 /* turn user-space tones off in cases of no tone OR dsp tone */
1757 Port::set_tone("",NULL);
1761 /* MESSAGE_mISDNSIGNAL */
1762 //extern struct message *dddebug;
1763 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1765 switch(param->mISDNsignal.message)
1767 case mISDNSIGNAL_VOLUME:
1768 if (p_m_txvol != param->mISDNsignal.txvol)
1770 p_m_txvol = param->mISDNsignal.txvol;
1771 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1772 if (p_m_b_index >= 0)
1773 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1775 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
1777 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
1780 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1781 if (p_m_rxvol != param->mISDNsignal.rxvol)
1783 p_m_rxvol = param->mISDNsignal.rxvol;
1784 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1785 if (p_m_b_index >= 0)
1786 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1788 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
1790 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
1793 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1796 case mISDNSIGNAL_CONF:
1797 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1798 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1799 if (p_m_conf != param->mISDNsignal.conf)
1801 p_m_conf = param->mISDNsignal.conf;
1802 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1803 if (p_m_b_index >= 0)
1804 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1806 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (p_m_conf)?CMX_CONF_JOIN:CMX_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
1808 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);
1811 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1812 /* we must set, even if currently tone forbids conf */
1813 p_m_conf = param->mISDNsignal.conf;
1814 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1817 case mISDNSIGNAL_JOINDATA:
1818 if (p_m_joindata != param->mISDNsignal.joindata)
1820 p_m_joindata = param->mISDNsignal.joindata;
1821 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1823 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1826 case mISDNSIGNAL_DELAY:
1827 if (p_m_delay != param->mISDNsignal.delay)
1829 p_m_delay = param->mISDNsignal.delay;
1830 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1831 if (p_m_b_index >= 0)
1832 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1834 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?CMX_DELAY:CMX_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1836 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);
1839 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1843 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1848 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1850 struct message *message;
1852 switch(param->crypt.type)
1854 case CC_ACTBF_REQ: /* activate blowfish */
1856 p_m_crypt_key_len = param->crypt.len;
1857 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1859 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1860 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1861 message->param.crypt.type = CC_ERROR_IND;
1862 message_put(message);
1865 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1867 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1868 if (p_m_b_index >= 0)
1869 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1871 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_crypt?BF_ENABLE_KEY:BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1873 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);
1877 case CC_DACT_REQ: /* deactivate session encryption */
1882 case CR_LISTEN_REQ: /* start listening to messages */
1883 p_m_crypt_listen = 1;
1884 p_m_crypt_listen_state = 0;
1887 case CR_UNLISTEN_REQ: /* stop listening to messages */
1888 p_m_crypt_listen = 0;
1891 case CR_MESSAGE_REQ: /* send message */
1892 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1893 if (!p_m_crypt_msg_len)
1895 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1898 p_m_crypt_msg_current = 0; /* reset */
1899 p_m_crypt_msg_loops = 3; /* enable */
1901 /* disable txmix, or we get corrupt data due to audio process */
1902 if (p_m_txmix && p_m_b_index>=0)
1904 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1906 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1908 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1915 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1921 * endpoint sends messages to the port
1923 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1925 if (Port::message_epoint(epoint_id, message_id, param))
1930 case MESSAGE_DATA: /* tx-data from upper layer */
1931 txfromup(param->data.data, param->data.len);
1934 case MESSAGE_mISDNSIGNAL: /* user command */
1935 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1936 message_mISDNsignal(epoint_id, message_id, param);
1939 case MESSAGE_CRYPT: /* crypt control command */
1940 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1941 message_crypt(epoint_id, message_id, param);
1950 * main loop for processing messages from mISDN device
1952 int mISDN_handler(void)
1957 struct mISDNport *mISDNport;
1958 class PmISDN *isdnport;
1961 mISDNuser_head_t *hh;
1964 /* the que avoids loopbacks when replying to stack after receiving
1966 mISDNport = mISDNport_first;
1969 /* process turning on/off rx */
1971 while(i < mISDNport->b_num)
1973 isdnport=mISDNport->b_port[i];
1976 /* call bridges in user space OR crypto OR recording */
1977 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1979 /* rx IS required */
1980 if (isdnport->p_m_rxoff)
1983 isdnport->p_m_rxoff = 0;
1984 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1985 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1986 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1991 /* rx NOT required */
1992 if (!isdnport->p_m_rxoff)
1995 isdnport->p_m_rxoff = 1;
1996 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1997 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1998 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2003 if (isdnport->p_record)
2005 /* txdata IS required */
2006 if (!isdnport->p_m_txdata)
2009 isdnport->p_m_txdata = 1;
2010 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2011 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2012 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2017 /* txdata NOT required */
2018 if (isdnport->p_m_txdata)
2021 isdnport->p_m_txdata = 0;
2022 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2023 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2024 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2032 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2034 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2035 mISDNport->l1timeout = 0;
2038 if (mISDNport->l2establish)
2040 if (now-mISDNport->l2establish > 5)
2042 if (mISDNport->ntmode)
2044 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2045 time(&mISDNport->l2establish);
2047 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2048 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2051 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2052 time(&mISDNport->l2establish);
2055 act.prim = DL_ESTABLISH | REQUEST;
2056 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2059 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2061 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
2066 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2068 if (mISDNport->ntmode)
2070 hh = (mISDNuser_head_t *)dmsg->data;
2071 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);
2072 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2076 frm = (iframe_t *)dmsg->data;
2077 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2078 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2079 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);
2080 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2085 mISDNport = mISDNport->next;
2088 /* no device, no read */
2089 if (mISDNdevice < 0)
2092 /* get message from kernel */
2093 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2095 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2099 if (errno == EAGAIN)
2101 FATAL("Failed to do mISDN_read()\n");
2106 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2110 frm = (iframe_t *)msg->data;
2115 case MGR_DELLAYER | CONFIRM:
2116 case MGR_INITTIMER | CONFIRM:
2117 case MGR_ADDTIMER | CONFIRM:
2118 case MGR_DELTIMER | CONFIRM:
2119 case MGR_REMOVETIMER | CONFIRM:
2124 /* handle timer events from mISDN for NT-stack
2125 * note: they do not associate with a stack */
2126 if (frm->prim == (MGR_TIMER | INDICATION))
2130 /* find mISDNport */
2131 mISDNport = mISDNport_first;
2135 if (mISDNport->ntmode)
2137 it = mISDNport->nst.tlist;
2141 if (it->id == (int)frm->addr)
2148 mISDNport = mISDNport->next;
2152 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2153 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2155 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2156 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2157 ret = it->function(it->data);
2160 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2165 /* find the mISDNport that belongs to the stack */
2166 mISDNport = mISDNport_first;
2169 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2171 mISDNport = mISDNport->next;
2175 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2180 if (!(frm->addr&FLG_CHILD_STACK))
2185 case MGR_SHORTSTATUS | INDICATION:
2186 case MGR_SHORTSTATUS | CONFIRM:
2187 switch(frm->dinfo) {
2188 case SSTATUS_L1_ACTIVATED:
2189 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2192 case SSTATUS_L1_DEACTIVATED:
2193 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2196 case SSTATUS_L2_ESTABLISHED:
2197 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
2200 case SSTATUS_L2_RELEASED:
2201 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
2207 case PH_ACTIVATE | CONFIRM:
2208 case PH_ACTIVATE | INDICATION:
2209 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2211 if (mISDNport->ntmode)
2213 mISDNport->l1link = 1;
2214 setup_queue(mISDNport, 1);
2218 mISDNport->l1link = 1;
2219 setup_queue(mISDNport, 1);
2222 case PH_DEACTIVATE | CONFIRM:
2223 case PH_DEACTIVATE | INDICATION:
2224 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2226 if (mISDNport->ntmode)
2228 mISDNport->l1link = 0;
2229 setup_queue(mISDNport, 0);
2233 mISDNport->l1link = 0;
2234 setup_queue(mISDNport, 0);
2237 case PH_CONTROL | CONFIRM:
2238 case PH_CONTROL | INDICATION:
2239 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2242 case DL_ESTABLISH | INDICATION:
2243 case DL_ESTABLISH | CONFIRM:
2244 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2246 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2248 if (mISDNport->l2establish)
2250 mISDNport->l2establish = 0;
2251 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2253 mISDNport->l2link = 1;
2256 case DL_RELEASE | INDICATION:
2257 case DL_RELEASE | CONFIRM:
2258 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2260 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2262 mISDNport->l2link = 0;
2265 time(&mISDNport->l2establish);
2266 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2272 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);
2273 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2275 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2278 if (mISDNport->ntmode)
2280 /* l1-data enters the nt-mode library */
2281 nst = &mISDNport->nst;
2282 if (nst->l1_l2(nst, msg))
2287 /* l3-data is sent to pbx */
2288 if (stack2manager_te(mISDNport, msg))
2299 /* we don't care about confirms, we use rx data to sync tx */
2300 case PH_DATA | CONFIRM:
2301 case DL_DATA | CONFIRM:
2304 /* we receive audio data, we respond to it AND we send tones */
2305 case PH_DATA | INDICATION:
2306 case DL_DATA | INDICATION:
2307 case PH_CONTROL | INDICATION:
2309 while(i < mISDNport->b_num)
2311 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2315 if (i == mISDNport->b_num)
2317 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2320 if (mISDNport->b_port[i])
2322 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2323 mISDNport->b_port[i]->bchannel_receive(frm);
2325 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2328 case PH_ACTIVATE | INDICATION:
2329 case DL_ESTABLISH | INDICATION:
2330 case PH_ACTIVATE | CONFIRM:
2331 case DL_ESTABLISH | CONFIRM:
2332 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2334 while(i < mISDNport->b_num)
2336 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2340 if (i == mISDNport->b_num)
2342 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2345 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2348 case PH_DEACTIVATE | INDICATION:
2349 case DL_RELEASE | INDICATION:
2350 case PH_DEACTIVATE | CONFIRM:
2351 case DL_RELEASE | CONFIRM:
2352 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2354 while(i < mISDNport->b_num)
2356 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2360 if (i == mISDNport->b_num)
2362 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2365 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2369 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2380 * global function to add a new card (port)
2382 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2385 unsigned char buff[1025];
2386 iframe_t *frm = (iframe_t *)buff;
2387 struct mISDNport *mISDNport, **mISDNportp;
2389 int pri, bri, ports;
2392 struct mlayer3 *ml3;
2393 struct mISDN_devinfo devinfo;
2395 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2398 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2402 // interface_info_t ii;
2406 stack_info_t *stinf;
2408 /* query port's requirements */
2409 cnt = mISDN_get_stack_count(mISDNdevice);
2414 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2417 if (port>cnt || port<1)
2419 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2423 pri = bri = ports = nt = te = 0;
2425 devinfo.id = port - 1;
2426 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2429 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2432 /* output the port info */
2433 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2438 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2444 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2451 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2458 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2465 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2471 if (force_nt && !nt)
2473 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2478 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2481 if (pots && !bri && !pri)
2483 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2488 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2493 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2496 /* force nt, by turning off TE */
2499 /* if TE an NT is supported (and not forced to NT), turn off NT */
2503 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2506 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2509 stinf = (stack_info_t *)&frm->data.p;
2510 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2512 case ISDN_PID_L0_TE_S0:
2513 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2515 case ISDN_PID_L0_NT_S0:
2516 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2519 case ISDN_PID_L0_TE_E1:
2520 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2523 case ISDN_PID_L0_NT_E1:
2524 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2529 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2535 if (stinf->pid.protocol[1] == 0)
2537 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2540 if (stinf->pid.protocol[2])
2542 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2549 if (stinf->pid.protocol[1] == 0)
2551 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2554 if (stinf->pid.protocol[2] == 0)
2556 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2559 if (stinf->pid.protocol[3] == 0)
2561 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2565 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2567 case ISDN_PID_L3_DSS1USER:
2571 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2575 if (stinf->pid.protocol[4])
2577 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2583 /* add mISDNport structure */
2584 mISDNportp = &mISDNport_first;
2586 mISDNportp = &((*mISDNportp)->next);
2587 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2589 *mISDNportp = mISDNport;
2591 /* allocate ressources of port */
2594 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2599 prop |= FLG_FORCE_PTMP;
2600 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2601 if (!mISDNport->ml3)
2603 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2608 /* if ntmode, establish L1 to send the tei removal during start */
2609 if (mISDNport->ntmode)
2613 act.prim = PH_ACTIVATE | REQUEST;
2614 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2615 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2618 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2619 usleep(10000); /* to be sure, that l1 is up */
2623 SCPY(mISDNport->name, devinfo.name);
2624 mISDNport->b_num = devinfo.nrbchan;
2626 msg_queue_init(&mISDNport->downqueue);
2627 mISDNport->d_stid = stinf->id;
2628 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2629 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2631 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2635 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
2640 /* create layer intance */
2641 memset(&li, 0, sizeof(li));
2642 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
2645 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
2646 li.pid.layermask = ISDN_LAYER((nt?2:4));
2647 li.st = mISDNport->d_stid;
2648 ret = mISDN_new_layer(mISDNdevice, &li);
2651 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
2653 mISDNport_close(mISDNport);
2656 mISDNport->upper_id = li.id;
2657 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
2660 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2663 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2664 if (mISDNport->lower_id < 0)
2666 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2669 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2670 if (mISDNport->upper_id < 0)
2672 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2675 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2677 /* if ntmode, establish L1 to send the tei removal during start */
2678 if (mISDNport->ntmode)
2682 act.prim = PH_ACTIVATE | REQUEST;
2683 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2684 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2687 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2688 usleep(10000); /* to be sure, that l1 is up */
2691 /* create nst (nt-mode only) */
2694 mgr = &mISDNport->mgr;
2695 nst = &mISDNport->nst;
2700 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2701 nst->device = mISDNdevice;
2703 nst->d_stid = mISDNport->d_stid;
2705 nst->feature = FEATURE_NET_HOLD;
2707 nst->feature |= FEATURE_NET_PTP;
2709 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2712 while(i < mISDNport->b_num)
2714 nst->b_stid[i] = mISDNport->b_stid[i];
2718 nst->l1_id = mISDNport->lower_id;
2719 nst->l2_id = mISDNport->upper_id;
2722 msg_queue_init(&nst->down_queue);
2728 mISDNport->b_num = stinf->childcnt;
2730 mISDNport->portnum = port;
2731 mISDNport->ntmode = nt;
2732 mISDNport->pri = pri;
2733 mISDNport->ptp = ptp;
2734 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2736 while(i < mISDNport->b_num)
2738 mISDNport->b_state[i] = B_STATE_IDLE;
2740 mISDNport->b_socket = -1;
2742 mISDNport->b_stid[i] = stinf->child[i];
2743 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
2748 /* if te-mode, query state link */
2749 if (!mISDNport->ntmode)
2753 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2754 act.prim = MGR_SHORTSTATUS | REQUEST;
2755 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2756 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2758 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2760 /* if ptp AND te-mode, pull up the link */
2761 if (mISDNport->ptp && !mISDNport->ntmode)
2765 act.prim = DL_ESTABLISH | REQUEST;
2766 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2769 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2771 /* if ptp AND nt-mode, pull up the link */
2772 if (mISDNport->ptp && mISDNport->ntmode)
2776 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2777 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2780 /* initially, we assume that the link is down, exept for nt-ptmp */
2781 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2783 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2785 start_trace(mISDNport->portnum,
2793 add_trace("channels", NULL, "%d", mISDNport->b_num);
2800 * function to free ALL cards (ports)
2802 void mISDNport_close_all(void)
2804 /* free all ports */
2805 while(mISDNport_first)
2806 mISDNport_close(mISDNport_first);
2810 * free only one port
2812 void mISDNport_close(struct mISDNport *mISDNport)
2814 struct mISDNport **mISDNportp;
2816 class PmISDN *isdnport;
2818 unsigned char buf[32];
2821 /* remove all port instance that are linked to this mISDNport */
2825 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2827 isdnport = (class PmISDN *)port;
2828 if (isdnport->p_m_mISDNport)
2830 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2837 /* only if we are already part of interface */
2838 if (mISDNport->ifport)
2840 start_trace(mISDNport->portnum,
2841 mISDNport->ifport->interface,
2851 /* free bchannels */
2853 while(i < mISDNport->b_num)
2855 if (mISDNport->b_addr[i])
2857 _bchannel_destroy(mISDNport, i);
2858 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2864 close_layer3(mISDNport->ml3);
2866 /* free ressources of port */
2867 msg_queue_purge(&mISDNport->downqueue);
2870 if (mISDNport->ntmode)
2872 nst = &mISDNport->nst;
2873 if (nst->manager) /* to see if initialized */
2875 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");
2876 cleanup_Isdnl3(nst);
2877 cleanup_Isdnl2(nst);
2880 msg_queue_purge(&nst->down_queue);
2881 if (nst->phd_down_msg)
2882 FREE(nst->phd_down_msg, 0);
2886 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2887 if (mISDNport->d_stid)
2889 if (mISDNport->upper_id)
2890 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2894 /* remove from list */
2895 mISDNportp = &mISDNport_first;
2898 if (*mISDNportp == mISDNport)
2900 *mISDNportp = (*mISDNportp)->next;
2904 mISDNportp = &((*mISDNportp)->next);
2908 FATAL("mISDNport not in list\n");
2910 FREE(mISDNport, sizeof(struct mISDNport));
2917 * global function to show all available isdn ports
2919 void mISDN_port_info(void)
2923 int useable, nt, te, pri, bri, pots;
2924 unsigned char buff[1025];
2925 iframe_t *frm = (iframe_t *)buff;
2927 struct mISDN_devinfo devinfo;
2931 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
2934 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
2938 /* get number of stacks */
2940 ret = ioctl(socket, IMGETCOUNT, &ii);
2943 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2947 stack_info_t *stinf;
2951 if ((device = mISDN_open()) < 0)
2953 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));
2957 /* get number of stacks */
2959 ii = mISDN_get_stack_count(device);
2964 printf("Found no card. Please be sure to load card drivers.\n");
2968 /* loop the number of cards and get their info */
2971 nt = te = bri = pri = pots = 0;
2976 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2979 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2983 /* output the port info */
2984 printf("Port %2d name='%s': ", i, devinfo.name);
2985 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2990 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2996 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3003 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3010 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3017 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3023 if ((te || nt) && (bri || pri || ports))
3027 printf("TE-mode BRI S/T interface line (for phone lines)");
3029 printf("NT-mode BRI S/T interface port (for phones)");
3031 printf("TE-mode PRI E1 interface line (for phone lines)");
3033 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3035 printf("FXS POTS interface port (for analog lines)");
3037 printf("FXO POTS interface port (for analog phones)");
3041 printf("\n -> Analog interfaces are not supported.");
3045 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3049 printf(" - %d B-channels\n", devinfo.nfbchan);
3051 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3054 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3057 stinf = (stack_info_t *)&frm->data.p;
3059 /* output the port info */
3060 printf("Port %2d: ", i);
3061 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3063 case ISDN_PID_L0_TE_S0:
3067 printf("TE-mode BRI S/T interface line (for phone lines)");
3069 case ISDN_PID_L0_NT_S0:
3073 printf("NT-mode BRI S/T interface port (for phones)");
3075 case ISDN_PID_L0_TE_E1:
3079 printf("TE-mode PRI E1 interface line (for phone lines)");
3081 case ISDN_PID_L0_NT_E1:
3085 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3089 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3095 if (stinf->pid.protocol[1] == 0)
3098 printf(" -> Missing layer 1 NT-mode protocol.\n");
3101 while(p <= MAX_LAYER_NR) {
3102 if (stinf->pid.protocol[p])
3105 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3112 printf(" -> Interface is Point-To-Point (PRI).\n");
3114 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3119 if (stinf->pid.protocol[1] == 0)
3122 printf(" -> Missing layer 1 protocol.\n");
3124 if (stinf->pid.protocol[2] == 0)
3127 printf(" -> Missing layer 2 protocol.\n");
3129 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3131 printf(" -> Interface is Poin-To-Point.\n");
3133 if (stinf->pid.protocol[3] == 0)
3136 printf(" -> Missing layer 3 protocol.\n");
3139 printf(" -> Protocol: ");
3140 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3142 case ISDN_PID_L3_DSS1USER:
3143 printf("DSS1 (Euro ISDN)");
3148 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3153 while(p <= MAX_LAYER_NR) {
3154 if (stinf->pid.protocol[p])
3157 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3162 printf(" - %d B-channels\n", stinf->childcnt);
3166 printf(" * Port NOT useable for LCR\n");
3168 printf("--------\n");
3179 if ((ret = mISDN_close(device)))
3180 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3186 * enque data from upper buffer
3188 void PmISDN::txfromup(unsigned char *data, int length)
3190 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3191 iframe_t *frm = (iframe_t *)buf;
3193 /* configure frame */
3194 frm->prim = DL_DATA | REQUEST;
3195 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3198 /* check if high priority tones exist
3199 * ignore data in this case
3201 if (p_tone_name[0] || p_m_crypt_msg_loops)
3204 /* preload procedure
3205 * if transmit buffer in DSP module is empty,
3206 * preload it to DSP_LOAD to prevent jitter gaps.
3208 if (p_m_load==0 && ISDN_LOAD>0)
3211 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3212 frm->len = ISDN_LOAD;
3213 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3214 p_m_load += frm->len;
3217 /* drop if load would exceed ISDN_MAXLOAD
3218 * this keeps the delay not too high
3220 if (p_m_load+length > ISDN_MAXLOAD)
3223 /* load data to buffer
3225 memcpy(buf+mISDN_HEADER_LEN, data, length);
3227 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3228 p_m_load += frm->len;