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 // timeouts if activating/deactivating response from mISDN got lost
76 #define B_TIMER_ACTIVATING 1
77 #define B_TIMER_DEACTIVATING 1
79 /* list of mISDN ports */
80 struct mISDNport *mISDNport_first;
82 /* noise randomizer */
83 unsigned char mISDN_rand[256];
84 int mISDN_rand_count = 0;
89 int mISDN_initialize(void)
91 /* try to open raw socket to check kernel */
92 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
95 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
99 /* initialize stuff of the NT lib */
100 if (options.deb & DEBUG_STACK)
102 global_debug = 0xffffffff & ~DBGM_MSG;
103 // global_debug = DBGM_L3DATA;
105 global_debug = DBGM_MAN;
106 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
107 if (options.deb & DEBUG_LOG)
108 mISDN_debug_init(global_debug, debug_log, debug_log, debug_log);
110 mISDN_debug_init(global_debug, NULL, NULL, NULL);
113 init_layer3(4); // buffer of 4
118 void mISDN_deinitialize(void)
124 if (mISDNsocket > -1)
128 int entity = 0; /* used for udevice */
129 int mISDNdevice = -1; /* the device handler and port list */
131 int mISDN_initialize(void)
134 unsigned char buff[1025];
135 iframe_t *frm = (iframe_t *)buff;
138 /* initialize stuff of the NT lib */
139 if (options.deb & DEBUG_STACK)
141 global_debug = 0xffffffff & ~DBGM_MSG;
142 // global_debug = DBGM_L3DATA;
144 global_debug = DBGM_MAN;
145 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
146 if (options.deb & DEBUG_LOG)
147 debug_init(global_debug, debug_log, debug_log, debug_log);
149 debug_init(global_debug, NULL, NULL, NULL);
152 /* open mISDNdevice if not already open */
158 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));
162 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
164 /* create entity for layer 3 TE-mode */
165 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
166 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
167 if (ret < (int)mISDN_HEADER_LEN)
170 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
172 entity = frm->dinfo & 0xffff;
175 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
180 void mISDN_deinitialize(void)
182 unsigned char buff[1025];
186 if (mISDNdevice >= 0)
189 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
191 mISDN_close(mISDNdevice);
193 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
201 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
203 p_m_mISDNport = mISDNport;
204 p_m_portnum = mISDNport->portnum;
211 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
212 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
220 p_m_dtmf = !mISDNport->ifport->nodtmf;
223 p_m_remote_ref = 0; /* channel shall be exported to given remote */
224 p_m_remote_id = 0; /* channel shall be exported to given remote */
225 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
233 p_m_crypt_listen = 0;
234 p_m_crypt_msg_loops = 0;
235 p_m_crypt_msg_loops = 0;
236 p_m_crypt_msg_len = 0;
237 p_m_crypt_msg[0] = '\0';
238 p_m_crypt_msg_current = 0;
239 p_m_crypt_key_len = 0;
240 p_m_crypt_listen = 0;
241 p_m_crypt_listen_state = 0;
242 p_m_crypt_listen_len = 0;
243 p_m_crypt_listen_msg[0] = '\0';
244 p_m_crypt_listen_crc = 0;
245 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
247 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
248 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
252 /* if any channel requested by constructor */
253 if (channel == CHANNEL_ANY)
255 /* reserve channel */
257 mISDNport->b_reserved++;
260 /* reserve channel */
261 if (channel > 0) // only if constructor was called with a channel resevation
262 seize_bchannel(channel, exclusive);
264 /* we increase the number of objects: */
266 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
275 struct message *message;
277 /* remove bchannel relation */
283 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
284 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
285 message->param.disconnectinfo.cause = 16;
286 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
287 message_put(message);
288 /* remove from list */
289 free_epointlist(p_epointlist);
292 /* we decrease the number of objects: */
293 p_m_mISDNport->use--;
294 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
301 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
303 /* init trace with given values */
304 start_trace(mISDNport?mISDNport->portnum:0,
305 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
306 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
307 port?port->p_dialinginfo.id:NULL,
310 port?port->p_serial:0,
318 static struct isdn_message {
322 {"TIMEOUT", CC_TIMEOUT},
324 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
325 {"PROCEEDING", CC_PROCEEDING},
326 {"ALERTING", CC_ALERTING},
327 {"CONNECT", CC_CONNECT},
328 {"CONNECT RES", CC_CONNECT},
329 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
330 {"DISCONNECT", CC_DISCONNECT},
331 {"RELEASE", CC_RELEASE},
332 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
333 {"INFORMATION", CC_INFORMATION},
334 {"PROGRESS", CC_PROGRESS},
335 {"NOTIFY", CC_NOTIFY},
336 {"SUSPEND", CC_SUSPEND},
337 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
338 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
339 {"RESUME", CC_RESUME},
340 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
341 {"RESUME_REJ", CC_RESUME_REJECT},
343 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
344 {"HOLD_REJ", CC_HOLD_REJECT},
345 {"RETRIEVE", CC_RETRIEVE},
346 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
347 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
348 {"FACILITY", CC_FACILITY},
349 {"STATUS", CC_STATUS},
350 {"RESTART", CC_RESTART},
351 {"RELEASE_CR", CC_RELEASE_CR},
352 {"NEW_CR", CC_NEW_CR},
353 {"DL_ESTABLISH", DL_ESTABLISH},
354 {"DL_RELEASE", DL_RELEASE},
355 {"PH_ACTIVATE", PH_ACTIVATE},
356 {"PH_DEACTIVATE", PH_DEACTIVATE},
360 static char *isdn_prim[4] = {
366 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
369 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
371 /* select message and primitive text */
373 while(isdn_message[i].name)
375 if (isdn_message[i].value == (prim&0xffffff00))
377 SCPY(msgtext, isdn_message[i].name);
382 SCAT(msgtext, isdn_prim[prim&0x00000003]);
385 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
389 if (mISDNport->ntmode)
391 if (direction == DIRECTION_OUT)
392 SCAT(msgtext, " N->U");
394 SCAT(msgtext, " N<-U");
397 if (direction == DIRECTION_OUT)
398 SCAT(msgtext, " U->N");
400 SCAT(msgtext, " U<-N");
405 /* init trace with given values */
406 start_trace(mISDNport?mISDNport->portnum:0,
407 mISDNport?mISDNport->ifport->interface:NULL,
408 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
409 port?port->p_dialinginfo.id:NULL,
412 port?port->p_serial:0,
418 * send control information to the channel (dsp-module)
420 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
423 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
424 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
425 unsigned long *d = buffer+MISDN_HEADER_LEN;
428 ctrl->prim = PH_CONTROL_REQ;
432 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
434 PERROR("Failed to send to socket %d\n", handle);
436 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
437 iframe_t *ctrl = (iframe_t *)buffer;
438 unsigned long *d = (unsigned long *)&ctrl->data.p;
440 ctrl->prim = PH_CONTROL | REQUEST;
441 ctrl->addr = handle | FLG_MSG_DOWN;
443 ctrl->len = sizeof(int)*2;
446 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
448 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
449 if (c1 == CMX_CONF_JOIN)
450 add_trace(trace_name, NULL, "0x%08x", trace_value);
452 add_trace(trace_name, NULL, "%d", trace_value);
456 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)
459 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
460 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
461 unsigned long *d = buffer+MISDN_HEADER_LEN;
464 ctrl->prim = PH_CONTROL_REQ;
467 memcpy(d, c2, c2_len);
468 ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
470 PERROR("Failed to send to socket %d\n", handle);
472 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
473 iframe_t *ctrl = (iframe_t *)buffer;
474 unsigned long *d = (unsigned long *)&ctrl->data.p;
476 ctrl->prim = PH_CONTROL | REQUEST;
477 ctrl->addr = handle | FLG_MSG_DOWN;
479 ctrl->len = sizeof(int)+c2_len;
481 memcpy(d, c2, c2_len);
482 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
484 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
485 add_trace(trace_name, NULL, "%d", trace_value);
491 * subfunction for bchannel_event
494 static int _bchannel_create(struct mISDNport *mISDNport, int i)
496 unsigned char buff[1024];
499 unsigned long on = 1;
500 struct sockadd_mISDN addr;
502 if (mISDNport->b_socket[i])
504 PERROR("Error: Socket already created for index %d\n", i);
509 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
510 if (mISDNport->b_socket[i] < 0)
512 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
516 /* set nonblocking io */
517 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
520 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
521 close(mISDNport->b_socket[i]);
522 mISDNport->b_socket[i] = -1;
526 /* bind socket to bchannel */
527 addr.family = AF_ISDN;
528 addr.dev = mISDNport->port-1;
529 addr.channel = i+1+(i>=15);
530 ret = bind(di->bchan, (struct sockaddr *)&addr, sizeof(addr));
533 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
534 close(mISDNport->b_socket[i]);
535 mISDNport->b_socket[i] = -1;
539 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
540 add_trace("channel", NULL, "%d", i+1+(i>=15));
541 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
547 if (!mISDNport->b_stid[i])
549 PERROR("Error: no stack for index %d\n", i);
552 if (mISDNport->b_addr[i])
554 PERROR("Error: stack already created for index %d\n", i);
558 /* create new layer */
559 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
560 memset(&li, 0, sizeof(li));
561 memset(&pid, 0, sizeof(pid));
564 li.st = mISDNport->b_stid[i];
565 UCPY(li.name, "B L4");
566 li.pid.layermask = ISDN_LAYER((4));
567 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
568 ret = mISDN_new_layer(mISDNdevice, &li);
572 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
575 mISDNport->b_addr[i] = li.id;
578 goto failed_new_layer;
580 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
582 /* create new stack */
583 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
584 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
585 pid.protocol[3] = ISDN_PID_L3_B_DSP;
586 pid.protocol[4] = ISDN_PID_L4_B_USER;
587 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
588 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
592 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
593 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
596 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
601 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
602 if (!mISDNport->b_addr[i])
604 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
605 add_trace("channel", NULL, "%d", i+1+(i>=15));
606 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
607 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
614 mISDNport->b_addr[i] = 0;
620 * subfunction for bchannel_event
621 * activate / deactivate request
623 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
626 struct mISDNhead act;
629 act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
631 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
633 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
637 /* activate bchannel */
638 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
639 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
642 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
646 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
647 add_trace("channel", NULL, "%d", i+1+(i>=15));
648 if (mISDNport->b_timer[i])
649 add_trace("event", NULL, "timeout recovery");
655 * subfunction for bchannel_event
658 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
664 handle = mISDNport->b_socket[i];
666 unsigned long handle;
668 handle = mISDNport->b_addr[i];
670 port = mISDNport->b_port[i];
673 PERROR("bchannel index i=%d not associated with a port object\n", i);
677 /* set dsp features */
679 if (port->p_m_txdata)
680 ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
682 ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
684 if (port->p_m_tx_gain)
685 ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
686 if (port->p_m_rx_gain)
687 ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
689 if (port->p_m_pipeline[0])
690 ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
693 ph_control(mISDNport, port, handle, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
695 ph_control(mISDNport, port, handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
697 ph_control(mISDNport, port, handle, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
699 ph_control(mISDNport, port, handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
700 // if (port->p_m_txmix)
701 // ph_control(mISDNport, port, handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
703 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
705 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);
709 * subfunction for bchannel_event
712 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
715 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
716 add_trace("channel", NULL, "%d", i+1+(i>=15));
717 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
719 if (mISDNport->b_socket[i] > -1)
721 close(mISDNport->b_socket[i]);
722 mISDNport->b_socket[i] = -1;
725 unsigned char buff[1024];
727 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
728 add_trace("channel", NULL, "%d", i+1+(i>=15));
729 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
730 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
732 /* remove our stack only if set */
733 if (mISDNport->b_addr[i])
735 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
736 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
737 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
738 mISDNport->b_addr[i] = 0;
748 A bchannel goes through the following states in this order:
751 No one is using the bchannel.
752 It is available and not linked to Port class, nor reserved.
755 The bchannel stack is created and an activation request is sent.
756 It MAY be linked to Port class, but already unlinked due to Port class removal.
759 The bchannel is active and cofigured to the Port class needs.
760 Also it is linked to a Port class, otherwhise it would be deactivated.
762 - B_STATE_DEACTIVATING
763 The bchannel is in deactivating state, due to deactivation request.
764 It may be linked to a Port class, that likes to reactivate it.
768 After deactivating bchannel, and if not used, the bchannel becomes idle again.
770 Also the bchannel may be exported, but only if the state is or becomes idle:
773 The bchannel assignment has been sent to the remove application.
776 The bchannel assignment is acknowledged by the remote application.
779 The bchannel is re-imported by mISDN port object.
783 After re-importing bchannel, and if not used, the bchannel becomes idle again.
786 A bchannel can have the following events:
789 A bchannel is required by a Port class.
790 The bchannel shall be exported to the remote application.
793 The bchannel beomes active.
796 The bchannel is not required by Port class anymore
798 - B_EVENT_DEACTIVATED
799 The bchannel becomes inactive.
802 The bchannel is now used by remote application.
805 The bchannel is not used by remote application.
807 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
809 if an export request is receive by remote application, p_m_remote_* is set.
810 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.)
811 - set on export request from remote application (if port is assigned)
812 - set on channel use, if requested by remote application (p_m_remote_*)
813 - cleared on drop request
815 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
816 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
817 the bchannel import/export is acknowledged with stack given.
819 if exporting, b_remote_*[index] is set to the remote socket id.
820 if importing has been acknowledged. b_remote_*[index] is cleared.
825 * process bchannel events
826 * - mISDNport is a pointer to the port's structure
827 * - i is the index of the bchannel
828 * - event is the B_EVENT_* value
829 * - port is the PmISDN class pointer
831 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
833 class PmISDN *b_port = mISDNport->b_port[i];
834 int state = mISDNport->b_state[i];
835 double timer = mISDNport->b_timer[i];
836 unsigned long p_m_remote_ref = 0;
837 unsigned long p_m_remote_id = 0;
840 char *p_m_pipeline = NULL;
841 unsigned char *p_m_crypt_key = NULL;
842 int p_m_crypt_key_len = 0;
843 int p_m_crypt_key_type = 0;
845 unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
847 unsigned long portid = mISDNport->b_stid[i];
852 p_m_remote_id = b_port->p_m_remote_id;
853 p_m_remote_ref = b_port->p_m_remote_ref;
854 p_m_tx_gain = b_port->p_m_tx_gain;
855 p_m_rx_gain = b_port->p_m_rx_gain;
856 p_m_pipeline = b_port->p_m_pipeline;
857 p_m_crypt_key = b_port->p_m_crypt_key;
858 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
859 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
865 /* port must be linked in order to allow activation */
867 FATAL("bchannel must be linked to a Port class\n");
873 /* export bchannel */
874 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);
875 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
876 add_trace("type", NULL, "assign");
878 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
880 add_trace("socket", "id", "%d", portid);
883 state = B_STATE_EXPORTING;
884 mISDNport->b_remote_id[i] = p_m_remote_id;
885 mISDNport->b_remote_ref[i] = p_m_remote_ref;
888 /* create stack and send activation request */
889 if (_bchannel_create(mISDNport, i))
891 _bchannel_activate(mISDNport, i, 1);
892 state = B_STATE_ACTIVATING;
893 timer = now_d + B_TIMER_ACTIVATING;
898 case B_STATE_ACTIVATING:
899 case B_STATE_EXPORTING:
900 /* do nothing, because it is already activating */
903 case B_STATE_DEACTIVATING:
904 case B_STATE_IMPORTING:
905 /* do nothing, because we must wait until we can reactivate */
909 /* problems that might ocurr:
910 * B_EVENT_USE is received when channel already in use.
911 * bchannel exported, but not freed by other port
913 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
917 case B_EVENT_EXPORTREQUEST:
918 /* special case where the bchannel is requested by remote */
921 PERROR("export request without remote channel set, please correct.\n");
927 /* in case, the bchannel is exported right after seize_bchannel */
928 /* export bchannel */
929 /* p_m_remote_id is set, when this event happens. */
930 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);
931 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
932 add_trace("type", NULL, "assign");
934 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
936 add_trace("socket", "id", "%d", portid);
939 state = B_STATE_EXPORTING;
940 mISDNport->b_remote_id[i] = p_m_remote_id;
941 mISDNport->b_remote_ref[i] = p_m_remote_ref;
944 case B_STATE_ACTIVATING:
945 case B_STATE_EXPORTING:
946 /* do nothing, because it is already activating */
949 case B_STATE_DEACTIVATING:
950 case B_STATE_IMPORTING:
951 /* do nothing, because we must wait until we can reactivate */
955 /* bchannel is active, so we deactivate */
956 _bchannel_activate(mISDNport, i, 0);
957 state = B_STATE_DEACTIVATING;
958 timer = now_d + B_TIMER_DEACTIVATING;
962 /* problems that might ocurr:
963 * ... when channel already in use.
964 * bchannel exported, but not freed by other port
966 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
970 case B_EVENT_ACTIVATED:
974 case B_STATE_ACTIVATING:
975 if (b_port && !p_m_remote_id)
977 /* bchannel is active and used by Port class, so we configure bchannel */
978 _bchannel_configure(mISDNport, i);
979 state = B_STATE_ACTIVE;
982 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
983 _bchannel_activate(mISDNport, i, 0);
984 state = B_STATE_DEACTIVATING;
985 timer = now_d + B_TIMER_DEACTIVATING;
990 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
994 case B_EVENT_EXPORTED:
997 case B_STATE_EXPORTING:
998 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
1000 /* remote export done */
1001 state = B_STATE_REMOTE;
1004 /* bchannel is now exported, but we need bchannel back
1005 * OR bchannel is not used anymore
1006 * OR bchannel has been exported to an obsolete ref,
1007 * so reimport, to later export to new remote */
1008 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1009 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1010 add_trace("type", NULL, "remove");
1012 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1014 add_trace("socket", "id", "%d", portid);
1017 state = B_STATE_IMPORTING;
1022 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1028 FATAL("bchannel must be linked to a Port class\n");
1032 /* bchannel is idle due to an error, so we do nothing */
1035 case B_STATE_ACTIVATING:
1036 case B_STATE_EXPORTING:
1037 /* do nothing because we must wait until bchanenl is active before deactivating */
1040 case B_STATE_ACTIVE:
1041 /* bchannel is active, so we deactivate */
1042 _bchannel_activate(mISDNport, i, 0);
1043 state = B_STATE_DEACTIVATING;
1044 timer = now_d + B_TIMER_DEACTIVATING;
1047 case B_STATE_REMOTE:
1048 /* bchannel is exported, so we re-import */
1049 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
1050 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1051 add_trace("type", NULL, "remove");
1053 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1055 add_trace("socket", "id", "%d", portid);
1058 state = B_STATE_IMPORTING;
1061 case B_STATE_DEACTIVATING:
1062 case B_STATE_IMPORTING:
1063 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
1067 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1071 case B_EVENT_DEACTIVATED:
1076 /* ignore due to deactivation confirm after unloading */
1079 case B_STATE_DEACTIVATING:
1080 _bchannel_destroy(mISDNport, i);
1081 state = B_STATE_IDLE;
1084 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
1087 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);
1088 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1089 add_trace("type", NULL, "assign");
1091 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1093 add_trace("socket", "id", "%d", portid);
1096 state = B_STATE_EXPORTING;
1097 mISDNport->b_remote_id[i] = p_m_remote_id;
1098 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1101 if (_bchannel_create(mISDNport, i))
1103 _bchannel_activate(mISDNport, i, 1);
1104 state = B_STATE_ACTIVATING;
1105 timer = now_d + B_TIMER_ACTIVATING;
1112 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1116 case B_EVENT_IMPORTED:
1119 case B_STATE_IMPORTING:
1120 state = B_STATE_IDLE;
1121 mISDNport->b_remote_id[i] = 0;
1122 mISDNport->b_remote_ref[i] = 0;
1125 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
1128 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);
1129 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
1130 add_trace("type", NULL, "assign");
1132 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
1134 add_trace("socket", "id", "%d", portid);
1137 state = B_STATE_EXPORTING;
1138 mISDNport->b_remote_id[i] = p_m_remote_id;
1139 mISDNport->b_remote_ref[i] = p_m_remote_ref;
1142 if (_bchannel_create(mISDNport, i))
1144 _bchannel_activate(mISDNport, i, 1);
1145 state = B_STATE_ACTIVATING;
1146 timer = now_d + B_TIMER_ACTIVATING;
1153 /* ignore, because not assigned */
1158 case B_EVENT_TIMEOUT:
1163 /* ignore due to deactivation confirm after unloading */
1166 case B_STATE_ACTIVATING:
1167 _bchannel_activate(mISDNport, i, 1);
1168 timer = now_d + B_TIMER_ACTIVATING;
1171 case B_STATE_DEACTIVATING:
1172 _bchannel_activate(mISDNport, i, 0);
1173 timer = now_d + B_TIMER_DEACTIVATING;
1177 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
1182 PERROR("Illegal event %d, please correct.\n", event);
1185 mISDNport->b_state[i] = state;
1186 mISDNport->b_timer[i] = timer;
1193 * check for available channel and reserve+set it.
1194 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
1195 * give exclusiv flag
1196 * returns -(cause value) or x = channel x or 0 = no channel
1197 * NOTE: no activation is done here
1199 int PmISDN::seize_bchannel(int channel, int exclusive)
1203 /* the channel is what we have */
1204 if (p_m_b_channel == channel)
1207 /* if channel already in use, release it */
1212 if (channel==CHANNEL_NO || channel==0)
1215 /* is channel in range ? */
1217 || (channel>p_m_mISDNport->b_num && channel<16)
1218 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1219 return(-6); /* channel unacceptable */
1221 /* request exclusive channel */
1222 if (exclusive && channel>0)
1224 i = channel-1-(channel>16);
1225 if (p_m_mISDNport->b_port[i])
1226 return(-44); /* requested channel not available */
1230 /* ask for channel */
1233 i = channel-1-(channel>16);
1234 if (p_m_mISDNport->b_port[i] == NULL)
1238 /* search for channel */
1240 while(i < p_m_mISDNport->b_num)
1242 if (!p_m_mISDNport->b_port[i])
1244 channel = i+1+(i>=15);
1249 return(-34); /* no free channel */
1252 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1255 p_m_mISDNport->b_port[i] = this;
1257 p_m_b_channel = channel;
1258 p_m_b_exclusive = exclusive;
1260 /* reserve channel */
1264 p_m_mISDNport->b_reserved++;
1271 * drop reserved channel and unset it.
1272 * deactivation is also done
1274 void PmISDN::drop_bchannel(void)
1276 /* unreserve channel */
1278 p_m_mISDNport->b_reserved--;
1282 if (p_m_b_index < 0)
1287 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1289 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1290 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1291 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1294 p_m_b_exclusive = 0;
1297 /* process bchannel export/import message from join */
1298 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long handle)
1300 class Endpoint *epoint;
1302 class PmISDN *isdnport;
1303 struct mISDNport *mISDNport;
1308 case BCHANNEL_REQUEST:
1309 /* find the port object for the join object ref */
1310 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1312 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1315 if (!epoint->ep_portlist)
1317 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1320 if (epoint->ep_portlist->next)
1322 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);
1324 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1326 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1329 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1331 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1333 isdnport = (class PmISDN *)port;
1336 if (isdnport->p_m_remote_id)
1338 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1341 mISDNport = isdnport->p_m_mISDNport;
1342 i = isdnport->p_m_b_index;
1343 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1344 add_trace("type", NULL, "export request");
1345 isdnport->p_m_remote_ref = joinremote->j_serial;
1346 isdnport->p_m_remote_id = joinremote->j_remote_id;
1347 if (mISDNport && i>=0)
1349 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1354 case BCHANNEL_ASSIGN_ACK:
1355 case BCHANNEL_REMOVE_ACK:
1356 /* find mISDNport for stack ID */
1357 mISDNport = mISDNport_first;
1361 ii = mISDNport->b_num;
1365 if (mISDNport->b_socket[i] == handle)
1367 if ((unsigned long)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1374 mISDNport = mISDNport->next;
1378 PERROR("received assign/remove ack for handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1381 /* mISDNport may now be set or NULL */
1384 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1385 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1386 if (mISDNport && i>=0)
1387 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1391 PERROR("received wrong bchannel message type %d from remote\n", type);
1399 audio transmission procedure:
1400 -----------------------------
1403 three sources of audio transmission:
1404 - crypto-data high priority
1405 - tones high priority (also high)
1406 - remote-data low priority
1409 a variable that temporarily shows the number of samples elapsed since last transmission process.
1410 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1413 a variable that is increased whenever data is transmitted.
1414 it is decreased while time elapses. it stores the number of samples that
1415 are currently loaded to dsp module.
1416 since clock in dsp module is the same clock for user space process, these
1420 there are two levels:
1421 ISDN_LOAD will give the load that have to be kept in dsp.
1422 ISDN_MAXLOAD will give the maximum load before dropping.
1424 * procedure for low priority data
1425 see txfromup() for procedure
1426 in short: remote data is ignored during high priority tones
1428 * procedure for high priority data
1429 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1430 if no more data is available, load becomes empty again.
1433 0 ISDN_LOAD ISDN_MAXLOAD
1434 +--------------------+----------------------+
1436 +--------------------+----------------------+
1438 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1439 0 ISDN_LOAD ISDN_MAXLOAD
1440 +--------------------+----------------------+
1441 |TTTTTTTTTTTTTTTTTTTT| |
1442 +--------------------+----------------------+
1444 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1445 0 ISDN_LOAD ISDN_MAXLOAD
1446 +--------------------+----------------------+
1447 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1448 +--------------------+----------------------+
1451 int PmISDN::handler(void)
1453 struct message *message;
1457 if ((ret = Port::handler()))
1461 if (p_m_last_tv_sec)
1463 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1464 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1467 /* set clock of first process ever in this instance */
1468 p_m_last_tv_sec = now_tv.tv_sec;
1469 p_m_last_tv_msec = now_tv.tv_usec/1000;
1471 /* process only if we have a minimum of samples, to make packets not too small */
1472 if (elapsed >= ISDN_TRANSMIT)
1474 /* set clock of last process! */
1475 p_m_last_tv_sec = now_tv.tv_sec;
1476 p_m_last_tv_msec = now_tv.tv_usec/1000;
1479 if (elapsed < p_m_load)
1480 p_m_load -= elapsed;
1484 /* to send data, tone must be active OR crypt messages must be on */
1485 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1486 && (p_m_load < ISDN_LOAD)
1487 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1489 int tosend = ISDN_LOAD - p_m_load, length;
1491 unsigned char buf[MISDN_HEADER_LEN+tosend];
1492 struct mISDNhead *frm = (struct mISDNhead *)buf;
1493 unsigned long *d = buf+MISDN_HEADER_LEN;
1495 unsigned char buf[mISDN_HEADER_LEN+tosend];
1496 iframe_t *frm = (iframe_t *)buf;
1497 unsigned char *p = buf+mISDN_HEADER_LEN;
1500 /* copy crypto loops */
1501 while (p_m_crypt_msg_loops && tosend)
1503 /* how much do we have to send */
1504 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1507 if (length > tosend)
1510 /* copy message (part) to buffer */
1511 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1514 p_m_crypt_msg_current += length;
1515 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1518 p_m_crypt_msg_current = 0;
1519 p_m_crypt_msg_loops--;
1520 // puts("eine loop weniger");
1528 if (p_tone_name[0] && tosend)
1530 tosend -= read_audio(p, tosend);
1535 frm->prim = DL_DATA_REQ;
1537 ret = sendto(handle, buffer, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1539 PERROR("Failed to send to socket %d\n", handle);
1541 frm->prim = DL_DATA | REQUEST;
1542 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1544 frm->len = ISDN_LOAD - p_m_load - tosend;
1547 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1548 p_m_load += frm->len;
1552 // NOTE: deletion is done by the child class
1554 /* handle timeouts */
1557 if (p_m_timer+p_m_timeout < now_d)
1559 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1561 /* send timeout to endpoint */
1562 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1563 message->param.state = p_state;
1564 message_put(message);
1569 return(0); /* nothing done */
1574 * whenever we get audio data from bchannel, we process it here
1577 void PmISDN::bchannel_receive(mISDNhead *hh, unsigned char *data, int len)
1579 unsigned long cont = *((unsigned long *)data);
1581 void PmISDN::bchannel_receive(iframe_t *frm)
1584 unsigned long cont = *((unsigned long *)&frm->data.p);
1585 unsigned char *data =(unsigned char *)&frm->data.p;
1587 unsigned char *data_temp;
1588 unsigned long length_temp;
1589 struct message *message;
1594 if (hh->prim == PH_CONTROL_IND)
1596 if (frm->prim == (PH_CONTROL | INDICATION))
1601 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1604 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1606 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1607 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1609 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1610 message->param.dtmf = cont & DTMF_TONE_MASK;
1611 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1612 message_put(message);
1618 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1619 add_trace("DSP-CRYPT", NULL, "error");
1621 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1622 message->param.crypt.type = CC_ERROR_IND;
1623 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1624 message_put(message);
1628 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1629 add_trace("DSP-CRYPT", NULL, "ok");
1631 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1632 message->param.crypt.type = CC_ACTBF_CONF;
1633 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1634 message_put(message);
1638 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1639 add_trace("unknown", NULL, "0x%x", cont);
1645 if (hh->prim == PH_SIGNAL_IND)
1647 if (frm->prim == (PH_SIGNAL | INDICATION))
1656 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1657 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1660 /* see below (same condition) */
1661 if (p_state!=PORT_STATE_CONNECT
1662 && !p_m_mISDNport->tones)
1664 // printf(".");fflush(stdout);return;
1666 record(data, len, 1); // from up
1671 chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
1672 add_trace("unknown", NULL, "0x%x", frm->dinfo);
1678 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1680 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1682 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1684 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1688 /* calls will not process any audio data unless
1689 * the call is connected OR interface features audio during call setup.
1691 //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);
1692 #ifndef DEBUG_COREBRIDGE
1693 if (p_state!=PORT_STATE_CONNECT
1694 && !p_m_mISDNport->tones)
1698 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1701 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1707 record(data, len, 0); // from down
1709 /* randomize and listen to crypt message if enabled */
1710 if (p_m_crypt_listen)
1712 /* the noisy randomizer */
1716 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1718 cryptman_listen_bch(data, len);
1723 /* send data to epoint */
1724 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1730 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1731 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1732 memcpy(message->param.data.data, data_temp, message->param.data.len);
1733 message_put(message);
1734 if (length_temp <= sizeof(message->param.data.data))
1736 data_temp += sizeof(message->param.data.data);
1737 length_temp -= sizeof(message->param.data.data);
1746 void PmISDN::set_echotest(int echo)
1748 if (p_m_echo != echo)
1751 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1753 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1755 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);
1757 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);
1765 void PmISDN::set_tone(char *dir, char *tone)
1771 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1778 /* check if we NOT really have to use a dsp-tone */
1779 if (!options.dsptones)
1783 if (p_m_b_index >= 0)
1784 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1786 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1788 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1790 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1794 Port::set_tone(dir, tone);
1800 /* now we USE dsp-tone, convert name */
1801 else if (!strcmp(tone, "dialtone"))
1803 switch(options.dsptones) {
1804 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1805 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1806 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1808 } else if (!strcmp(tone, "dialpbx"))
1810 switch(options.dsptones) {
1811 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1812 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1813 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1815 } else if (!strcmp(tone, "ringing"))
1817 switch(options.dsptones) {
1818 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1819 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1820 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1822 } else if (!strcmp(tone, "ringpbx"))
1824 switch(options.dsptones) {
1825 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1826 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1827 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1829 } else if (!strcmp(tone, "busy"))
1832 switch(options.dsptones) {
1833 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1834 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1835 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1837 } else if (!strcmp(tone, "release"))
1840 switch(options.dsptones) {
1841 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1842 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1843 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1845 } else if (!strcmp(tone, "cause_10"))
1847 else if (!strcmp(tone, "cause_11"))
1849 else if (!strcmp(tone, "cause_22"))
1851 switch(options.dsptones) {
1852 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1853 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1854 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1856 } else if (!strncmp(tone, "cause_", 6))
1857 id = TONE_SPECIAL_INFO;
1861 /* if we have a tone that is not supported by dsp */
1862 if (id==TONE_OFF && tone[0])
1870 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1871 if (p_m_b_index >= 0)
1872 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1874 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?TONE_PATT_ON:TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1876 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);
1879 /* turn user-space tones off in cases of no tone OR dsp tone */
1880 Port::set_tone("",NULL);
1884 /* MESSAGE_mISDNSIGNAL */
1885 //extern struct message *dddebug;
1886 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1888 switch(param->mISDNsignal.message)
1890 case mISDNSIGNAL_VOLUME:
1891 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1893 p_m_tx_gain = param->mISDNsignal.tx_gain;
1894 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1895 if (p_m_b_index >= 0)
1896 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1898 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);
1900 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);
1903 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1904 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1906 p_m_rx_gain = param->mISDNsignal.rx_gain;
1907 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1908 if (p_m_b_index >= 0)
1909 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1911 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);
1913 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);
1916 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1919 case mISDNSIGNAL_CONF:
1920 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1921 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1922 if (p_m_conf != param->mISDNsignal.conf)
1924 p_m_conf = param->mISDNsignal.conf;
1925 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1926 if (p_m_b_index >= 0)
1927 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1929 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);
1931 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);
1934 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1935 /* we must set, even if currently tone forbids conf */
1936 p_m_conf = param->mISDNsignal.conf;
1937 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1940 case mISDNSIGNAL_JOINDATA:
1941 if (p_m_joindata != param->mISDNsignal.joindata)
1943 p_m_joindata = param->mISDNsignal.joindata;
1944 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1946 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1949 case mISDNSIGNAL_DELAY:
1950 if (p_m_delay != param->mISDNsignal.delay)
1952 p_m_delay = param->mISDNsignal.delay;
1953 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1955 if (p_m_b_index >= 0)
1956 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1958 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);
1960 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);
1964 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1968 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1973 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1975 struct message *message;
1977 switch(param->crypt.type)
1979 case CC_ACTBF_REQ: /* activate blowfish */
1981 p_m_crypt_key_len = param->crypt.len;
1982 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1984 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1985 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1986 message->param.crypt.type = CC_ERROR_IND;
1987 message_put(message);
1990 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1992 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1993 if (p_m_b_index >= 0)
1994 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1996 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);
1998 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);
2002 case CC_DACT_REQ: /* deactivate session encryption */
2007 case CR_LISTEN_REQ: /* start listening to messages */
2008 p_m_crypt_listen = 1;
2009 p_m_crypt_listen_state = 0;
2012 case CR_UNLISTEN_REQ: /* stop listening to messages */
2013 p_m_crypt_listen = 0;
2016 case CR_MESSAGE_REQ: /* send message */
2017 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
2018 if (!p_m_crypt_msg_len)
2020 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
2023 p_m_crypt_msg_current = 0; /* reset */
2024 p_m_crypt_msg_loops = 6; /* enable */
2026 /* disable txmix, or we get corrupt data due to audio process */
2027 if (p_m_txmix && p_m_b_index>=0)
2029 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
2031 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2033 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
2040 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
2046 * endpoint sends messages to the port
2048 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
2050 if (Port::message_epoint(epoint_id, message_id, param))
2055 case MESSAGE_DATA: /* tx-data from upper layer */
2056 txfromup(param->data.data, param->data.len);
2059 case MESSAGE_mISDNSIGNAL: /* user command */
2060 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
2061 message_mISDNsignal(epoint_id, message_id, param);
2064 case MESSAGE_CRYPT: /* crypt control command */
2065 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
2066 message_crypt(epoint_id, message_id, param);
2075 * main loop for processing messages from mISDN
2078 int mISDN_handler(void)
2081 struct mISDNport *mISDNport;
2082 class PmISDN *isdnport;
2084 char buffer[2048+MISDN_HEADER_LEN];
2085 struct mISDNhead *hh = (struct mISDNhead *)buffer;
2087 /* process all ports */
2088 mISDNport = mISDNport_first;
2091 /* process all bchannels */
2093 while(i < mISDNport->b_num)
2095 /* process timer events for bchannel handling */
2096 if (mISDNport->b_timer[i])
2098 if (mISDNport->b_timer[i] <= now_d)
2099 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2101 /* handle port of bchannel */
2102 isdnport=mISDNport->b_port[i];
2105 /* call bridges in user space OR crypto OR recording */
2106 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2108 /* rx IS required */
2109 if (isdnport->p_m_rxoff)
2112 isdnport->p_m_rxoff = 0;
2113 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2114 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2115 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2120 /* rx NOT required */
2121 if (!isdnport->p_m_rxoff)
2124 isdnport->p_m_rxoff = 1;
2125 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2126 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2127 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2132 if (isdnport->p_record)
2134 /* txdata IS required */
2135 if (!isdnport->p_m_txdata)
2138 isdnport->p_m_txdata = 1;
2139 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2140 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2141 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2146 /* txdata NOT required */
2147 if (isdnport->p_m_txdata)
2150 isdnport->p_m_txdata = 0;
2151 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2152 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2153 ph_control(mISDNport, isdnport, mISDNport->b_socket[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2159 /* handle message from bchannel */
2160 if (mISDNport->b_stack[i] > -1)
2162 ret = recv(mISDNport->b_stack[i], buffer, sizeof(buffer), 0);
2163 if (ret >= MISDN_HEADER_LEN)
2168 /* we don't care about confirms, we use rx data to sync tx */
2173 /* we receive audio data, we respond to it AND we send tones */
2177 case PH_CONTROL_IND:
2178 if (mISDNport->b_port[i])
2179 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2181 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_stack[i]);
2184 case PH_ACTIVATE_IND:
2185 case DL_ESTABLISH_IND:
2186 case PH_ACTIVATE_CONF:
2187 case DL_ESTABLISH_CONF:
2188 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
2189 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2192 case PH_DEACTIVATE_IND:
2193 case DL_RELEASE_IND:
2194 case PH_DEACTIVATE_CONF:
2195 case DL_RELEASE_CONF:
2196 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
2197 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2201 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], msg->len);
2205 if (ret < 0 && errno != EWOULDBLOCK)
2206 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
2213 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2215 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2216 mISDNport->l1timeout = 0;
2219 /* layer 2 establish timer */
2220 if (mISDNport->l2establish)
2222 if (now-mISDNport->l2establish > 5)
2225 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2226 mISDNport->ml3->to_layer2(mISDNport->ml3, DL_ESTABLISH_REQ);
2227 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_REQ, DIRECTION_OUT);
2234 mISDNport = mISDNport->next;
2237 /* if we received at least one b-frame, we will return 1 */
2241 int mISDN_handler(void)
2244 struct mISDNport *mISDNport;
2245 class PmISDN *isdnport;
2250 mISDNuser_head_t *hh;
2253 /* the que avoids loopbacks when replying to stack after receiving
2255 mISDNport = mISDNport_first;
2258 /* process turning on/off rx */
2260 while(i < mISDNport->b_num)
2262 /* process timer events for bchannel handling */
2263 if (mISDNport->b_timer[i])
2265 if (mISDNport->b_timer[i] <= now_d)
2266 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2268 isdnport=mISDNport->b_port[i];
2271 /* call bridges in user space OR crypto OR recording */
2272 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
2274 /* rx IS required */
2275 if (isdnport->p_m_rxoff)
2278 isdnport->p_m_rxoff = 0;
2279 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
2280 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2281 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
2286 /* rx NOT required */
2287 if (!isdnport->p_m_rxoff)
2290 isdnport->p_m_rxoff = 1;
2291 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
2292 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2293 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
2298 if (isdnport->p_record)
2300 /* txdata IS required */
2301 if (!isdnport->p_m_txdata)
2304 isdnport->p_m_txdata = 1;
2305 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
2307 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2308 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
2314 /* txdata NOT required */
2315 if (isdnport->p_m_txdata)
2318 isdnport->p_m_txdata = 0;
2319 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
2321 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
2322 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
2331 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2333 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2334 mISDNport->l1timeout = 0;
2337 if (mISDNport->l2establish)
2339 if (now-mISDNport->l2establish > 5)
2341 if (mISDNport->ntmode)
2343 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
2344 time(&mISDNport->l2establish);
2346 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2347 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2352 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
2353 time(&mISDNport->l2establish);
2355 act.prim = DL_ESTABLISH | REQUEST;
2356 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
2359 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2361 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
2366 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
2368 if (mISDNport->ntmode)
2370 hh = (mISDNuser_head_t *)dmsg->data;
2371 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);
2372 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2376 frm = (iframe_t *)dmsg->data;
2377 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
2378 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
2379 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);
2380 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
2385 mISDNport = mISDNport->next;
2388 /* no device, no read */
2389 if (mISDNdevice < 0)
2392 /* get message from kernel */
2393 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
2395 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
2399 if (errno == EAGAIN)
2401 FATAL("Failed to do mISDN_read()\n");
2406 // printf("%s: ERROR: mISDN_read() returns nothing\n");
2410 frm = (iframe_t *)msg->data;
2415 case MGR_DELLAYER | CONFIRM:
2416 case MGR_INITTIMER | CONFIRM:
2417 case MGR_ADDTIMER | CONFIRM:
2418 case MGR_DELTIMER | CONFIRM:
2419 case MGR_REMOVETIMER | CONFIRM:
2424 /* handle timer events from mISDN for NT-stack
2425 * note: they do not associate with a stack */
2426 if (frm->prim == (MGR_TIMER | INDICATION))
2430 /* find mISDNport */
2431 mISDNport = mISDNport_first;
2435 if (mISDNport->ntmode)
2437 it = mISDNport->nst.tlist;
2441 if (it->id == (int)frm->addr)
2448 mISDNport = mISDNport->next;
2452 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
2453 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
2455 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
2456 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
2457 ret = it->function(it->data);
2460 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
2465 /* find the mISDNport that belongs to the stack */
2466 mISDNport = mISDNport_first;
2469 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
2471 mISDNport = mISDNport->next;
2475 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2480 if (!(frm->addr&FLG_CHILD_STACK))
2485 case MGR_SHORTSTATUS | INDICATION:
2486 case MGR_SHORTSTATUS | CONFIRM:
2487 switch(frm->dinfo) {
2488 case SSTATUS_L1_ACTIVATED:
2489 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2492 case SSTATUS_L1_DEACTIVATED:
2493 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
2496 case SSTATUS_L2_ESTABLISHED:
2497 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
2500 case SSTATUS_L2_RELEASED:
2501 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
2507 case PH_ACTIVATE | CONFIRM:
2508 case PH_ACTIVATE | INDICATION:
2509 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2511 if (mISDNport->ntmode)
2513 mISDNport->l1link = 1;
2514 setup_queue(mISDNport, 1);
2518 mISDNport->l1link = 1;
2519 setup_queue(mISDNport, 1);
2522 case PH_DEACTIVATE | CONFIRM:
2523 case PH_DEACTIVATE | INDICATION:
2524 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2526 if (mISDNport->ntmode)
2528 mISDNport->l1link = 0;
2529 setup_queue(mISDNport, 0);
2533 mISDNport->l1link = 0;
2534 setup_queue(mISDNport, 0);
2537 case PH_CONTROL | CONFIRM:
2538 case PH_CONTROL | INDICATION:
2539 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2542 case DL_ESTABLISH | INDICATION:
2543 case DL_ESTABLISH | CONFIRM:
2544 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2546 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2548 if (mISDNport->l2establish)
2550 mISDNport->l2establish = 0;
2551 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2553 mISDNport->l2link = 1;
2556 case DL_RELEASE | INDICATION:
2557 case DL_RELEASE | CONFIRM:
2558 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2560 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2562 mISDNport->l2link = 0;
2565 time(&mISDNport->l2establish);
2566 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2572 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);
2573 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2575 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2578 if (mISDNport->ntmode)
2580 /* l1-data enters the nt-mode library */
2581 nst = &mISDNport->nst;
2582 if (nst->l1_l2(nst, msg))
2587 /* l3-data is sent to pbx */
2588 if (stack2manager_te(mISDNport, msg))
2599 /* we don't care about confirms, we use rx data to sync tx */
2600 case PH_DATA | CONFIRM:
2601 case DL_DATA | CONFIRM:
2604 /* we receive audio data, we respond to it AND we send tones */
2605 case PH_DATA | INDICATION:
2606 case DL_DATA | INDICATION:
2607 case PH_CONTROL | INDICATION:
2608 case PH_SIGNAL | INDICATION:
2610 while(i < mISDNport->b_num)
2612 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2616 if (i == mISDNport->b_num)
2618 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2621 if (mISDNport->b_port[i])
2623 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2624 mISDNport->b_port[i]->bchannel_receive(frm);
2626 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2629 case PH_ACTIVATE | INDICATION:
2630 case DL_ESTABLISH | INDICATION:
2631 case PH_ACTIVATE | CONFIRM:
2632 case DL_ESTABLISH | CONFIRM:
2633 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2635 while(i < mISDNport->b_num)
2637 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2641 if (i == mISDNport->b_num)
2643 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2646 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2649 case PH_DEACTIVATE | INDICATION:
2650 case DL_RELEASE | INDICATION:
2651 case PH_DEACTIVATE | CONFIRM:
2652 case DL_RELEASE | CONFIRM:
2653 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2655 while(i < mISDNport->b_num)
2657 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2661 if (i == mISDNport->b_num)
2663 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2666 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2670 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2681 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2683 struct mISDNport *mISDNport = ml3->private;
2685 if (cmd == MT_ASSIGN)
2691 achtung MT_ASSIGN kommt hier an
2697 case MGR_SHORTSTATUS_IND:
2698 case MGR_SHORTSTATUS_CONF:
2699 switch(frm->dinfo) {
2700 case SSTATUS_L1_ACTIVATED:
2701 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE_IND, DIRECTION_IN);
2704 case SSTATUS_L1_DEACTIVATED:
2705 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE_IND, DIRECTION_IN);
2708 case SSTATUS_L2_ESTABLISHED:
2709 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH_IND, DIRECTION_IN);
2712 case SSTATUS_L2_RELEASED:
2713 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE_IND, DIRECTION_IN);
2719 case PH_ACTIVATE_CONF:
2720 case PH_ACTIVATE_IND:
2721 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2724 mISDNport->l1link = 1;
2726 if (mISDNport->ntmode)
2727 setup_queue(mISDNport, 1);
2731 case PH_DEACTIVATE | CONFIRM:
2732 case PH_DEACTIVATE | INDICATION:
2733 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2736 mISDNport->l1link = 0;
2737 raus mit der setup-queue, da dies im stack geschieht
2739 if (mISDNport->ntmode)
2740 setup_queue(mISDNport, 0);
2744 case PH_CONTROL_CONFIRM:
2745 case PH_CONTROL_INDICATION:
2746 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2749 case DL_ESTABLISH_IND:
2750 case DL_ESTABLISH_CONF:
2751 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2753 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2755 if (mISDNport->l2establish)
2757 mISDNport->l2establish = 0;
2758 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2760 mISDNport->l2link = 1;
2763 case DL_RELEASE_IND:
2764 case DL_RELEASE_CONF:
2765 l1l2l3_trace_header(mISDNport, NULL, cmd, DIRECTION_IN);
2768 mISDNport->l2link = 0;
2771 time(&mISDNport->l2establish);
2772 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2777 /* l3-data is sent to LCR */
2778 message_from_mlayer3(mISDNport, cmd, pid, l3m);
2794 * global function to add a new card (port)
2796 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, int force_nt, struct interface *interface)
2799 unsigned char buff[1025];
2800 iframe_t *frm = (iframe_t *)buff;
2801 struct mISDNport *mISDNport, **mISDNportp;
2803 int pri, bri, ports;
2806 struct mlayer3 *ml3;
2807 struct mISDN_devinfo devinfo;
2809 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2812 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2816 // interface_info_t ii;
2820 stack_info_t *stinf;
2822 /* query port's requirements */
2823 cnt = mISDN_get_stack_count(mISDNdevice);
2828 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2831 if (port>cnt || port<1)
2833 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2837 pri = bri = ports = nt = te = 0;
2839 devinfo.id = port - 1;
2840 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
2843 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
2846 /* output the port info */
2847 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2852 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2858 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2865 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2872 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2879 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2885 if (force_nt && !nt)
2887 PERROR_RUNTIME("Port %d does not support NT-mode.\n", port);
2892 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2895 if (pots && !bri && !pri)
2897 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2902 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2907 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2910 /* force nt, by turning off TE */
2913 /* if TE an NT is supported (and not forced to NT), turn off NT */
2917 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2920 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2923 stinf = (stack_info_t *)&frm->data.p;
2924 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2926 case ISDN_PID_L0_TE_S0:
2927 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2929 case ISDN_PID_L0_NT_S0:
2930 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2933 case ISDN_PID_L0_TE_E1:
2934 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2937 case ISDN_PID_L0_NT_E1:
2938 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2943 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2949 if (stinf->pid.protocol[1] == 0)
2951 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2954 if (stinf->pid.protocol[2])
2956 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2963 if (stinf->pid.protocol[1] == 0)
2965 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2968 if (stinf->pid.protocol[2] == 0)
2970 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2973 if (stinf->pid.protocol[3] == 0)
2975 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2979 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2981 case ISDN_PID_L3_DSS1USER:
2985 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2989 if (stinf->pid.protocol[4])
2991 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2997 /* add mISDNport structure */
2998 mISDNportp = &mISDNport_first;
3000 mISDNportp = &((*mISDNportp)->next);
3001 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
3003 *mISDNportp = mISDNport;
3005 /* allocate ressources of port */
3008 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
3013 prop |= FLG_FORCE_PTMP;
3014 mISDNport->ml3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
3015 if (!mISDNport->ml3)
3017 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3022 /* if ntmode, establish L1 to send the tei removal during start */
3023 if (mISDNport->ntmode)
3027 act.prim = PH_ACTIVATE | REQUEST;
3028 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3029 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3032 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3033 usleep(10000); /* to be sure, that l1 is up */
3037 SCPY(mISDNport->name, devinfo.name);
3038 mISDNport->b_num = devinfo.nrbchan;
3040 msg_queue_init(&mISDNport->downqueue);
3041 mISDNport->d_stid = stinf->id;
3042 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
3043 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
3045 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
3049 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
3054 /* create layer intance */
3055 memset(&li, 0, sizeof(li));
3056 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
3059 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
3060 li.pid.layermask = ISDN_LAYER((nt?2:4));
3061 li.st = mISDNport->d_stid;
3062 ret = mISDN_new_layer(mISDNdevice, &li);
3065 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
3067 mISDNport_close(mISDNport);
3070 mISDNport->upper_id = li.id;
3071 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
3074 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
3077 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
3078 if (mISDNport->lower_id < 0)
3080 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
3083 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
3084 if (mISDNport->upper_id < 0)
3086 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
3089 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
3091 /* if ntmode, establish L1 to send the tei removal during start */
3092 if (mISDNport->ntmode)
3096 act.prim = PH_ACTIVATE | REQUEST;
3097 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
3098 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
3101 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3102 usleep(10000); /* to be sure, that l1 is up */
3105 /* create nst (nt-mode only) */
3108 mgr = &mISDNport->mgr;
3109 nst = &mISDNport->nst;
3114 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
3115 nst->device = mISDNdevice;
3117 nst->d_stid = mISDNport->d_stid;
3119 nst->feature = FEATURE_NET_HOLD;
3121 nst->feature |= FEATURE_NET_PTP;
3123 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
3126 while(i < mISDNport->b_num)
3128 nst->b_stid[i] = mISDNport->b_stid[i];
3132 nst->l1_id = mISDNport->lower_id;
3133 nst->l2_id = mISDNport->upper_id;
3136 msg_queue_init(&nst->down_queue);
3142 mISDNport->b_num = stinf->childcnt;
3144 mISDNport->portnum = port;
3145 mISDNport->ntmode = nt;
3146 mISDNport->pri = pri;
3147 mISDNport->ptp = ptp;
3148 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
3150 while(i < mISDNport->b_num)
3152 mISDNport->b_state[i] = B_STATE_IDLE;
3154 mISDNport->b_socket = -1;
3156 mISDNport->b_stid[i] = stinf->child[i];
3157 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
3162 /* if te-mode, query state link */
3163 if (!mISDNport->ntmode)
3167 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
3168 act.prim = MGR_SHORTSTATUS | REQUEST;
3169 act.addr = mISDNport->upper_id | MSG_BROADCAST;
3170 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
3172 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3174 /* if ptp AND te-mode, pull up the link */
3175 if (mISDNport->ptp && !mISDNport->ntmode)
3179 act.prim = DL_ESTABLISH | REQUEST;
3180 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
3183 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
3185 /* if ptp AND nt-mode, pull up the link */
3186 if (mISDNport->ptp && mISDNport->ntmode)
3190 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
3191 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
3194 /* initially, we assume that the link is down, exept for nt-ptmp */
3195 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
3197 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
3199 start_trace(mISDNport->portnum,
3207 add_trace("channels", NULL, "%d", mISDNport->b_num);
3214 * function to free ALL cards (ports)
3216 void mISDNport_close_all(void)
3218 /* free all ports */
3219 while(mISDNport_first)
3220 mISDNport_close(mISDNport_first);
3224 * free only one port
3226 void mISDNport_close(struct mISDNport *mISDNport)
3228 struct mISDNport **mISDNportp;
3230 class PmISDN *isdnport;
3232 unsigned char buf[32];
3235 /* remove all port instance that are linked to this mISDNport */
3239 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
3241 isdnport = (class PmISDN *)port;
3242 if (isdnport->p_m_mISDNport)
3244 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
3251 /* only if we are already part of interface */
3252 if (mISDNport->ifport)
3254 start_trace(mISDNport->portnum,
3255 mISDNport->ifport->interface,
3265 /* free bchannels */
3267 while(i < mISDNport->b_num)
3269 if (mISDNport->b_addr[i])
3271 _bchannel_destroy(mISDNport, i);
3272 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
3278 close_layer3(mISDNport->ml3);
3280 /* free ressources of port */
3281 msg_queue_purge(&mISDNport->downqueue);
3284 if (mISDNport->ntmode)
3286 nst = &mISDNport->nst;
3287 if (nst->manager) /* to see if initialized */
3289 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");
3290 cleanup_Isdnl3(nst);
3291 cleanup_Isdnl2(nst);
3294 msg_queue_purge(&nst->down_queue);
3295 if (nst->phd_down_msg)
3296 FREE(nst->phd_down_msg, 0);
3300 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
3301 if (mISDNport->d_stid)
3303 if (mISDNport->upper_id)
3304 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
3308 /* remove from list */
3309 mISDNportp = &mISDNport_first;
3312 if (*mISDNportp == mISDNport)
3314 *mISDNportp = (*mISDNportp)->next;
3318 mISDNportp = &((*mISDNportp)->next);
3322 FATAL("mISDNport not in list\n");
3324 FREE(mISDNport, sizeof(struct mISDNport));
3331 * global function to show all available isdn ports
3333 void mISDN_port_info(void)
3337 int useable, nt, te, pri, bri, pots;
3338 unsigned char buff[1025];
3339 iframe_t *frm = (iframe_t *)buff;
3341 struct mISDN_devinfo devinfo;
3345 socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
3348 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
3352 /* get number of stacks */
3354 ret = ioctl(socket, IMGETCOUNT, &ii);
3357 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
3361 stack_info_t *stinf;
3365 if ((device = mISDN_open()) < 0)
3367 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));
3371 /* get number of stacks */
3373 ii = mISDN_get_stack_count(device);
3378 printf("Found no card. Please be sure to load card drivers.\n");
3382 /* loop the number of cards and get their info */
3385 nt = te = bri = pri = pots = 0;
3390 ret = ioctl(socket, IMGETDEVINFO, &devinfo);
3393 fprintf(stderr, "Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", i, ret);
3397 /* output the port info */
3398 printf("Port %2d name='%s': ", i, devinfo.name);
3399 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
3404 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
3410 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
3417 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
3424 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
3431 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
3437 if ((te || nt) && (bri || pri || ports))
3441 printf("TE-mode BRI S/T interface line (for phone lines)");
3443 printf("NT-mode BRI S/T interface port (for phones)");
3445 printf("TE-mode PRI E1 interface line (for phone lines)");
3447 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3449 printf("FXS POTS interface port (for analog lines)");
3451 printf("FXO POTS interface port (for analog phones)");
3455 printf("\n -> Analog interfaces are not supported.");
3459 printf("unsupported interface protocol bits 0x%016x", devinfo.Dprotocols);
3463 printf(" - %d B-channels\n", devinfo.nfbchan);
3465 ret = mISDN_get_stack_info(device, i, buff, sizeof(buff));
3468 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d error=%d\n", i, ret);
3471 stinf = (stack_info_t *)&frm->data.p;
3473 /* output the port info */
3474 printf("Port %2d: ", i);
3475 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
3477 case ISDN_PID_L0_TE_S0:
3481 printf("TE-mode BRI S/T interface line (for phone lines)");
3483 case ISDN_PID_L0_NT_S0:
3487 printf("NT-mode BRI S/T interface port (for phones)");
3489 case ISDN_PID_L0_TE_E1:
3493 printf("TE-mode PRI E1 interface line (for phone lines)");
3495 case ISDN_PID_L0_NT_E1:
3499 printf("NT-mode PRI E1 interface port (for E1 terminals)");
3503 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
3509 if (stinf->pid.protocol[1] == 0)
3512 printf(" -> Missing layer 1 NT-mode protocol.\n");
3515 while(p <= MAX_LAYER_NR) {
3516 if (stinf->pid.protocol[p])
3519 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3526 printf(" -> Interface is Point-To-Point (PRI).\n");
3528 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
3533 if (stinf->pid.protocol[1] == 0)
3536 printf(" -> Missing layer 1 protocol.\n");
3538 if (stinf->pid.protocol[2] == 0)
3541 printf(" -> Missing layer 2 protocol.\n");
3543 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
3545 printf(" -> Interface is Poin-To-Point.\n");
3547 if (stinf->pid.protocol[3] == 0)
3550 printf(" -> Missing layer 3 protocol.\n");
3553 printf(" -> Protocol: ");
3554 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
3556 case ISDN_PID_L3_DSS1USER:
3557 printf("DSS1 (Euro ISDN)");
3562 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
3567 while(p <= MAX_LAYER_NR) {
3568 if (stinf->pid.protocol[p])
3571 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
3576 printf(" - %d B-channels\n", stinf->childcnt);
3580 printf(" * Port NOT useable for LCR\n");
3582 printf("--------\n");
3593 if ((ret = mISDN_close(device)))
3594 FATAL("mISDN_close() failed: err=%d '%s'\n", ret, strerror(ret));
3600 * enque data from upper buffer
3602 void PmISDN::txfromup(unsigned char *data, int length)
3605 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3606 struct mISDNhead *frm = (struct mISDNhead *)buf;
3608 if (p_m_b_index < 0)
3610 if (!p_m_mISDNport->b_socket[p_m_b_index])
3613 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
3614 iframe_t *frm = (iframe_t *)buf;
3616 if (p_m_b_index < 0)
3618 if (!p_m_mISDNport->b_addr[p_m_b_index])
3622 /* check if high priority tones exist
3623 * ignore data in this case
3625 if (p_tone_name[0] || p_m_crypt_msg_loops)
3628 /* preload procedure
3629 * if transmit buffer in DSP module is empty,
3630 * preload it to DSP_LOAD to prevent jitter gaps.
3632 if (p_m_load==0 && ISDN_LOAD>0)
3635 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
3636 frm->len = ISDN_LOAD;
3637 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
3638 p_m_load += frm->len;
3641 /* drop if load would exceed ISDN_MAXLOAD
3642 * this keeps the delay not too high
3644 if (p_m_load+length > ISDN_MAXLOAD)
3647 /* make and send frame */
3649 frm->prim = DL_DATA_REQ;
3651 memcpy(buf+MISDN_HEADER_LEN, data, length);
3652 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
3654 PERROR("Failed to send to socket %d\n", handle);
3656 frm->prim = DL_DATA | REQUEST;
3657 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
3660 memcpy(buf+mISDN_HEADER_LEN, data, length);
3661 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);