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>
31 #include <mISDNuser/net_l2.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 portid = (mISDNport->portnum<<8) + i+1+(i>=15);
785 unsigned long portid = 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, portid);
807 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
808 add_trace("type", NULL, "assign");
810 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
812 add_trace("socket", "id", "%d", portid);
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, portid);
862 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
863 add_trace("type", NULL, "assign");
865 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
867 add_trace("socket", "id", "%d", portid);
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, portid);
937 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
938 add_trace("type", NULL, "remove");
940 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
942 add_trace("socket", "id", "%d", portid);
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, portid);
977 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
978 add_trace("type", NULL, "remove");
980 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
982 add_trace("socket", "id", "%d", portid);
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, portid);
1014 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1015 add_trace("type", NULL, "assign");
1017 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1019 add_trace("socket", "id", "%d", portid);
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, portid);
1054 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1055 add_trace("type", NULL, "assign");
1057 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1059 add_trace("socket", "id", "%d", portid);
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 /* unreserve channel */
1178 p_m_mISDNport->b_reserved--;
1182 if (p_m_b_index < 0)
1187 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1189 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1190 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1191 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1194 p_m_b_exclusive = 0;
1197 /* process bchannel export/import message from join */
1198 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1200 class Endpoint *epoint;
1202 class PmISDN *isdnport;
1203 struct mISDNport *mISDNport;
1208 case BCHANNEL_REQUEST:
1209 /* find the port object for the join object ref */
1210 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1212 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1215 if (!epoint->ep_portlist)
1217 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1220 if (epoint->ep_portlist->next)
1222 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);
1224 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1226 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1229 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1231 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1233 isdnport = (class PmISDN *)port;
1236 if (isdnport->p_m_remote_id)
1238 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1241 mISDNport = isdnport->p_m_mISDNport;
1242 i = isdnport->p_m_b_index;
1243 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1244 add_trace("type", NULL, "export request");
1245 isdnport->p_m_remote_ref = joinremote->j_serial;
1246 isdnport->p_m_remote_id = joinremote->j_remote_id;
1247 if (mISDNport && i>=0)
1249 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1254 case BCHANNEL_ASSIGN_ACK:
1255 case BCHANNEL_REMOVE_ACK:
1256 /* find mISDNport for stack ID */
1257 mISDNport = mISDNport_first;
1261 ii = mISDNport->b_num;
1265 if (mISDNport->b_socket[i] == handle)
1267 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1274 mISDNport = mISDNport->next;
1278 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1281 /* mISDNport may now be set or NULL */
1284 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1285 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1286 if (mISDNport && i>=0)
1287 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1291 PERROR("received wrong bchannel message type %d from remote\n", type);
1299 audio transmission procedure:
1300 -----------------------------
1303 three sources of audio transmission:
1304 - crypto-data high priority
1305 - tones high priority (also high)
1306 - remote-data low priority
1309 a variable that temporarily shows the number of samples elapsed since last transmission process.
1310 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1313 a variable that is increased whenever data is transmitted.
1314 it is decreased while time elapses. it stores the number of samples that
1315 are currently loaded to dsp module.
1316 since clock in dsp module is the same clock for user space process, these
1320 there are two levels:
1321 ISDN_LOAD will give the load that have to be kept in dsp.
1322 ISDN_MAXLOAD will give the maximum load before dropping.
1324 * procedure for low priority data
1325 see txfromup() for procedure
1326 in short: remote data is ignored during high priority tones
1328 * procedure for high priority data
1329 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1330 if no more data is available, load becomes empty again.
1333 0 ISDN_LOAD ISDN_MAXLOAD
1334 +--------------------+----------------------+
1336 +--------------------+----------------------+
1338 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1339 0 ISDN_LOAD ISDN_MAXLOAD
1340 +--------------------+----------------------+
1341 |TTTTTTTTTTTTTTTTTTTT| |
1342 +--------------------+----------------------+
1344 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1345 0 ISDN_LOAD ISDN_MAXLOAD
1346 +--------------------+----------------------+
1347 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1348 +--------------------+----------------------+
1351 int PmISDN::handler(void)
1353 struct message *message;
1357 if ((ret = Port::handler()))
1361 if (p_m_last_tv_sec)
1363 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1364 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1367 /* set clock of first process ever in this instance */
1368 p_m_last_tv_sec = now_tv.tv_sec;
1369 p_m_last_tv_msec = now_tv.tv_usec/1000;
1371 /* process only if we have a minimum of samples, to make packets not too small */
1372 if (elapsed >= ISDN_TRANSMIT)
1374 /* set clock of last process! */
1375 p_m_last_tv_sec = now_tv.tv_sec;
1376 p_m_last_tv_msec = now_tv.tv_usec/1000;
1379 if (elapsed < p_m_load)
1380 p_m_load -= elapsed;
1384 /* to send data, tone must be active OR crypt messages must be on */
1385 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1386 && (p_m_load < ISDN_LOAD)
1387 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1389 int tosend = ISDN_LOAD - p_m_load, length;
1391 unsigned char buf[MISDN_HEADER_LEN+tosend];
1392 struct mISDNhead *frm = (struct mISDNhead *)buf;
1393 unsigned long *d = buf+MISDN_HEADER_LEN;
1395 unsigned char buf[mISDN_HEADER_LEN+tosend];
1396 iframe_t *frm = (iframe_t *)buf;
1397 unsigned char *p = buf+mISDN_HEADER_LEN;
1400 /* copy crypto loops */
1401 while (p_m_crypt_msg_loops && tosend)
1403 /* how much do we have to send */
1404 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1407 if (length > tosend)
1410 /* copy message (part) to buffer */
1411 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1414 p_m_crypt_msg_current += length;
1415 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1418 p_m_crypt_msg_current = 0;
1419 p_m_crypt_msg_loops--;
1420 // puts("eine loop weniger");
1428 if (p_tone_name[0] && tosend)
1430 tosend -= read_audio(p, tosend);
1435 frm->prim = DL_DATA_REQ;
1437 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1439 PERROR("Failed to send to socket %d\n", handle);
1441 frm->prim = DL_DATA | REQUEST;
1442 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1444 frm->len = ISDN_LOAD - p_m_load - tosend;
1447 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1448 p_m_load += frm->len;
1452 // NOTE: deletion is done by the child class
1454 /* handle timeouts */
1457 if (p_m_timer+p_m_timeout < now_d)
1459 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1461 /* send timeout to endpoint */
1462 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1463 message->param.state = p_state;
1464 message_put(message);
1469 return(0); /* nothing done */
1474 * whenever we get audio data from bchannel, we process it here
1477 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1479 unsigned long cont = *((unsigned long *)data);
1481 void PmISDN::bchannel_receive(iframe_t *frm)
1484 unsigned long cont = *((unsigned long *)&frm->data.p);
1485 unsigned char *data =(unsigned char *)&frm->data.p;
1487 unsigned char *data_temp;
1488 unsigned long length_temp;
1489 struct message *message;
1494 if (hh->prim == PH_CONTROL_IND)
1496 if (frm->prim == (PH_CONTROL | INDICATION))
1501 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1504 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1506 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1507 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1509 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1510 message->param.dtmf = cont & DTMF_TONE_MASK;
1511 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1512 message_put(message);
1518 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1519 add_trace("DSP-CRYPT", NULL, "error");
1521 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1522 message->param.crypt.type = CC_ERROR_IND;
1523 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1524 message_put(message);
1528 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1529 add_trace("DSP-CRYPT", NULL, "ok");
1531 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1532 message->param.crypt.type = CC_ACTBF_CONF;
1533 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1534 message_put(message);
1538 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1539 add_trace("unknown", NULL, "0x%x", cont);
1545 if (hh->prim == PH_SIGNAL_IND)
1547 if (frm->prim == (PH_SIGNAL | INDICATION))
1555 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1556 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1559 /* see below (same condition) */
1560 if (p_state!=PORT_STATE_CONNECT
1561 && !p_m_mISDNport->tones)
1563 // printf(".");fflush(stdout);return;
1565 record(data, len, 1); // from up
1569 chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
1570 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1576 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1578 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1580 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1582 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1586 /* calls will not process any audio data unless
1587 * the call is connected OR interface features audio during call setup.
1589 //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);
1590 #ifndef DEBUG_COREBRIDGE
1591 if (p_state!=PORT_STATE_CONNECT
1592 && !p_m_mISDNport->tones)
1596 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1599 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1605 record(data, len, 0); // from down
1607 /* randomize and listen to crypt message if enabled */
1608 if (p_m_crypt_listen)
1610 /* the noisy randomizer */
1614 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1616 cryptman_listen_bch(data, len);
1621 /* send data to epoint */
1622 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1628 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1629 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1630 memcpy(message->param.data.data, data_temp, message->param.data.len);
1631 message_put(message);
1632 if (length_temp <= sizeof(message->param.data.data))
1634 data_temp += sizeof(message->param.data.data);
1635 length_temp -= sizeof(message->param.data.data);
1644 void PmISDN::set_echotest(int echo)
1646 if (p_m_echo != echo)
1649 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1651 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1653 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);
1655 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);
1663 void PmISDN::set_tone(char *dir, char *tone)
1669 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1676 /* check if we NOT really have to use a dsp-tone */
1677 if (!options.dsptones)
1681 if (p_m_b_index >= 0)
1682 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1684 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1686 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1688 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1692 Port::set_tone(dir, tone);
1698 /* now we USE dsp-tone, convert name */
1699 else if (!strcmp(tone, "dialtone"))
1701 switch(options.dsptones) {
1702 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1703 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1704 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1706 } else if (!strcmp(tone, "dialpbx"))
1708 switch(options.dsptones) {
1709 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1710 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1711 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1713 } else if (!strcmp(tone, "ringing"))
1715 switch(options.dsptones) {
1716 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1717 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1718 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1720 } else if (!strcmp(tone, "ringpbx"))
1722 switch(options.dsptones) {
1723 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1724 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1725 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1727 } else if (!strcmp(tone, "busy"))
1730 switch(options.dsptones) {
1731 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1732 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1733 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1735 } else if (!strcmp(tone, "release"))
1738 switch(options.dsptones) {
1739 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1740 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1741 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1743 } else if (!strcmp(tone, "cause_10"))
1745 else if (!strcmp(tone, "cause_11"))
1747 else if (!strcmp(tone, "cause_22"))
1749 switch(options.dsptones) {
1750 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1751 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1752 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1754 } else if (!strncmp(tone, "cause_", 6))
1755 id = TONE_SPECIAL_INFO;
1759 /* if we have a tone that is not supported by dsp */
1760 if (id==TONE_OFF && tone[0])
1768 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1769 if (p_m_b_index >= 0)
1770 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1772 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);
1774 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);
1777 /* turn user-space tones off in cases of no tone OR dsp tone */
1778 Port::set_tone("",NULL);
1782 /* MESSAGE_mISDNSIGNAL */
1783 //extern struct message *dddebug;
1784 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1786 switch(param->mISDNsignal.message)
1788 case mISDNSIGNAL_VOLUME:
1789 if (p_m_txvol != param->mISDNsignal.txvol)
1791 p_m_txvol = param->mISDNsignal.txvol;
1792 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1793 if (p_m_b_index >= 0)
1794 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1796 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);
1798 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);
1801 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1802 if (p_m_rxvol != param->mISDNsignal.rxvol)
1804 p_m_rxvol = param->mISDNsignal.rxvol;
1805 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1806 if (p_m_b_index >= 0)
1807 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1809 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);
1811 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);
1814 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1817 case mISDNSIGNAL_CONF:
1818 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1819 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1820 if (p_m_conf != param->mISDNsignal.conf)
1822 p_m_conf = param->mISDNsignal.conf;
1823 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1824 if (p_m_b_index >= 0)
1825 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1827 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);
1829 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);
1832 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1833 /* we must set, even if currently tone forbids conf */
1834 p_m_conf = param->mISDNsignal.conf;
1835 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1838 case mISDNSIGNAL_JOINDATA:
1839 if (p_m_joindata != param->mISDNsignal.joindata)
1841 p_m_joindata = param->mISDNsignal.joindata;
1842 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1844 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1847 case mISDNSIGNAL_DELAY:
1848 if (p_m_delay != param->mISDNsignal.delay)
1850 p_m_delay = param->mISDNsignal.delay;
1851 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1852 if (p_m_b_index >= 0)
1853 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1855 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);
1857 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);
1860 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1864 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1869 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1871 struct message *message;
1873 switch(param->crypt.type)
1875 case CC_ACTBF_REQ: /* activate blowfish */
1877 p_m_crypt_key_len = param->crypt.len;
1878 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1880 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1881 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1882 message->param.crypt.type = CC_ERROR_IND;
1883 message_put(message);
1886 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1888 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1889 if (p_m_b_index >= 0)
1890 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1892 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);
1894 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);
1898 case CC_DACT_REQ: /* deactivate session encryption */
1903 case CR_LISTEN_REQ: /* start listening to messages */
1904 p_m_crypt_listen = 1;
1905 p_m_crypt_listen_state = 0;
1908 case CR_UNLISTEN_REQ: /* stop listening to messages */
1909 p_m_crypt_listen = 0;
1912 case CR_MESSAGE_REQ: /* send message */
1913 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1914 if (!p_m_crypt_msg_len)
1916 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1919 p_m_crypt_msg_current = 0; /* reset */
1920 p_m_crypt_msg_loops = 6; /* enable */
1922 /* disable txmix, or we get corrupt data due to audio process */
1923 if (p_m_txmix && p_m_b_index>=0)
1925 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1927 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1929 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1936 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1942 * endpoint sends messages to the port
1944 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1946 if (Port::message_epoint(epoint_id, message_id, param))
1951 case MESSAGE_DATA: /* tx-data from upper layer */
1952 txfromup(param->data.data, param->data.len);
1955 case MESSAGE_mISDNSIGNAL: /* user command */
1956 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1957 message_mISDNsignal(epoint_id, message_id, param);
1960 case MESSAGE_CRYPT: /* crypt control command */
1961 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1962 message_crypt(epoint_id, message_id, param);
1971 * main loop for processing messages from mISDN
1974 int mISDN_handler(void)
1977 struct mISDNport *mISDNport;
1978 class PmISDN *isdnport;
1980 char buffer[2048+MISDN_HEADER_LEN];
1981 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1983 /* process all ports */
1984 mISDNport = mISDNport_first;
1987 /* process all bchannels */
1989 while(i < mISDNport->b_num)
1991 /* handle port of bchannel */
1992 isdnport=mISDNport->b_port[i];
1995 /* call bridges in user space OR crypto OR recording */
1996 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1998 /* rx IS required */
1999 if (isdnport->p_m_rxoff)
2002 isdnport->p_m_rxoff = 0;
2003 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2004 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2005 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2010 /* rx NOT required */
2011 if (!isdnport->p_m_rxoff)
2014 isdnport->p_m_rxoff = 1;
2015 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2016 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2017 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2022 if (isdnport->p_record)
2024 /* txdata IS required */
2025 if (!isdnport->p_m_txdata)
2028 isdnport->p_m_txdata = 1;
2029 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2030 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2031 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2036 /* txdata NOT required */
2037 if (isdnport->p_m_txdata)
2040 isdnport->p_m_txdata = 0;
2041 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2042 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2043 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2049 /* handle message from bchannel */
2050 if (mISDNport->b_stack[i] > -1)
2052 ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
2053 if (ret >= MISDN_HEADER_LEN)
2058 /* we don't care about confirms, we use rx data to sync tx */
2063 /* we receive audio data, we respond to it AND we send tones */
2067 case PH_CONTROL_IND:
2068 if (mISDNport->b_port[i])
2069 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2071 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_stack[i]);
2074 case PH_ACTIVATE_IND:
2075 case DL_ESTABLISH_IND:
2076 case PH_ACTIVATE_CONF:
2077 case DL_ESTABLISH_CONF:
2078 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2079 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2082 case PH_DEACTIVATE_IND:
2083 case DL_RELEASE_IND:
2084 case PH_DEACTIVATE_CONF:
2085 case DL_RELEASE_CONF:
2086 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2087 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2091 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], msg->len);
2095 if (ret < 0 && errno != EWOULDBLOCK)
2096 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2103 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2105 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2106 mISDNport->l1timeout = 0;
2109 /* layer 2 establish timer */
2110 if (mISDNport->l2establish)
2112 if (now-mISDNport->l2establish > 5)
2115 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2116 mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2117 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ, DIRECTION_OUT);
2124 mISDNport = mISDNport->next;
2127 /* if we received at least one b-frame, we will return 1 */
2131 int mISDN_handler(void)
2134 struct mISDNport *mISDNport;
2135 class PmISDN *isdnport;
2140 mISDNuser_head_t *hh;
2143 /* the que avoids loopbacks when replying to stack after receiving
2145 mISDNport = mISDNport_first;
2148 /* process turning on/off rx */
2150 while(i < mISDNport->b_num)
2152 isdnport=mISDNport->b_port[i];
2155 /* call bridges in user space OR crypto OR recording */
2156 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2158 /* rx IS required */
2159 if (isdnport->p_m_rxoff)
2162 isdnport->p_m_rxoff = 0;
2163 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2164 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2165 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2170 /* rx NOT required */
2171 if (!isdnport->p_m_rxoff)
2174 isdnport->p_m_rxoff = 1;
2175 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2176 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2177 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2182 if (isdnport->p_record)
2184 /* txdata IS required */
2185 if (!isdnport->p_m_txdata)
2188 isdnport->p_m_txdata = 1;
2189 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2190 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2191 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2196 /* txdata NOT required */
2197 if (isdnport->p_m_txdata)
2200 isdnport->p_m_txdata = 0;
2201 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2202 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2203 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2211 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2213 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2214 mISDNport->l1timeout = 0;
2217 if (mISDNport->l2establish)
2219 if (now-mISDNport->l2establish > 5)
2221 if (mISDNport->ntmode)
2223 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2224 time(&mISDNport->l2establish);
2226 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2227 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2232 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2233 time(&mISDNport->l2establish);
2235 act.prim = DL_ESTABLISH | REQUEST;
2236 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2239 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2241 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
2246 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2248 if (mISDNport->ntmode)
2250 hh = (mISDNuser_head_t *)dmsg->data;
2251 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);
2252 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2256 frm = (iframe_t *)dmsg->data;
2257 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2258 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2259 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);
2260 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2265 mISDNport = mISDNport->next;
2268 /* no device, no read */
2269 if (mISDNdevice < 0)
2272 /* get message from kernel */
2273 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2275 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2279 if (errno == EAGAIN)
2281 FATAL("Failed to do mISDN_read()\n");
2286 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2290 frm = (iframe_t *)msg->data;
2295 case MGR_DELLAYER | CONFIRM:
2296 case MGR_INITTIMER | CONFIRM:
2297 case MGR_ADDTIMER | CONFIRM:
2298 case MGR_DELTIMER | CONFIRM:
2299 case MGR_REMOVETIMER | CONFIRM:
2304 /* handle timer events from mISDN for NT-stack
2305 * note: they do not associate with a stack */
2306 if (frm->prim == (MGR_TIMER | INDICATION))
2310 /* find mISDNport */
2311 mISDNport = mISDNport_first;
2315 if (mISDNport->ntmode)
2317 it = mISDNport->nst.tlist;
2321 if (it->id == (int)frm->addr)
2328 mISDNport = mISDNport->next;
2332 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2333 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2335 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2336 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2337 ret = it->function(it->data);
2340 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2345 /* find the mISDNport that belongs to the stack */
2346 mISDNport = mISDNport_first;
2349 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2351 mISDNport = mISDNport->next;
2355 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2360 if (!(frm->addr&FLG_CHILD_STACK))
2365 case MGR_SHORTSTATUS | INDICATION:
2366 case MGR_SHORTSTATUS | CONFIRM:
2367 switch(frm->dinfo) {
2368 case SSTATUS_L1_ACTIVATED:
2369 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2372 case SSTATUS_L1_DEACTIVATED:
2373 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2376 case SSTATUS_L2_ESTABLISHED:
2377 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
2380 case SSTATUS_L2_RELEASED:
2381 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
2387 case PH_ACTIVATE | CONFIRM:
2388 case PH_ACTIVATE | INDICATION:
2389 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2391 if (mISDNport->ntmode)
2393 mISDNport->l1link = 1;
2394 setup_queue(mISDNport, 1);
2398 mISDNport->l1link = 1;
2399 setup_queue(mISDNport, 1);
2402 case PH_DEACTIVATE | CONFIRM:
2403 case PH_DEACTIVATE | INDICATION:
2404 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2406 if (mISDNport->ntmode)
2408 mISDNport->l1link = 0;
2409 setup_queue(mISDNport, 0);
2413 mISDNport->l1link = 0;
2414 setup_queue(mISDNport, 0);
2417 case PH_CONTROL | CONFIRM:
2418 case PH_CONTROL | INDICATION:
2419 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2422 case DL_ESTABLISH | INDICATION:
2423 case DL_ESTABLISH | CONFIRM:
2424 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2426 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2428 if (mISDNport->l2establish)
2430 mISDNport->l2establish = 0;
2431 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2433 mISDNport->l2link = 1;
2436 case DL_RELEASE | INDICATION:
2437 case DL_RELEASE | CONFIRM:
2438 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2440 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2442 mISDNport->l2link = 0;
2445 time(&mISDNport->l2establish);
2446 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2452 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);
2453 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2455 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2458 if (mISDNport->ntmode)
2460 /* l1-data enters the nt-mode library */
2461 nst = &mISDNport->nst;
2462 if (nst->l1_l2(nst, msg))
2467 /* l3-data is sent to pbx */
2468 if (stack2manager_te(mISDNport, msg))
2479 /* we don't care about confirms, we use rx data to sync tx */
2480 case PH_DATA | CONFIRM:
2481 case DL_DATA | CONFIRM:
2484 /* we receive audio data, we respond to it AND we send tones */
2485 case PH_DATA | INDICATION:
2486 case DL_DATA | INDICATION:
2487 case PH_CONTROL | INDICATION:
2488 case PH_SIGNAL | INDICATION:
2490 while(i < mISDNport->b_num)
2492 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2496 if (i == mISDNport->b_num)
2498 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2501 if (mISDNport->b_port[i])
2503 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2504 mISDNport->b_port[i]->bchannel_receive(frm);
2506 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2509 case PH_ACTIVATE | INDICATION:
2510 case DL_ESTABLISH | INDICATION:
2511 case PH_ACTIVATE | CONFIRM:
2512 case DL_ESTABLISH | CONFIRM:
2513 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2515 while(i < mISDNport->b_num)
2517 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2521 if (i == mISDNport->b_num)
2523 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2526 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2529 case PH_DEACTIVATE | INDICATION:
2530 case DL_RELEASE | INDICATION:
2531 case PH_DEACTIVATE | CONFIRM:
2532 case DL_RELEASE | CONFIRM:
2533 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2535 while(i < mISDNport->b_num)
2537 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2541 if (i == mISDNport->b_num)
2543 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2546 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2550 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2561 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2563 struct mISDNport *mISDNport = ml3->private;
2565 if (cmd == MT_ASSIGN)
2571 achtung MT_ASSIGN kommt hier an
2577 case MGR_SHORTSTATUS_IND:
2578 case MGR_SHORTSTATUS_CONF:
2579 switch(frm->dinfo) {
2580 case SSTATUS_L1_ACTIVATED:
2581 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE_IND, DIRECTION_IN);
2584 case SSTATUS_L1_DEACTIVATED:
2585 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE_IND, DIRECTION_IN);
2588 case SSTATUS_L2_ESTABLISHED:
2589 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_IND, DIRECTION_IN);
2592 case SSTATUS_L2_RELEASED:
2593 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_IND, DIRECTION_IN);
2599 case PH_ACTIVATE_CONF:
2600 case PH_ACTIVATE_IND:
2601 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2604 mISDNport->l1link = 1;
2606 if (mISDNport->ntmode)
2607 setup_queue(mISDNport, 1);
2611 case PH_DEACTIVATE | CONFIRM:
2612 case PH_DEACTIVATE | INDICATION:
2613 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2616 mISDNport->l1link = 0;
2617 raus mit der setup-queue, da dies im stack geschieht
2619 if (mISDNport->ntmode)
2620 setup_queue(mISDNport, 0);
2624 case PH_CONTROL_CONFIRM:
2625 case PH_CONTROL_INDICATION:
2626 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2629 case DL_ESTABLISH_IND:
2630 case DL_ESTABLISH_CONF:
2631 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2633 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2635 if (mISDNport->l2establish)
2637 mISDNport->l2establish = 0;
2638 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2640 mISDNport->l2link = 1;
2643 case DL_RELEASE_IND:
2644 case DL_RELEASE_CONF:
2645 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2648 mISDNport->l2link = 0;
2651 time(&mISDNport->l2establish);
2652 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2657 /* l3-data is sent to LCR */
2658 message_from_mlayer3(mISDNport, cmd, pid, l3m);
2674 * global function to add a new card (port)
2676 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2679 unsigned char buff[1025];
2680 iframe_t *frm = (iframe_t *)buff;
2681 struct mISDNport *mISDNport, **mISDNportp;
2683 int pri, bri, ports;
2686 struct mlayer3 *ml3;
2687 struct mISDN_devinfo devinfo;
2689 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2692 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2696 // interface_info_t ii;
2700 stack_info_t *stinf;
2702 /* query port's requirements */
2703 cnt = mISDN_get_stack_count(mISDNdevice);
2708 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2711 if (port>cnt || port<1)
2713 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2717 pri = bri = ports = nt = te = 0;
2719 devinfo.id = port - 1;
2720 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2723 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2726 /* output the port info */
2727 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2732 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2738 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2745 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2752 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2759 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2765 if (force_nt && !nt)
2767 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2772 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2775 if (pots && !bri && !pri)
2777 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2782 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2787 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2790 /* force nt, by turning off TE */
2793 /* if TE an NT is supported (and not forced to NT), turn off NT */
2797 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2800 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2803 stinf = (stack_info_t *)&frm->data.p;
2804 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2806 case ISDN_PID_L0_TE_S0:
2807 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2809 case ISDN_PID_L0_NT_S0:
2810 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2813 case ISDN_PID_L0_TE_E1:
2814 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2817 case ISDN_PID_L0_NT_E1:
2818 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2823 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2829 if (stinf->pid.protocol[1] == 0)
2831 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2834 if (stinf->pid.protocol[2])
2836 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2843 if (stinf->pid.protocol[1] == 0)
2845 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2848 if (stinf->pid.protocol[2] == 0)
2850 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2853 if (stinf->pid.protocol[3] == 0)
2855 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2859 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2861 case ISDN_PID_L3_DSS1USER:
2865 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2869 if (stinf->pid.protocol[4])
2871 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2877 /* add mISDNport structure */
2878 mISDNportp = &mISDNport_first;
2880 mISDNportp = &((*mISDNportp)->next);
2881 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2883 *mISDNportp = mISDNport;
2885 /* allocate ressources of port */
2888 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2893 prop |= FLG_FORCE_PTMP;
2894 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2895 if (!mISDNport->ml3)
2897 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2902 /* if ntmode, establish L1 to send the tei removal during start */
2903 if (mISDNport->ntmode)
2907 act.prim = PH_ACTIVATE | REQUEST;
2908 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2909 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2912 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2913 usleep(10000); /* to be sure, that l1 is up */
2917 SCPY(mISDNport->name, devinfo.name);
2918 mISDNport->b_num = devinfo.nrbchan;
2920 msg_queue_init(&mISDNport->downqueue);
2921 mISDNport->d_stid = stinf->id;
2922 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2923 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2925 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2929 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
2934 /* create layer intance */
2935 memset(&li, 0, sizeof(li));
2936 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
2939 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
2940 li.pid.layermask = ISDN_LAYER((nt?2:4));
2941 li.st = mISDNport->d_stid;
2942 ret = mISDN_new_layer(mISDNdevice, &li);
2945 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
2947 mISDNport_close(mISDNport);
2950 mISDNport->upper_id = li.id;
2951 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
2954 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2957 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2958 if (mISDNport->lower_id < 0)
2960 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2963 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2964 if (mISDNport->upper_id < 0)
2966 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2969 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2971 /* if ntmode, establish L1 to send the tei removal during start */
2972 if (mISDNport->ntmode)
2976 act.prim = PH_ACTIVATE | REQUEST;
2977 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2978 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2981 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2982 usleep(10000); /* to be sure, that l1 is up */
2985 /* create nst (nt-mode only) */
2988 mgr = &mISDNport->mgr;
2989 nst = &mISDNport->nst;
2994 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2995 nst->device = mISDNdevice;
2997 nst->d_stid = mISDNport->d_stid;
2999 nst->feature = FEATURE_NET_HOLD;
3001 nst->feature |= FEATURE_NET_PTP;
3003 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3006 while(i < mISDNport->b_num)
3008 nst->b_stid[i] = mISDNport->b_stid[i];
3012 nst->l1_id = mISDNport->lower_id;
3013 nst->l2_id = mISDNport->upper_id;
3016 msg_queue_init(&nst->down_queue);
3022 mISDNport->b_num = stinf->childcnt;
3024 mISDNport->portnum = port;
3025 mISDNport->ntmode = nt;
3026 mISDNport->pri = pri;
3027 mISDNport->ptp = ptp;
3028 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3030 while(i < mISDNport->b_num)
3032 mISDNport->b_state[i] = B_STATE_IDLE;
3034 mISDNport->b_socket = -1;
3036 mISDNport->b_stid[i] = stinf->child[i];
3037 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3042 /* if te-mode, query state link */
3043 if (!mISDNport->ntmode)
3047 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3048 act.prim = MGR_SHORTSTATUS | REQUEST;
3049 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3050 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3052 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3054 /* if ptp AND te-mode, pull up the link */
3055 if (mISDNport->ptp && !mISDNport->ntmode)
3059 act.prim = DL_ESTABLISH | REQUEST;
3060 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3063 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3065 /* if ptp AND nt-mode, pull up the link */
3066 if (mISDNport->ptp && mISDNport->ntmode)
3070 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3071 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3074 /* initially, we assume that the link is down, exept for nt-ptmp */
3075 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3077 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3079 start_trace(mISDNport->portnum,
3087 add_trace("channels", NULL, "%d", mISDNport->b_num);
3094 * function to free ALL cards (ports)
3096 void mISDNport_close_all(void)
3098 /* free all ports */
3099 while(mISDNport_first)
3100 mISDNport_close(mISDNport_first);
3104 * free only one port
3106 void mISDNport_close(struct mISDNport *mISDNport)
3108 struct mISDNport **mISDNportp;
3110 class PmISDN *isdnport;
3112 unsigned char buf[32];
3115 /* remove all port instance that are linked to this mISDNport */
3119 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3121 isdnport = (class PmISDN *)port;
3122 if (isdnport->p_m_mISDNport)
3124 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3131 /* only if we are already part of interface */
3132 if (mISDNport->ifport)
3134 start_trace(mISDNport->portnum,
3135 mISDNport->ifport->interface,
3145 /* free bchannels */
3147 while(i < mISDNport->b_num)
3149 if (mISDNport->b_addr[i])
3151 _bchannel_destroy(mISDNport, i);
3152 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3158 close_layer3(mISDNport->ml3);
3160 /* free ressources of port */
3161 msg_queue_purge(&mISDNport->downqueue);
3164 if (mISDNport->ntmode)
3166 nst = &mISDNport->nst;
3167 if (nst->manager) /* to see if initialized */
3169 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");
3170 cleanup_Isdnl3(nst);
3171 cleanup_Isdnl2(nst);
3174 msg_queue_purge(&nst->down_queue);
3175 if (nst->phd_down_msg)
3176 FREE(nst->phd_down_msg, 0);
3180 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3181 if (mISDNport->d_stid)
3183 if (mISDNport->upper_id)
3184 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3188 /* remove from list */
3189 mISDNportp = &mISDNport_first;
3192 if (*mISDNportp == mISDNport)
3194 *mISDNportp = (*mISDNportp)->next;
3198 mISDNportp = &((*mISDNportp)->next);
3202 FATAL("mISDNport not in list\n");
3204 FREE(mISDNport, sizeof(struct mISDNport));
3211 * global function to show all available isdn ports
3213 void mISDN_port_info(void)
3217 int useable, nt, te, pri, bri, pots;
3218 unsigned char buff[1025];
3219 iframe_t *frm = (iframe_t *)buff;
3221 struct mISDN_devinfo devinfo;
3225 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3228 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3232 /* get number of stacks */
3234 ret = ioctl(socket, IMGETCOUNT, &ii);
3237 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3241 stack_info_t *stinf;
3245 if ((device = mISDN_open()) < 0)
3247 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));
3251 /* get number of stacks */
3253 ii = mISDN_get_stack_count(device);
3258 printf("Found no card. Please be sure to load card drivers.\n");
3262 /* loop the number of cards and get their info */
3265 nt = te = bri = pri = pots = 0;
3270 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
3273 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3277 /* output the port info */
3278 printf("Port %2d name='%s': ", i, devinfo.name);
3279 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3284 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3290 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3297 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3304 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3311 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3317 if ((te || nt) && (bri || pri || ports))
3321 printf("TE-mode BRI S/T interface line (for phone lines)");
3323 printf("NT-mode BRI S/T interface port (for phones)");
3325 printf("TE-mode PRI E1 interface line (for phone lines)");
3327 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3329 printf("FXS POTS interface port (for analog lines)");
3331 printf("FXO POTS interface port (for analog phones)");
3335 printf("\n -> Analog interfaces are not supported.");
3339 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3343 printf(" - %d B-channels\n", devinfo.nfbchan);
3345 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3348 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3351 stinf = (stack_info_t *)&frm->data.p;
3353 /* output the port info */
3354 printf("Port %2d: ", i);
3355 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3357 case ISDN_PID_L0_TE_S0:
3361 printf("TE-mode BRI S/T interface line (for phone lines)");
3363 case ISDN_PID_L0_NT_S0:
3367 printf("NT-mode BRI S/T interface port (for phones)");
3369 case ISDN_PID_L0_TE_E1:
3373 printf("TE-mode PRI E1 interface line (for phone lines)");
3375 case ISDN_PID_L0_NT_E1:
3379 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3383 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3389 if (stinf->pid.protocol[1] == 0)
3392 printf(" -> Missing layer 1 NT-mode protocol.\n");
3395 while(p <= MAX_LAYER_NR) {
3396 if (stinf->pid.protocol[p])
3399 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3406 printf(" -> Interface is Point-To-Point (PRI).\n");
3408 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3413 if (stinf->pid.protocol[1] == 0)
3416 printf(" -> Missing layer 1 protocol.\n");
3418 if (stinf->pid.protocol[2] == 0)
3421 printf(" -> Missing layer 2 protocol.\n");
3423 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3425 printf(" -> Interface is Poin-To-Point.\n");
3427 if (stinf->pid.protocol[3] == 0)
3430 printf(" -> Missing layer 3 protocol.\n");
3433 printf(" -> Protocol: ");
3434 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3436 case ISDN_PID_L3_DSS1USER:
3437 printf("DSS1 (Euro ISDN)");
3442 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3447 while(p <= MAX_LAYER_NR) {
3448 if (stinf->pid.protocol[p])
3451 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3456 printf(" - %d B-channels\n", stinf->childcnt);
3460 printf(" * Port NOT useable for LCR\n");
3462 printf("--------\n");
3473 if ((ret = mISDN_close(device)))
3474 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3480 * enque data from upper buffer
3482 void PmISDN::txfromup(unsigned char *data, int length)
3485 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3486 struct mISDNhead *frm = (struct mISDNhead *)buf;
3488 if (p_m_b_index < 0)
3490 if (!p_m_mISDNport->b_socket[p_m_b_index])
3493 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3494 iframe_t *frm = (iframe_t *)buf;
3496 if (p_m_b_index < 0)
3498 if (!p_m_mISDNport->b_addr[p_m_b_index])
3502 /* check if high priority tones exist
3503 * ignore data in this case
3505 if (p_tone_name[0] || p_m_crypt_msg_loops)
3508 /* preload procedure
3509 * if transmit buffer in DSP module is empty,
3510 * preload it to DSP_LOAD to prevent jitter gaps.
3512 if (p_m_load==0 && ISDN_LOAD>0)
3515 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3516 frm->len = ISDN_LOAD;
3517 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3518 p_m_load += frm->len;
3521 /* drop if load would exceed ISDN_MAXLOAD
3522 * this keeps the delay not too high
3524 if (p_m_load+length > ISDN_MAXLOAD)
3527 /* make and send frame */
3529 frm->prim = DL_DATA_REQ;
3531 memcpy(buf+MISDN_HEADER_LEN, data, length);
3532 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3534 PERROR("Failed to send to socket %d\n", handle);
3536 frm->prim = DL_DATA | REQUEST;
3537 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3540 memcpy(buf+mISDN_HEADER_LEN, data, length);
3541 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);