1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
15 #include <sys/ioctl.h>
16 #include <sys/types.h>
20 #include <netinet/udp.h>
21 #include <netinet/in.h>
23 #include <sys/socket.h>
25 #include <linux/mISDNif.h>
30 #include <mISDNuser/net_l2.h>
37 #ifndef CMX_TXDATA_OFF
52 #warning *********************************************************
54 #warning * It seems that you use an older version of mISDN.
55 #warning * Features like voice recording or echo will not work.
56 #warning * Also it causes problems with loading modules and may
57 #warning * not work at all.
59 #warning * Please upgrade to newer version. A working version can
60 #warning * be found at www.linux-call-router.de.
62 #warning * Do not use the mISDN_1_1 branch, it does not have all
63 #warning * the features that are required. Use the master branch
66 #warning *********************************************************
71 #ifndef ISDN_PID_L4_B_USER
72 #define ISDN_PID_L4_B_USER 0x440000ff
75 /* list of mISDN ports */
76 struct mISDNport *mISDNport_first;
78 /* noise randomizer */
79 unsigned char mISDN_rand[256];
80 int mISDN_rand_count = 0;
85 int mISDN_initialize(void)
87 /* try to open raw socket to check kernel */
88 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
91 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
95 /* initialize stuff of the NT lib */
96 if (options.deb & DEBUG_STACK)
98 global_debug = 0xffffffff & ~DBGM_MSG;
99 // global_debug = DBGM_L3DATA;
101 global_debug = DBGM_MAN;
102 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
103 if (options.deb & DEBUG_LOG)
104 mISDN_debug_init(global_debug, debug_log, debug_log, debug_log);
106 mISDN_debug_init(global_debug, NULL, NULL, NULL);
109 init_layer3(4); // buffer of 4
114 void mISDN_deinitialize(void)
120 if (mISDNsocket > -1)
124 int entity = 0; /* used for udevice */
125 int mISDNdevice = -1; /* the device handler and port list */
127 int mISDN_initialize(void)
130 unsigned char buff[1025];
131 iframe_t *frm = (iframe_t *)buff;
134 /* initialize stuff of the NT lib */
135 if (options.deb & DEBUG_STACK)
137 global_debug = 0xffffffff & ~DBGM_MSG;
138 // global_debug = DBGM_L3DATA;
140 global_debug = DBGM_MAN;
141 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
142 if (options.deb & DEBUG_LOG)
143 debug_init(global_debug, debug_log, debug_log, debug_log);
145 debug_init(global_debug, NULL, NULL, NULL);
148 /* open mISDNdevice if not already open */
154 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));
158 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
160 /* create entity for layer 3 TE-mode */
161 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
162 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
163 if (ret < (int)mISDN_HEADER_LEN)
166 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
168 entity = frm->dinfo & 0xffff;
171 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
176 void mISDN_deinitialize(void)
178 unsigned char buff[1025];
182 if (mISDNdevice >= 0)
185 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
187 mISDN_close(mISDNdevice);
189 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
197 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
199 p_m_mISDNport = mISDNport;
200 p_m_portnum = mISDNport->portnum;
207 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
208 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
216 p_m_dtmf = !mISDNport->ifport->nodtmf;
219 p_m_remote_ref = 0; /* channel shall be exported to given remote */
220 p_m_remote_id = 0; /* channel shall be exported to given remote */
221 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
229 p_m_crypt_listen = 0;
230 p_m_crypt_msg_loops = 0;
231 p_m_crypt_msg_loops = 0;
232 p_m_crypt_msg_len = 0;
233 p_m_crypt_msg[0] = '\0';
234 p_m_crypt_msg_current = 0;
235 p_m_crypt_key_len = 0;
236 p_m_crypt_listen = 0;
237 p_m_crypt_listen_state = 0;
238 p_m_crypt_listen_len = 0;
239 p_m_crypt_listen_msg[0] = '\0';
240 p_m_crypt_listen_crc = 0;
241 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
243 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
244 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
248 /* if any channel requested by constructor */
249 if (channel == CHANNEL_ANY)
251 /* reserve channel */
253 mISDNport->b_reserved++;
256 /* reserve channel */
257 if (channel > 0) // only if constructor was called with a channel resevation
258 seize_bchannel(channel, exclusive);
260 /* we increase the number of objects: */
262 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
271 struct message *message;
273 /* remove bchannel relation */
279 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
280 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
281 message->param.disconnectinfo.cause = 16;
282 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
283 message_put(message);
284 /* remove from list */
285 free_epointlist(p_epointlist);
288 /* we decrease the number of objects: */
289 p_m_mISDNport->use--;
290 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
297 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
299 /* init trace with given values */
300 start_trace(mISDNport?mISDNport->portnum:0,
301 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
302 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
303 port?port->p_dialinginfo.id:NULL,
306 port?port->p_serial:0,
314 static struct isdn_message {
318 {"TIMEOUT", CC_TIMEOUT},
320 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
321 {"PROCEEDING", CC_PROCEEDING},
322 {"ALERTING", CC_ALERTING},
323 {"CONNECT", CC_CONNECT},
324 {"CONNECT RES", CC_CONNECT},
325 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
326 {"DISCONNECT", CC_DISCONNECT},
327 {"RELEASE", CC_RELEASE},
328 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
329 {"INFORMATION", CC_INFORMATION},
330 {"PROGRESS", CC_PROGRESS},
331 {"NOTIFY", CC_NOTIFY},
332 {"SUSPEND", CC_SUSPEND},
333 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
334 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
335 {"RESUME", CC_RESUME},
336 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
337 {"RESUME_REJ", CC_RESUME_REJECT},
339 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
340 {"HOLD_REJ", CC_HOLD_REJECT},
341 {"RETRIEVE", CC_RETRIEVE},
342 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
343 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
344 {"FACILITY", CC_FACILITY},
345 {"STATUS", CC_STATUS},
346 {"RESTART", CC_RESTART},
347 {"RELEASE_CR", CC_RELEASE_CR},
348 {"NEW_CR", CC_NEW_CR},
349 {"DL_ESTABLISH", DL_ESTABLISH},
350 {"DL_RELEASE", DL_RELEASE},
351 {"PH_ACTIVATE", PH_ACTIVATE},
352 {"PH_DEACTIVATE", PH_DEACTIVATE},
356 static char *isdn_prim[4] = {
362 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
365 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
367 /* select message and primitive text */
369 while(isdn_message[i].name)
371 if (isdn_message[i].value == (prim&0xffffff00))
373 SCPY(msgtext, isdn_message[i].name);
378 SCAT(msgtext, isdn_prim[prim&0x00000003]);
381 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
385 if (mISDNport->ntmode)
387 if (direction == DIRECTION_OUT)
388 SCAT(msgtext, " N->U");
390 SCAT(msgtext, " N<-U");
393 if (direction == DIRECTION_OUT)
394 SCAT(msgtext, " U->N");
396 SCAT(msgtext, " U<-N");
401 /* init trace with given values */
402 start_trace(mISDNport?mISDNport->portnum:0,
403 mISDNport?mISDNport->ifport->interface:NULL,
404 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
405 port?port->p_dialinginfo.id:NULL,
408 port?port->p_serial:0,
414 * send control information to the channel (dsp-module)
416 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
419 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
420 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
421 unsigned long *d = buffer+MISDN_HEADER_LEN;
424 ctrl->prim = PH_CONTROL_REQ;
428 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
430 PERROR("Failed to send to socket %d\n", handle);
432 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
433 iframe_t *ctrl = (iframe_t *)buffer;
434 unsigned long *d = (unsigned long *)&ctrl->data.p;
436 ctrl->prim = PH_CONTROL | REQUEST;
437 ctrl->addr = handle | FLG_MSG_DOWN;
439 ctrl->len = sizeof(int)*2;
442 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
444 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
445 if (c1 == CMX_CONF_JOIN)
446 add_trace(trace_name, NULL, "0x%08x", trace_value);
448 add_trace(trace_name, NULL, "%d", trace_value);
452 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)
455 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
456 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
457 unsigned long *d = buffer+MISDN_HEADER_LEN;
460 ctrl->prim = PH_CONTROL_REQ;
463 memcpy(d, c2, c2_len);
464 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
466 PERROR("Failed to send to socket %d\n", handle);
468 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
469 iframe_t *ctrl = (iframe_t *)buffer;
470 unsigned long *d = (unsigned long *)&ctrl->data.p;
472 ctrl->prim = PH_CONTROL | REQUEST;
473 ctrl->addr = handle | FLG_MSG_DOWN;
475 ctrl->len = sizeof(int)+c2_len;
477 memcpy(d, c2, c2_len);
478 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
480 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
481 add_trace(trace_name, NULL, "%d", trace_value);
487 * subfunction for bchannel_event
490 static int _bchannel_create(struct mISDNport *mISDNport, int i)
492 unsigned char buff[1024];
495 unsigned long on = 1;
496 struct sockadd_mISDN addr;
498 if (mISDNport->b_socket[i])
500 PERROR("Error: Socket already created for index %d\n", i);
505 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
506 if (mISDNport->b_socket[i] < 0)
508 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
512 /* set nonblocking io */
513 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
516 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
517 close(mISDNport->b_socket[i]);
518 mISDNport->b_socket[i] = -1;
522 /* bind socket to bchannel */
523 addr.family = AF_ISDN;
524 addr.dev = mISDNport->port-1;
525 addr.channel = i+1+(i>=15);
526 ret = bind(di->bchan, (struct sockaddr *)&addr, sizeof(addr));
529 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
530 close(mISDNport->b_socket[i]);
531 mISDNport->b_socket[i] = -1;
535 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
536 add_trace("channel", NULL, "%d", i+1+(i>=15));
537 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
543 if (!mISDNport->b_stid[i])
545 PERROR("Error: no stack for index %d\n", i);
548 if (mISDNport->b_addr[i])
550 PERROR("Error: stack already created for index %d\n", i);
554 /* create new layer */
555 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
556 memset(&li, 0, sizeof(li));
557 memset(&pid, 0, sizeof(pid));
560 li.st = mISDNport->b_stid[i];
561 UCPY(li.name, "B L4");
562 li.pid.layermask = ISDN_LAYER((4));
563 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
564 ret = mISDN_new_layer(mISDNdevice, &li);
568 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
571 mISDNport->b_addr[i] = li.id;
574 goto failed_new_layer;
576 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
578 /* create new stack */
579 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
580 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
581 pid.protocol[3] = ISDN_PID_L3_B_DSP;
582 pid.protocol[4] = ISDN_PID_L4_B_USER;
583 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
584 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
588 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
589 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
592 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
597 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
598 if (!mISDNport->b_addr[i])
600 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
601 add_trace("channel", NULL, "%d", i+1+(i>=15));
602 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
603 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
610 mISDNport->b_addr[i] = 0;
616 * subfunction for bchannel_event
617 * activate / deactivate request
619 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
622 struct mISDNhead act;
625 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
627 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
629 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
633 /* activate bchannel */
634 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
635 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
638 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
642 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
643 add_trace("channel", NULL, "%d", i+1+(i>=15));
649 * subfunction for bchannel_event
652 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
658 handle = mISDNport->b_socket[i];
660 unsigned long handle;
662 handle = mISDNport->b_addr[i];
664 port = mISDNport->b_port[i];
667 PERROR("bchannel index i=%d not associated with a port object\n", i);
671 /* set dsp features */
673 if (port->p_m_txdata)
674 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
676 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
678 if (port->p_m_tx_gain)
679 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
680 if (port->p_m_rx_gain)
681 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
683 if (port->p_m_pipeline[0])
684 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
687 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
689 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
691 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
693 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
694 // if (port->p_m_txmix)
695 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
697 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
699 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);
703 * subfunction for bchannel_event
706 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
709 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
710 add_trace("channel", NULL, "%d", i+1+(i>=15));
711 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
713 if (mISDNport->b_socket[i] > -1)
715 close(mISDNport->b_socket[i]);
716 mISDNport->b_socket[i] = -1;
719 unsigned char buff[1024];
721 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
722 add_trace("channel", NULL, "%d", i+1+(i>=15));
723 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
724 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
726 /* remove our stack only if set */
727 if (mISDNport->b_addr[i])
729 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
730 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
731 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
732 mISDNport->b_addr[i] = 0;
742 A bchannel goes through the following states in this order:
745 No one is using the bchannel.
746 It is available and not linked to Port class, nor reserved.
749 The bchannel stack is created and an activation request is sent.
750 It MAY be linked to Port class, but already unlinked due to Port class removal.
753 The bchannel is active and cofigured to the Port class needs.
754 Also it is linked to a Port class, otherwhise it would be deactivated.
756 - B_STATE_DEACTIVATING
757 The bchannel is in deactivating state, due to deactivation request.
758 It may be linked to a Port class, that likes to reactivate it.
762 After deactivating bchannel, and if not used, the bchannel becomes idle again.
764 Also the bchannel may be exported, but only if the state is or becomes idle:
767 The bchannel assignment has been sent to the remove application.
770 The bchannel assignment is acknowledged by the remote application.
773 The bchannel is re-imported by mISDN port object.
777 After re-importing bchannel, and if not used, the bchannel becomes idle again.
780 A bchannel can have the following events:
783 A bchannel is required by a Port class.
784 The bchannel shall be exported to the remote application.
787 The bchannel beomes active.
790 The bchannel is not required by Port class anymore
792 - B_EVENT_DEACTIVATED
793 The bchannel becomes inactive.
796 The bchannel is now used by remote application.
799 The bchannel is not used by remote application.
801 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
803 if an export request is receive by remote application, p_m_remote_* is set.
804 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.)
805 - set on export request from remote application (if port is assigned)
806 - set on channel use, if requested by remote application (p_m_remote_*)
807 - cleared on drop request
809 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
810 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
811 the bchannel import/export is acknowledged with stack given.
813 if exporting, b_remote_*[index] is set to the remote socket id.
814 if importing has been acknowledged. b_remote_*[index] is cleared.
819 * process bchannel events
820 * - mISDNport is a pointer to the port's structure
821 * - i is the index of the bchannel
822 * - event is the B_EVENT_* value
823 * - port is the PmISDN class pointer
825 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
827 class PmISDN *b_port = mISDNport->b_port[i];
828 int state = mISDNport->b_state[i];
829 unsigned long p_m_remote_ref = 0;
830 unsigned long p_m_remote_id = 0;
833 char *p_m_pipeline = NULL;
834 unsigned char *p_m_crypt_key = NULL;
835 int p_m_crypt_key_len = 0;
836 int p_m_crypt_key_type = 0;
838 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
840 unsigned long portid = mISDNport->b_stid[i];
845 p_m_remote_id = b_port->p_m_remote_id;
846 p_m_remote_ref = b_port->p_m_remote_ref;
847 p_m_tx_gain = b_port->p_m_tx_gain;
848 p_m_rx_gain = b_port->p_m_rx_gain;
849 p_m_pipeline = b_port->p_m_pipeline;
850 p_m_crypt_key = b_port->p_m_crypt_key;
851 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
852 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
858 /* port must be linked in order to allow activation */
860 FATAL("bchannel must be linked to a Port class\n");
866 /* export bchannel */
867 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
868 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
869 add_trace("type", NULL, "assign");
871 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
873 add_trace("socket", "id", "%d", portid);
876 state = B_STATE_EXPORTING;
877 mISDNport->b_remote_id[i] = p_m_remote_id;
878 mISDNport->b_remote_ref[i] = p_m_remote_ref;
881 /* create stack and send activation request */
882 if (_bchannel_create(mISDNport, i))
884 _bchannel_activate(mISDNport, i, 1);
885 state = B_STATE_ACTIVATING;
890 case B_STATE_ACTIVATING:
891 case B_STATE_EXPORTING:
892 /* do nothing, because it is already activating */
895 case B_STATE_DEACTIVATING:
896 case B_STATE_IMPORTING:
897 /* do nothing, because we must wait until we can reactivate */
901 /* problems that might ocurr:
902 * B_EVENT_USE is received when channel already in use.
903 * bchannel exported, but not freed by other port
905 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
909 case B_EVENT_EXPORTREQUEST:
910 /* special case where the bchannel is requested by remote */
913 PERROR("export request without remote channel set, please correct.\n");
919 /* in case, the bchannel is exported right after seize_bchannel */
920 /* export bchannel */
921 /* p_m_remote_id is set, when this event happens. */
922 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
923 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
924 add_trace("type", NULL, "assign");
926 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
928 add_trace("socket", "id", "%d", portid);
931 state = B_STATE_EXPORTING;
932 mISDNport->b_remote_id[i] = p_m_remote_id;
933 mISDNport->b_remote_ref[i] = p_m_remote_ref;
936 case B_STATE_ACTIVATING:
937 case B_STATE_EXPORTING:
938 /* do nothing, because it is already activating */
941 case B_STATE_DEACTIVATING:
942 case B_STATE_IMPORTING:
943 /* do nothing, because we must wait until we can reactivate */
947 /* bchannel is active, so we deactivate */
948 _bchannel_activate(mISDNport, i, 0);
949 state = B_STATE_DEACTIVATING;
953 /* problems that might ocurr:
954 * ... when channel already in use.
955 * bchannel exported, but not freed by other port
957 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
961 case B_EVENT_ACTIVATED:
964 case B_STATE_ACTIVATING:
965 if (b_port && !p_m_remote_id)
967 /* bchannel is active and used by Port class, so we configure bchannel */
968 _bchannel_configure(mISDNport, i);
969 state = B_STATE_ACTIVE;
972 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
973 _bchannel_activate(mISDNport, i, 0);
974 state = B_STATE_DEACTIVATING;
979 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
983 case B_EVENT_EXPORTED:
986 case B_STATE_EXPORTING:
987 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
989 /* remote export done */
990 state = B_STATE_REMOTE;
993 /* bchannel is now exported, but we need bchannel back
994 * OR bchannel is not used anymore
995 * OR bchannel has been exported to an obsolete ref,
996 * so reimport, to later export to new remote */
997 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
998 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
999 add_trace("type", NULL, "remove");
1001 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1003 add_trace("socket", "id", "%d", portid);
1006 state = B_STATE_IMPORTING;
1011 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1017 FATAL("bchannel must be linked to a Port class\n");
1021 /* bchannel is idle due to an error, so we do nothing */
1024 case B_STATE_ACTIVATING:
1025 case B_STATE_EXPORTING:
1026 /* do nothing because we must wait until bchanenl is active before deactivating */
1029 case B_STATE_ACTIVE:
1030 /* bchannel is active, so we deactivate */
1031 _bchannel_activate(mISDNport, i, 0);
1032 state = B_STATE_DEACTIVATING;
1035 case B_STATE_REMOTE:
1036 /* bchannel is exported, so we re-import */
1037 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1038 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1039 add_trace("type", NULL, "remove");
1041 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1043 add_trace("socket", "id", "%d", portid);
1046 state = B_STATE_IMPORTING;
1049 case B_STATE_DEACTIVATING:
1050 case B_STATE_IMPORTING:
1051 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1055 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1059 case B_EVENT_DEACTIVATED:
1063 /* ignore due to deactivation confirm after unloading */
1066 case B_STATE_DEACTIVATING:
1067 _bchannel_destroy(mISDNport, i);
1068 state = B_STATE_IDLE;
1071 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1074 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
1075 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1076 add_trace("type", NULL, "assign");
1078 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1080 add_trace("socket", "id", "%d", portid);
1083 state = B_STATE_EXPORTING;
1084 mISDNport->b_remote_id[i] = p_m_remote_id;
1085 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1088 if (_bchannel_create(mISDNport, i))
1090 _bchannel_activate(mISDNport, i, 1);
1091 state = B_STATE_ACTIVATING;
1098 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1102 case B_EVENT_IMPORTED:
1105 case B_STATE_IMPORTING:
1106 state = B_STATE_IDLE;
1107 mISDNport->b_remote_id[i] = 0;
1108 mISDNport->b_remote_ref[i] = 0;
1111 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1114 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
1115 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1116 add_trace("type", NULL, "assign");
1118 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1120 add_trace("socket", "id", "%d", portid);
1123 state = B_STATE_EXPORTING;
1124 mISDNport->b_remote_id[i] = p_m_remote_id;
1125 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1128 if (_bchannel_create(mISDNport, i))
1130 _bchannel_activate(mISDNport, i, 1);
1131 state = B_STATE_ACTIVATING;
1138 /* ignore, because not assigned */
1144 PERROR("Illegal event %d, please correct.\n", event);
1147 mISDNport->b_state[i] = state;
1154 * check for available channel and reserve+set it.
1155 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1156 * give exclusiv flag
1157 * returns -(cause value) or x = channel x or 0 = no channel
1158 * NOTE: no activation is done here
1160 int PmISDN::seize_bchannel(int channel, int exclusive)
1164 /* the channel is what we have */
1165 if (p_m_b_channel == channel)
1168 /* if channel already in use, release it */
1173 if (channel==CHANNEL_NO || channel==0)
1176 /* is channel in range ? */
1178 || (channel>p_m_mISDNport->b_num && channel<16)
1179 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1180 return(-6); /* channel unacceptable */
1182 /* request exclusive channel */
1183 if (exclusive && channel>0)
1185 i = channel-1-(channel>16);
1186 if (p_m_mISDNport->b_port[i])
1187 return(-44); /* requested channel not available */
1191 /* ask for channel */
1194 i = channel-1-(channel>16);
1195 if (p_m_mISDNport->b_port[i] == NULL)
1199 /* search for channel */
1201 while(i < p_m_mISDNport->b_num)
1203 if (!p_m_mISDNport->b_port[i])
1205 channel = i+1+(i>=15);
1210 return(-34); /* no free channel */
1213 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1216 p_m_mISDNport->b_port[i] = this;
1218 p_m_b_channel = channel;
1219 p_m_b_exclusive = exclusive;
1221 /* reserve channel */
1225 p_m_mISDNport->b_reserved++;
1232 * drop reserved channel and unset it.
1233 * deactivation is also done
1235 void PmISDN::drop_bchannel(void)
1237 /* unreserve channel */
1239 p_m_mISDNport->b_reserved--;
1243 if (p_m_b_index < 0)
1248 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1250 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1251 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1252 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1255 p_m_b_exclusive = 0;
1258 /* process bchannel export/import message from join */
1259 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1261 class Endpoint *epoint;
1263 class PmISDN *isdnport;
1264 struct mISDNport *mISDNport;
1269 case BCHANNEL_REQUEST:
1270 /* find the port object for the join object ref */
1271 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1273 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1276 if (!epoint->ep_portlist)
1278 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1281 if (epoint->ep_portlist->next)
1283 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);
1285 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1287 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1290 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1292 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1294 isdnport = (class PmISDN *)port;
1297 if (isdnport->p_m_remote_id)
1299 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1302 mISDNport = isdnport->p_m_mISDNport;
1303 i = isdnport->p_m_b_index;
1304 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1305 add_trace("type", NULL, "export request");
1306 isdnport->p_m_remote_ref = joinremote->j_serial;
1307 isdnport->p_m_remote_id = joinremote->j_remote_id;
1308 if (mISDNport && i>=0)
1310 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1315 case BCHANNEL_ASSIGN_ACK:
1316 case BCHANNEL_REMOVE_ACK:
1317 /* find mISDNport for stack ID */
1318 mISDNport = mISDNport_first;
1322 ii = mISDNport->b_num;
1326 if (mISDNport->b_socket[i] == handle)
1328 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1335 mISDNport = mISDNport->next;
1339 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1342 /* mISDNport may now be set or NULL */
1345 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1346 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1347 if (mISDNport && i>=0)
1348 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1352 PERROR("received wrong bchannel message type %d from remote\n", type);
1360 audio transmission procedure:
1361 -----------------------------
1364 three sources of audio transmission:
1365 - crypto-data high priority
1366 - tones high priority (also high)
1367 - remote-data low priority
1370 a variable that temporarily shows the number of samples elapsed since last transmission process.
1371 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1374 a variable that is increased whenever data is transmitted.
1375 it is decreased while time elapses. it stores the number of samples that
1376 are currently loaded to dsp module.
1377 since clock in dsp module is the same clock for user space process, these
1381 there are two levels:
1382 ISDN_LOAD will give the load that have to be kept in dsp.
1383 ISDN_MAXLOAD will give the maximum load before dropping.
1385 * procedure for low priority data
1386 see txfromup() for procedure
1387 in short: remote data is ignored during high priority tones
1389 * procedure for high priority data
1390 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1391 if no more data is available, load becomes empty again.
1394 0 ISDN_LOAD ISDN_MAXLOAD
1395 +--------------------+----------------------+
1397 +--------------------+----------------------+
1399 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1400 0 ISDN_LOAD ISDN_MAXLOAD
1401 +--------------------+----------------------+
1402 |TTTTTTTTTTTTTTTTTTTT| |
1403 +--------------------+----------------------+
1405 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1406 0 ISDN_LOAD ISDN_MAXLOAD
1407 +--------------------+----------------------+
1408 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1409 +--------------------+----------------------+
1412 int PmISDN::handler(void)
1414 struct message *message;
1418 if ((ret = Port::handler()))
1422 if (p_m_last_tv_sec)
1424 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1425 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1428 /* set clock of first process ever in this instance */
1429 p_m_last_tv_sec = now_tv.tv_sec;
1430 p_m_last_tv_msec = now_tv.tv_usec/1000;
1432 /* process only if we have a minimum of samples, to make packets not too small */
1433 if (elapsed >= ISDN_TRANSMIT)
1435 /* set clock of last process! */
1436 p_m_last_tv_sec = now_tv.tv_sec;
1437 p_m_last_tv_msec = now_tv.tv_usec/1000;
1440 if (elapsed < p_m_load)
1441 p_m_load -= elapsed;
1445 /* to send data, tone must be active OR crypt messages must be on */
1446 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1447 && (p_m_load < ISDN_LOAD)
1448 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1450 int tosend = ISDN_LOAD - p_m_load, length;
1452 unsigned char buf[MISDN_HEADER_LEN+tosend];
1453 struct mISDNhead *frm = (struct mISDNhead *)buf;
1454 unsigned long *d = buf+MISDN_HEADER_LEN;
1456 unsigned char buf[mISDN_HEADER_LEN+tosend];
1457 iframe_t *frm = (iframe_t *)buf;
1458 unsigned char *p = buf+mISDN_HEADER_LEN;
1461 /* copy crypto loops */
1462 while (p_m_crypt_msg_loops && tosend)
1464 /* how much do we have to send */
1465 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1468 if (length > tosend)
1471 /* copy message (part) to buffer */
1472 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1475 p_m_crypt_msg_current += length;
1476 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1479 p_m_crypt_msg_current = 0;
1480 p_m_crypt_msg_loops--;
1481 // puts("eine loop weniger");
1489 if (p_tone_name[0] && tosend)
1491 tosend -= read_audio(p, tosend);
1496 frm->prim = DL_DATA_REQ;
1498 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1500 PERROR("Failed to send to socket %d\n", handle);
1502 frm->prim = DL_DATA | REQUEST;
1503 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1505 frm->len = ISDN_LOAD - p_m_load - tosend;
1508 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1509 p_m_load += frm->len;
1513 // NOTE: deletion is done by the child class
1515 /* handle timeouts */
1518 if (p_m_timer+p_m_timeout < now_d)
1520 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1522 /* send timeout to endpoint */
1523 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1524 message->param.state = p_state;
1525 message_put(message);
1530 return(0); /* nothing done */
1535 * whenever we get audio data from bchannel, we process it here
1538 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1540 unsigned long cont = *((unsigned long *)data);
1542 void PmISDN::bchannel_receive(iframe_t *frm)
1545 unsigned long cont = *((unsigned long *)&frm->data.p);
1546 unsigned char *data =(unsigned char *)&frm->data.p;
1548 unsigned char *data_temp;
1549 unsigned long length_temp;
1550 struct message *message;
1555 if (hh->prim == PH_CONTROL_IND)
1557 if (frm->prim == (PH_CONTROL | INDICATION))
1562 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1565 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1567 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1568 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1570 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1571 message->param.dtmf = cont & DTMF_TONE_MASK;
1572 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1573 message_put(message);
1579 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1580 add_trace("DSP-CRYPT", NULL, "error");
1582 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1583 message->param.crypt.type = CC_ERROR_IND;
1584 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1585 message_put(message);
1589 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1590 add_trace("DSP-CRYPT", NULL, "ok");
1592 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1593 message->param.crypt.type = CC_ACTBF_CONF;
1594 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1595 message_put(message);
1599 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1600 add_trace("unknown", NULL, "0x%x", cont);
1606 if (hh->prim == PH_SIGNAL_IND)
1608 if (frm->prim == (PH_SIGNAL | INDICATION))
1617 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1618 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1621 /* see below (same condition) */
1622 if (p_state!=PORT_STATE_CONNECT
1623 && !p_m_mISDNport->tones)
1625 // printf(".");fflush(stdout);return;
1627 record(data, len, 1); // from up
1632 chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
1633 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1639 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1641 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1643 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1645 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1649 /* calls will not process any audio data unless
1650 * the call is connected OR interface features audio during call setup.
1652 //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);
1653 #ifndef DEBUG_COREBRIDGE
1654 if (p_state!=PORT_STATE_CONNECT
1655 && !p_m_mISDNport->tones)
1659 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1662 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1668 record(data, len, 0); // from down
1670 /* randomize and listen to crypt message if enabled */
1671 if (p_m_crypt_listen)
1673 /* the noisy randomizer */
1677 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1679 cryptman_listen_bch(data, len);
1684 /* send data to epoint */
1685 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1691 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1692 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1693 memcpy(message->param.data.data, data_temp, message->param.data.len);
1694 message_put(message);
1695 if (length_temp <= sizeof(message->param.data.data))
1697 data_temp += sizeof(message->param.data.data);
1698 length_temp -= sizeof(message->param.data.data);
1707 void PmISDN::set_echotest(int echo)
1709 if (p_m_echo != echo)
1712 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1714 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1716 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);
1718 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);
1726 void PmISDN::set_tone(char *dir, char *tone)
1732 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1739 /* check if we NOT really have to use a dsp-tone */
1740 if (!options.dsptones)
1744 if (p_m_b_index >= 0)
1745 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1747 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1749 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1751 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1755 Port::set_tone(dir, tone);
1761 /* now we USE dsp-tone, convert name */
1762 else if (!strcmp(tone, "dialtone"))
1764 switch(options.dsptones) {
1765 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1766 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1767 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1769 } else if (!strcmp(tone, "dialpbx"))
1771 switch(options.dsptones) {
1772 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1773 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1774 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1776 } else if (!strcmp(tone, "ringing"))
1778 switch(options.dsptones) {
1779 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1780 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1781 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1783 } else if (!strcmp(tone, "ringpbx"))
1785 switch(options.dsptones) {
1786 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1787 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1788 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1790 } else if (!strcmp(tone, "busy"))
1793 switch(options.dsptones) {
1794 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1795 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1796 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1798 } else if (!strcmp(tone, "release"))
1801 switch(options.dsptones) {
1802 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1803 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1804 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1806 } else if (!strcmp(tone, "cause_10"))
1808 else if (!strcmp(tone, "cause_11"))
1810 else if (!strcmp(tone, "cause_22"))
1812 switch(options.dsptones) {
1813 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1814 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1815 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1817 } else if (!strncmp(tone, "cause_", 6))
1818 id = TONE_SPECIAL_INFO;
1822 /* if we have a tone that is not supported by dsp */
1823 if (id==TONE_OFF && tone[0])
1831 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1832 if (p_m_b_index >= 0)
1833 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1835 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1837 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);
1840 /* turn user-space tones off in cases of no tone OR dsp tone */
1841 Port::set_tone("",NULL);
1845 /* MESSAGE_mISDNSIGNAL */
1846 //extern struct message *dddebug;
1847 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1849 switch(param->mISDNsignal.message)
1851 case mISDNSIGNAL_VOLUME:
1852 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1854 p_m_tx_gain = param->mISDNsignal.tx_gain;
1855 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1856 if (p_m_b_index >= 0)
1857 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1859 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1861 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1864 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1865 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1867 p_m_rx_gain = param->mISDNsignal.rx_gain;
1868 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1869 if (p_m_b_index >= 0)
1870 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1872 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1874 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1877 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1880 case mISDNSIGNAL_CONF:
1881 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1882 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1883 if (p_m_conf != param->mISDNsignal.conf)
1885 p_m_conf = param->mISDNsignal.conf;
1886 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1887 if (p_m_b_index >= 0)
1888 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1890 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);
1892 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);
1895 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1896 /* we must set, even if currently tone forbids conf */
1897 p_m_conf = param->mISDNsignal.conf;
1898 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1901 case mISDNSIGNAL_JOINDATA:
1902 if (p_m_joindata != param->mISDNsignal.joindata)
1904 p_m_joindata = param->mISDNsignal.joindata;
1905 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1907 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1910 case mISDNSIGNAL_DELAY:
1911 if (p_m_delay != param->mISDNsignal.delay)
1913 p_m_delay = param->mISDNsignal.delay;
1914 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1916 if (p_m_b_index >= 0)
1917 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1919 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);
1921 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);
1925 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1929 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1934 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1936 struct message *message;
1938 switch(param->crypt.type)
1940 case CC_ACTBF_REQ: /* activate blowfish */
1942 p_m_crypt_key_len = param->crypt.len;
1943 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1945 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1946 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1947 message->param.crypt.type = CC_ERROR_IND;
1948 message_put(message);
1951 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1953 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1954 if (p_m_b_index >= 0)
1955 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1957 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);
1959 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);
1963 case CC_DACT_REQ: /* deactivate session encryption */
1968 case CR_LISTEN_REQ: /* start listening to messages */
1969 p_m_crypt_listen = 1;
1970 p_m_crypt_listen_state = 0;
1973 case CR_UNLISTEN_REQ: /* stop listening to messages */
1974 p_m_crypt_listen = 0;
1977 case CR_MESSAGE_REQ: /* send message */
1978 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1979 if (!p_m_crypt_msg_len)
1981 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1984 p_m_crypt_msg_current = 0; /* reset */
1985 p_m_crypt_msg_loops = 6; /* enable */
1987 /* disable txmix, or we get corrupt data due to audio process */
1988 if (p_m_txmix && p_m_b_index>=0)
1990 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1992 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1994 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2001 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2007 * endpoint sends messages to the port
2009 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2011 if (Port::message_epoint(epoint_id, message_id, param))
2016 case MESSAGE_DATA: /* tx-data from upper layer */
2017 txfromup(param->data.data, param->data.len);
2020 case MESSAGE_mISDNSIGNAL: /* user command */
2021 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2022 message_mISDNsignal(epoint_id, message_id, param);
2025 case MESSAGE_CRYPT: /* crypt control command */
2026 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2027 message_crypt(epoint_id, message_id, param);
2036 * main loop for processing messages from mISDN
2039 int mISDN_handler(void)
2042 struct mISDNport *mISDNport;
2043 class PmISDN *isdnport;
2045 char buffer[2048+MISDN_HEADER_LEN];
2046 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2048 /* process all ports */
2049 mISDNport = mISDNport_first;
2052 /* process all bchannels */
2054 while(i < mISDNport->b_num)
2056 /* handle port of bchannel */
2057 isdnport=mISDNport->b_port[i];
2060 /* call bridges in user space OR crypto OR recording */
2061 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2063 /* rx IS required */
2064 if (isdnport->p_m_rxoff)
2067 isdnport->p_m_rxoff = 0;
2068 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2069 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2070 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2075 /* rx NOT required */
2076 if (!isdnport->p_m_rxoff)
2079 isdnport->p_m_rxoff = 1;
2080 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2081 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2082 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2087 if (isdnport->p_record)
2089 /* txdata IS required */
2090 if (!isdnport->p_m_txdata)
2093 isdnport->p_m_txdata = 1;
2094 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2095 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2096 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2101 /* txdata NOT required */
2102 if (isdnport->p_m_txdata)
2105 isdnport->p_m_txdata = 0;
2106 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2107 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2108 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2114 /* handle message from bchannel */
2115 if (mISDNport->b_stack[i] > -1)
2117 ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
2118 if (ret >= MISDN_HEADER_LEN)
2123 /* we don't care about confirms, we use rx data to sync tx */
2128 /* we receive audio data, we respond to it AND we send tones */
2132 case PH_CONTROL_IND:
2133 if (mISDNport->b_port[i])
2134 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2136 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_stack[i]);
2139 case PH_ACTIVATE_IND:
2140 case DL_ESTABLISH_IND:
2141 case PH_ACTIVATE_CONF:
2142 case DL_ESTABLISH_CONF:
2143 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2144 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2147 case PH_DEACTIVATE_IND:
2148 case DL_RELEASE_IND:
2149 case PH_DEACTIVATE_CONF:
2150 case DL_RELEASE_CONF:
2151 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2152 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2156 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], msg->len);
2160 if (ret < 0 && errno != EWOULDBLOCK)
2161 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2168 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2170 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2171 mISDNport->l1timeout = 0;
2174 /* layer 2 establish timer */
2175 if (mISDNport->l2establish)
2177 if (now-mISDNport->l2establish > 5)
2180 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2181 mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2182 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ, DIRECTION_OUT);
2189 mISDNport = mISDNport->next;
2192 /* if we received at least one b-frame, we will return 1 */
2196 int mISDN_handler(void)
2199 struct mISDNport *mISDNport;
2200 class PmISDN *isdnport;
2205 mISDNuser_head_t *hh;
2208 /* the que avoids loopbacks when replying to stack after receiving
2210 mISDNport = mISDNport_first;
2213 /* process turning on/off rx */
2215 while(i < mISDNport->b_num)
2217 isdnport=mISDNport->b_port[i];
2220 /* call bridges in user space OR crypto OR recording */
2221 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2223 /* rx IS required */
2224 if (isdnport->p_m_rxoff)
2227 isdnport->p_m_rxoff = 0;
2228 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2229 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2230 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2235 /* rx NOT required */
2236 if (!isdnport->p_m_rxoff)
2239 isdnport->p_m_rxoff = 1;
2240 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2241 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2242 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2247 if (isdnport->p_record)
2249 /* txdata IS required */
2250 if (!isdnport->p_m_txdata)
2253 isdnport->p_m_txdata = 1;
2254 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2256 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2257 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2263 /* txdata NOT required */
2264 if (isdnport->p_m_txdata)
2267 isdnport->p_m_txdata = 0;
2268 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2270 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2271 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2280 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2282 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2283 mISDNport->l1timeout = 0;
2286 if (mISDNport->l2establish)
2288 if (now-mISDNport->l2establish > 5)
2290 if (mISDNport->ntmode)
2292 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2293 time(&mISDNport->l2establish);
2295 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2296 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2301 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2302 time(&mISDNport->l2establish);
2304 act.prim = DL_ESTABLISH | REQUEST;
2305 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2308 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2310 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
2315 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2317 if (mISDNport->ntmode)
2319 hh = (mISDNuser_head_t *)dmsg->data;
2320 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);
2321 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2325 frm = (iframe_t *)dmsg->data;
2326 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2327 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2328 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);
2329 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2334 mISDNport = mISDNport->next;
2337 /* no device, no read */
2338 if (mISDNdevice < 0)
2341 /* get message from kernel */
2342 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2344 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2348 if (errno == EAGAIN)
2350 FATAL("Failed to do mISDN_read()\n");
2355 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2359 frm = (iframe_t *)msg->data;
2364 case MGR_DELLAYER | CONFIRM:
2365 case MGR_INITTIMER | CONFIRM:
2366 case MGR_ADDTIMER | CONFIRM:
2367 case MGR_DELTIMER | CONFIRM:
2368 case MGR_REMOVETIMER | CONFIRM:
2373 /* handle timer events from mISDN for NT-stack
2374 * note: they do not associate with a stack */
2375 if (frm->prim == (MGR_TIMER | INDICATION))
2379 /* find mISDNport */
2380 mISDNport = mISDNport_first;
2384 if (mISDNport->ntmode)
2386 it = mISDNport->nst.tlist;
2390 if (it->id == (int)frm->addr)
2397 mISDNport = mISDNport->next;
2401 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2402 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2404 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2405 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2406 ret = it->function(it->data);
2409 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2414 /* find the mISDNport that belongs to the stack */
2415 mISDNport = mISDNport_first;
2418 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2420 mISDNport = mISDNport->next;
2424 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2429 if (!(frm->addr&FLG_CHILD_STACK))
2434 case MGR_SHORTSTATUS | INDICATION:
2435 case MGR_SHORTSTATUS | CONFIRM:
2436 switch(frm->dinfo) {
2437 case SSTATUS_L1_ACTIVATED:
2438 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2441 case SSTATUS_L1_DEACTIVATED:
2442 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2445 case SSTATUS_L2_ESTABLISHED:
2446 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
2449 case SSTATUS_L2_RELEASED:
2450 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
2456 case PH_ACTIVATE | CONFIRM:
2457 case PH_ACTIVATE | INDICATION:
2458 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2460 if (mISDNport->ntmode)
2462 mISDNport->l1link = 1;
2463 setup_queue(mISDNport, 1);
2467 mISDNport->l1link = 1;
2468 setup_queue(mISDNport, 1);
2471 case PH_DEACTIVATE | CONFIRM:
2472 case PH_DEACTIVATE | INDICATION:
2473 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2475 if (mISDNport->ntmode)
2477 mISDNport->l1link = 0;
2478 setup_queue(mISDNport, 0);
2482 mISDNport->l1link = 0;
2483 setup_queue(mISDNport, 0);
2486 case PH_CONTROL | CONFIRM:
2487 case PH_CONTROL | INDICATION:
2488 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2491 case DL_ESTABLISH | INDICATION:
2492 case DL_ESTABLISH | CONFIRM:
2493 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2495 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2497 if (mISDNport->l2establish)
2499 mISDNport->l2establish = 0;
2500 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2502 mISDNport->l2link = 1;
2505 case DL_RELEASE | INDICATION:
2506 case DL_RELEASE | CONFIRM:
2507 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2509 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2511 mISDNport->l2link = 0;
2514 time(&mISDNport->l2establish);
2515 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2521 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);
2522 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2524 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2527 if (mISDNport->ntmode)
2529 /* l1-data enters the nt-mode library */
2530 nst = &mISDNport->nst;
2531 if (nst->l1_l2(nst, msg))
2536 /* l3-data is sent to pbx */
2537 if (stack2manager_te(mISDNport, msg))
2548 /* we don't care about confirms, we use rx data to sync tx */
2549 case PH_DATA | CONFIRM:
2550 case DL_DATA | CONFIRM:
2553 /* we receive audio data, we respond to it AND we send tones */
2554 case PH_DATA | INDICATION:
2555 case DL_DATA | INDICATION:
2556 case PH_CONTROL | INDICATION:
2557 case PH_SIGNAL | INDICATION:
2559 while(i < mISDNport->b_num)
2561 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2565 if (i == mISDNport->b_num)
2567 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2570 if (mISDNport->b_port[i])
2572 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2573 mISDNport->b_port[i]->bchannel_receive(frm);
2575 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2578 case PH_ACTIVATE | INDICATION:
2579 case DL_ESTABLISH | INDICATION:
2580 case PH_ACTIVATE | CONFIRM:
2581 case DL_ESTABLISH | CONFIRM:
2582 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2584 while(i < mISDNport->b_num)
2586 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2590 if (i == mISDNport->b_num)
2592 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2595 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2598 case PH_DEACTIVATE | INDICATION:
2599 case DL_RELEASE | INDICATION:
2600 case PH_DEACTIVATE | CONFIRM:
2601 case DL_RELEASE | CONFIRM:
2602 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2604 while(i < mISDNport->b_num)
2606 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2610 if (i == mISDNport->b_num)
2612 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2615 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2619 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2630 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2632 struct mISDNport *mISDNport = ml3->private;
2634 if (cmd == MT_ASSIGN)
2640 achtung MT_ASSIGN kommt hier an
2646 case MGR_SHORTSTATUS_IND:
2647 case MGR_SHORTSTATUS_CONF:
2648 switch(frm->dinfo) {
2649 case SSTATUS_L1_ACTIVATED:
2650 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE_IND, DIRECTION_IN);
2653 case SSTATUS_L1_DEACTIVATED:
2654 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE_IND, DIRECTION_IN);
2657 case SSTATUS_L2_ESTABLISHED:
2658 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_IND, DIRECTION_IN);
2661 case SSTATUS_L2_RELEASED:
2662 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_IND, DIRECTION_IN);
2668 case PH_ACTIVATE_CONF:
2669 case PH_ACTIVATE_IND:
2670 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2673 mISDNport->l1link = 1;
2675 if (mISDNport->ntmode)
2676 setup_queue(mISDNport, 1);
2680 case PH_DEACTIVATE | CONFIRM:
2681 case PH_DEACTIVATE | INDICATION:
2682 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2685 mISDNport->l1link = 0;
2686 raus mit der setup-queue, da dies im stack geschieht
2688 if (mISDNport->ntmode)
2689 setup_queue(mISDNport, 0);
2693 case PH_CONTROL_CONFIRM:
2694 case PH_CONTROL_INDICATION:
2695 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2698 case DL_ESTABLISH_IND:
2699 case DL_ESTABLISH_CONF:
2700 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2702 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2704 if (mISDNport->l2establish)
2706 mISDNport->l2establish = 0;
2707 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2709 mISDNport->l2link = 1;
2712 case DL_RELEASE_IND:
2713 case DL_RELEASE_CONF:
2714 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2717 mISDNport->l2link = 0;
2720 time(&mISDNport->l2establish);
2721 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2726 /* l3-data is sent to LCR */
2727 message_from_mlayer3(mISDNport, cmd, pid, l3m);
2743 * global function to add a new card (port)
2745 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2748 unsigned char buff[1025];
2749 iframe_t *frm = (iframe_t *)buff;
2750 struct mISDNport *mISDNport, **mISDNportp;
2752 int pri, bri, ports;
2755 struct mlayer3 *ml3;
2756 struct mISDN_devinfo devinfo;
2758 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2761 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2765 // interface_info_t ii;
2769 stack_info_t *stinf;
2771 /* query port's requirements */
2772 cnt = mISDN_get_stack_count(mISDNdevice);
2777 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2780 if (port>cnt || port<1)
2782 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2786 pri = bri = ports = nt = te = 0;
2788 devinfo.id = port - 1;
2789 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2792 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2795 /* output the port info */
2796 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2801 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2807 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2814 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2821 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2828 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2834 if (force_nt && !nt)
2836 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2841 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2844 if (pots && !bri && !pri)
2846 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2851 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2856 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2859 /* force nt, by turning off TE */
2862 /* if TE an NT is supported (and not forced to NT), turn off NT */
2866 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2869 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2872 stinf = (stack_info_t *)&frm->data.p;
2873 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2875 case ISDN_PID_L0_TE_S0:
2876 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2878 case ISDN_PID_L0_NT_S0:
2879 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2882 case ISDN_PID_L0_TE_E1:
2883 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2886 case ISDN_PID_L0_NT_E1:
2887 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2892 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2898 if (stinf->pid.protocol[1] == 0)
2900 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2903 if (stinf->pid.protocol[2])
2905 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2912 if (stinf->pid.protocol[1] == 0)
2914 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2917 if (stinf->pid.protocol[2] == 0)
2919 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2922 if (stinf->pid.protocol[3] == 0)
2924 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2928 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2930 case ISDN_PID_L3_DSS1USER:
2934 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2938 if (stinf->pid.protocol[4])
2940 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2946 /* add mISDNport structure */
2947 mISDNportp = &mISDNport_first;
2949 mISDNportp = &((*mISDNportp)->next);
2950 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2952 *mISDNportp = mISDNport;
2954 /* allocate ressources of port */
2957 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2962 prop |= FLG_FORCE_PTMP;
2963 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2964 if (!mISDNport->ml3)
2966 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\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 */
2986 SCPY(mISDNport->name, devinfo.name);
2987 mISDNport->b_num = devinfo.nrbchan;
2989 msg_queue_init(&mISDNport->downqueue);
2990 mISDNport->d_stid = stinf->id;
2991 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2992 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2994 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2998 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
3003 /* create layer intance */
3004 memset(&li, 0, sizeof(li));
3005 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3008 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3009 li.pid.layermask = ISDN_LAYER((nt?2:4));
3010 li.st = mISDNport->d_stid;
3011 ret = mISDN_new_layer(mISDNdevice, &li);
3014 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3016 mISDNport_close(mISDNport);
3019 mISDNport->upper_id = li.id;
3020 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3023 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3026 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3027 if (mISDNport->lower_id < 0)
3029 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3032 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3033 if (mISDNport->upper_id < 0)
3035 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3038 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3040 /* if ntmode, establish L1 to send the tei removal during start */
3041 if (mISDNport->ntmode)
3045 act.prim = PH_ACTIVATE | REQUEST;
3046 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3047 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3050 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3051 usleep(10000); /* to be sure, that l1 is up */
3054 /* create nst (nt-mode only) */
3057 mgr = &mISDNport->mgr;
3058 nst = &mISDNport->nst;
3063 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3064 nst->device = mISDNdevice;
3066 nst->d_stid = mISDNport->d_stid;
3068 nst->feature = FEATURE_NET_HOLD;
3070 nst->feature |= FEATURE_NET_PTP;
3072 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3075 while(i < mISDNport->b_num)
3077 nst->b_stid[i] = mISDNport->b_stid[i];
3081 nst->l1_id = mISDNport->lower_id;
3082 nst->l2_id = mISDNport->upper_id;
3085 msg_queue_init(&nst->down_queue);
3091 mISDNport->b_num = stinf->childcnt;
3093 mISDNport->portnum = port;
3094 mISDNport->ntmode = nt;
3095 mISDNport->pri = pri;
3096 mISDNport->ptp = ptp;
3097 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3099 while(i < mISDNport->b_num)
3101 mISDNport->b_state[i] = B_STATE_IDLE;
3103 mISDNport->b_socket = -1;
3105 mISDNport->b_stid[i] = stinf->child[i];
3106 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3111 /* if te-mode, query state link */
3112 if (!mISDNport->ntmode)
3116 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3117 act.prim = MGR_SHORTSTATUS | REQUEST;
3118 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3119 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3121 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3123 /* if ptp AND te-mode, pull up the link */
3124 if (mISDNport->ptp && !mISDNport->ntmode)
3128 act.prim = DL_ESTABLISH | REQUEST;
3129 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3132 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3134 /* if ptp AND nt-mode, pull up the link */
3135 if (mISDNport->ptp && mISDNport->ntmode)
3139 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3140 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3143 /* initially, we assume that the link is down, exept for nt-ptmp */
3144 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3146 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3148 start_trace(mISDNport->portnum,
3156 add_trace("channels", NULL, "%d", mISDNport->b_num);
3163 * function to free ALL cards (ports)
3165 void mISDNport_close_all(void)
3167 /* free all ports */
3168 while(mISDNport_first)
3169 mISDNport_close(mISDNport_first);
3173 * free only one port
3175 void mISDNport_close(struct mISDNport *mISDNport)
3177 struct mISDNport **mISDNportp;
3179 class PmISDN *isdnport;
3181 unsigned char buf[32];
3184 /* remove all port instance that are linked to this mISDNport */
3188 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3190 isdnport = (class PmISDN *)port;
3191 if (isdnport->p_m_mISDNport)
3193 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3200 /* only if we are already part of interface */
3201 if (mISDNport->ifport)
3203 start_trace(mISDNport->portnum,
3204 mISDNport->ifport->interface,
3214 /* free bchannels */
3216 while(i < mISDNport->b_num)
3218 if (mISDNport->b_addr[i])
3220 _bchannel_destroy(mISDNport, i);
3221 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3227 close_layer3(mISDNport->ml3);
3229 /* free ressources of port */
3230 msg_queue_purge(&mISDNport->downqueue);
3233 if (mISDNport->ntmode)
3235 nst = &mISDNport->nst;
3236 if (nst->manager) /* to see if initialized */
3238 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");
3239 cleanup_Isdnl3(nst);
3240 cleanup_Isdnl2(nst);
3243 msg_queue_purge(&nst->down_queue);
3244 if (nst->phd_down_msg)
3245 FREE(nst->phd_down_msg, 0);
3249 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3250 if (mISDNport->d_stid)
3252 if (mISDNport->upper_id)
3253 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3257 /* remove from list */
3258 mISDNportp = &mISDNport_first;
3261 if (*mISDNportp == mISDNport)
3263 *mISDNportp = (*mISDNportp)->next;
3267 mISDNportp = &((*mISDNportp)->next);
3271 FATAL("mISDNport not in list\n");
3273 FREE(mISDNport, sizeof(struct mISDNport));
3280 * global function to show all available isdn ports
3282 void mISDN_port_info(void)
3286 int useable, nt, te, pri, bri, pots;
3287 unsigned char buff[1025];
3288 iframe_t *frm = (iframe_t *)buff;
3290 struct mISDN_devinfo devinfo;
3294 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3297 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3301 /* get number of stacks */
3303 ret = ioctl(socket, IMGETCOUNT, &ii);
3306 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3310 stack_info_t *stinf;
3314 if ((device = mISDN_open()) < 0)
3316 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));
3320 /* get number of stacks */
3322 ii = mISDN_get_stack_count(device);
3327 printf("Found no card. Please be sure to load card drivers.\n");
3331 /* loop the number of cards and get their info */
3334 nt = te = bri = pri = pots = 0;
3339 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
3342 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3346 /* output the port info */
3347 printf("Port %2d name='%s': ", i, devinfo.name);
3348 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3353 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3359 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3366 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3373 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3380 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3386 if ((te || nt) && (bri || pri || ports))
3390 printf("TE-mode BRI S/T interface line (for phone lines)");
3392 printf("NT-mode BRI S/T interface port (for phones)");
3394 printf("TE-mode PRI E1 interface line (for phone lines)");
3396 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3398 printf("FXS POTS interface port (for analog lines)");
3400 printf("FXO POTS interface port (for analog phones)");
3404 printf("\n -> Analog interfaces are not supported.");
3408 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3412 printf(" - %d B-channels\n", devinfo.nfbchan);
3414 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3417 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3420 stinf = (stack_info_t *)&frm->data.p;
3422 /* output the port info */
3423 printf("Port %2d: ", i);
3424 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3426 case ISDN_PID_L0_TE_S0:
3430 printf("TE-mode BRI S/T interface line (for phone lines)");
3432 case ISDN_PID_L0_NT_S0:
3436 printf("NT-mode BRI S/T interface port (for phones)");
3438 case ISDN_PID_L0_TE_E1:
3442 printf("TE-mode PRI E1 interface line (for phone lines)");
3444 case ISDN_PID_L0_NT_E1:
3448 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3452 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3458 if (stinf->pid.protocol[1] == 0)
3461 printf(" -> Missing layer 1 NT-mode protocol.\n");
3464 while(p <= MAX_LAYER_NR) {
3465 if (stinf->pid.protocol[p])
3468 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3475 printf(" -> Interface is Point-To-Point (PRI).\n");
3477 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3482 if (stinf->pid.protocol[1] == 0)
3485 printf(" -> Missing layer 1 protocol.\n");
3487 if (stinf->pid.protocol[2] == 0)
3490 printf(" -> Missing layer 2 protocol.\n");
3492 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3494 printf(" -> Interface is Poin-To-Point.\n");
3496 if (stinf->pid.protocol[3] == 0)
3499 printf(" -> Missing layer 3 protocol.\n");
3502 printf(" -> Protocol: ");
3503 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3505 case ISDN_PID_L3_DSS1USER:
3506 printf("DSS1 (Euro ISDN)");
3511 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3516 while(p <= MAX_LAYER_NR) {
3517 if (stinf->pid.protocol[p])
3520 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3525 printf(" - %d B-channels\n", stinf->childcnt);
3529 printf(" * Port NOT useable for LCR\n");
3531 printf("--------\n");
3542 if ((ret = mISDN_close(device)))
3543 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3549 * enque data from upper buffer
3551 void PmISDN::txfromup(unsigned char *data, int length)
3554 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3555 struct mISDNhead *frm = (struct mISDNhead *)buf;
3557 if (p_m_b_index < 0)
3559 if (!p_m_mISDNport->b_socket[p_m_b_index])
3562 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3563 iframe_t *frm = (iframe_t *)buf;
3565 if (p_m_b_index < 0)
3567 if (!p_m_mISDNport->b_addr[p_m_b_index])
3571 /* check if high priority tones exist
3572 * ignore data in this case
3574 if (p_tone_name[0] || p_m_crypt_msg_loops)
3577 /* preload procedure
3578 * if transmit buffer in DSP module is empty,
3579 * preload it to DSP_LOAD to prevent jitter gaps.
3581 if (p_m_load==0 && ISDN_LOAD>0)
3584 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3585 frm->len = ISDN_LOAD;
3586 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3587 p_m_load += frm->len;
3590 /* drop if load would exceed ISDN_MAXLOAD
3591 * this keeps the delay not too high
3593 if (p_m_load+length > ISDN_MAXLOAD)
3596 /* make and send frame */
3598 frm->prim = DL_DATA_REQ;
3600 memcpy(buf+MISDN_HEADER_LEN, data, length);
3601 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3603 PERROR("Failed to send to socket %d\n", handle);
3605 frm->prim = DL_DATA | REQUEST;
3606 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3609 memcpy(buf+mISDN_HEADER_LEN, data, length);
3610 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);