1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
16 #include <sys/ioctl.h>
17 #include <sys/types.h>
21 #include <netinet/udp.h>
22 #include <netinet/in.h>
24 #include <sys/socket.h>
26 #include <linux/mISDNif.h>
35 #ifndef ISDN_PID_L4_B_USER
36 #define ISDN_PID_L4_B_USER 0x440000ff
39 /* list of mISDN ports */
40 struct mISDNport *mISDNport_first;
42 /* noise randomizer */
43 unsigned char mISDN_rand[256];
44 int mISDN_rand_count = 0;
47 int mISDN_initialize(void)
49 /* try to open raw socket to check kernel */
50 ret = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
53 fprintf(stderr, "Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
58 init_layer3(4); // buffer of 4
63 void mISDN_deinitialize(void)
68 int entity = 0; /* used for udevice */
69 int mISDNdevice = -1; /* the device handler and port list */
71 int mISDN_initialize(void)
74 unsigned char buff[1025];
75 iframe_t *frm = (iframe_t *)buff;
78 /* initialize stuff of the NT lib */
79 if (options.deb & DEBUG_STACK)
81 global_debug = 0xffffffff & ~DBGM_MSG;
82 // global_debug = DBGM_L3DATA;
84 global_debug = DBGM_MAN;
85 SPRINT(debug_log, "%s/debug.log", INSTALL_DATA);
86 if (options.deb & DEBUG_LOG)
87 debug_init(global_debug, debug_log, debug_log, debug_log);
89 debug_init(global_debug, NULL, NULL, NULL);
92 /* open mISDNdevice if not already open */
98 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));
102 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
104 /* create entity for layer 3 TE-mode */
105 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
106 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
107 if (ret < (int)mISDN_HEADER_LEN)
110 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
112 entity = frm->dinfo & 0xffff;
115 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
120 void mISDN_deinitialize(void)
122 unsigned char buff[1025];
126 if (mISDNdevice >= 0)
129 mISDN_write_frame(mISDNdevice, buff, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
131 mISDN_close(mISDNdevice);
133 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
141 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
143 p_m_mISDNport = mISDNport;
144 p_m_portnum = mISDNport->portnum;
151 p_m_txvol = p_m_rxvol = 0;
159 p_m_dtmf = !mISDNport->ifport->nodtmf;
162 p_m_remote_ref = 0; /* channel shall be exported to given remote */
163 p_m_remote_id = 0; /* channel shall be exported to given remote */
171 p_m_crypt_listen = 0;
172 p_m_crypt_msg_loops = 0;
173 p_m_crypt_msg_loops = 0;
174 p_m_crypt_msg_len = 0;
175 p_m_crypt_msg[0] = '\0';
176 p_m_crypt_msg_current = 0;
177 p_m_crypt_key[0] = '\0';
178 p_m_crypt_key_len = 0;
179 p_m_crypt_listen = 0;
180 p_m_crypt_listen_state = 0;
181 p_m_crypt_listen_len = 0;
182 p_m_crypt_listen_msg[0] = '\0';
183 p_m_crypt_listen_crc = 0;
185 /* if any channel requested by constructor */
186 if (channel == CHANNEL_ANY)
188 /* reserve channel */
190 mISDNport->b_reserved++;
193 /* reserve channel */
194 if (channel > 0) // only if constructor was called with a channel resevation
195 seize_bchannel(channel, exclusive);
197 /* we increase the number of objects: */
199 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
208 struct message *message;
210 /* remove bchannel relation */
216 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
217 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
218 message->param.disconnectinfo.cause = 16;
219 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
220 message_put(message);
221 /* remove from list */
222 free_epointlist(p_epointlist);
225 /* we decrease the number of objects: */
226 p_m_mISDNport->use--;
227 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
234 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
236 /* init trace with given values */
237 start_trace(mISDNport?mISDNport->portnum:0,
238 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
239 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
240 port?port->p_dialinginfo.id:NULL,
243 port?port->p_serial:0,
251 static struct isdn_message {
255 {"TIMEOUT", CC_TIMEOUT},
257 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
258 {"PROCEEDING", CC_PROCEEDING},
259 {"ALERTING", CC_ALERTING},
260 {"CONNECT", CC_CONNECT},
261 {"CONNECT RES", CC_CONNECT},
262 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
263 {"DISCONNECT", CC_DISCONNECT},
264 {"RELEASE", CC_RELEASE},
265 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
266 {"INFORMATION", CC_INFORMATION},
267 {"PROGRESS", CC_PROGRESS},
268 {"NOTIFY", CC_NOTIFY},
269 {"SUSPEND", CC_SUSPEND},
270 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
271 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
272 {"RESUME", CC_RESUME},
273 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
274 {"RESUME_REJ", CC_RESUME_REJECT},
276 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
277 {"HOLD_REJ", CC_HOLD_REJECT},
278 {"RETRIEVE", CC_RETRIEVE},
279 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
280 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
281 {"FACILITY", CC_FACILITY},
282 {"STATUS", CC_STATUS},
283 {"RESTART", CC_RESTART},
284 {"RELEASE_CR", CC_RELEASE_CR},
285 {"NEW_CR", CC_NEW_CR},
286 {"DL_ESTABLISH", DL_ESTABLISH},
287 {"DL_RELEASE", DL_RELEASE},
288 {"PH_ACTIVATE", PH_ACTIVATE},
289 {"PH_DEACTIVATE", PH_DEACTIVATE},
293 static char *isdn_prim[4] = {
299 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
302 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
304 /* select message and primitive text */
306 while(isdn_message[i].name)
308 if (isdn_message[i].value == (prim&0xffffff00))
310 SCPY(msgtext, isdn_message[i].name);
315 SCAT(msgtext, isdn_prim[prim&0x00000003]);
318 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
322 if (mISDNport->ntmode)
324 if (direction == DIRECTION_OUT)
325 SCAT(msgtext, " N->U");
327 SCAT(msgtext, " N<-U");
330 if (direction == DIRECTION_OUT)
331 SCAT(msgtext, " U->N");
333 SCAT(msgtext, " U<-N");
338 /* init trace with given values */
339 start_trace(mISDNport?mISDNport->portnum:0,
340 mISDNport?mISDNport->ifport->interface:NULL,
341 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
342 port?port->p_dialinginfo.id:NULL,
345 port?port->p_serial:0,
351 * send control information to the channel (dsp-module)
353 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, int c2, char *trace_name, int trace_value)
355 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
356 iframe_t *ctrl = (iframe_t *)buffer;
357 unsigned long *d = (unsigned long *)&ctrl->data.p;
359 ctrl->prim = PH_CONTROL | REQUEST;
360 ctrl->addr = b_addr | FLG_MSG_DOWN;
362 ctrl->len = sizeof(int)*2;
365 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
366 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
367 if (c1 == CMX_CONF_JOIN)
368 add_trace(trace_name, NULL, "0x%08x", trace_value);
370 add_trace(trace_name, NULL, "%d", trace_value);
374 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, void *c2, int c2_len, char *trace_name, int trace_value)
376 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
377 iframe_t *ctrl = (iframe_t *)buffer;
378 unsigned long *d = (unsigned long *)&ctrl->data.p;
380 ctrl->prim = PH_CONTROL | REQUEST;
381 ctrl->addr = b_addr | FLG_MSG_DOWN;
383 ctrl->len = sizeof(int)+c2_len;
385 memcpy(d, c2, c2_len);
386 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
387 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
388 add_trace(trace_name, NULL, "%d", trace_value);
394 * subfunction for bchannel_event
397 static int _bchannel_create(struct mISDNport *mISDNport, int i)
399 unsigned char buff[1024];
404 if (!mISDNport->b_stid[i])
406 PERROR("Error: no stack for index %d\n", i);
409 if (mISDNport->b_addr[i])
411 PERROR("Error: stack already created for index %d\n", i);
415 /* create new layer */
416 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
417 memset(&li, 0, sizeof(li));
418 memset(&pid, 0, sizeof(pid));
421 li.st = mISDNport->b_stid[i];
422 UCPY(li.name, "B L4");
423 li.pid.layermask = ISDN_LAYER((4));
424 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
425 ret = mISDN_new_layer(mISDNdevice, &li);
429 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
432 mISDNport->b_addr[i] = li.id;
435 goto failed_new_layer;
437 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
439 /* create new stack */
440 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
441 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
442 pid.protocol[3] = ISDN_PID_L3_B_DSP;
443 pid.protocol[4] = ISDN_PID_L4_B_USER;
444 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
445 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
449 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
450 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
453 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
458 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
459 if (!mISDNport->b_addr[i])
461 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
462 add_trace("channel", NULL, "%d", i+1+(i>=15));
463 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
464 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
470 mISDNport->b_addr[i] = 0;
476 * subfunction for bchannel_event
477 * activate / deactivate request
479 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
483 /* activate bchannel */
484 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
485 add_trace("channel", NULL, "%d", i+1+(i>=15));
487 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
488 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
491 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
496 * subfunction for bchannel_event
499 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
504 port = mISDNport->b_port[i];
505 addr = mISDNport->b_addr[i];
508 PERROR("bchannel index i=%d not associated with a port object\n", i);
512 /* set dsp features */
513 if (port->p_m_txdata)
514 ph_control(mISDNport, port, addr, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
516 ph_control(mISDNport, port, addr, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
518 ph_control(mISDNport, port, addr, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
520 ph_control(mISDNport, port, addr, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
522 ph_control(mISDNport, port, addr, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
524 ph_control(mISDNport, port, addr, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
526 ph_control(mISDNport, port, addr, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
528 ph_control(mISDNport, port, addr, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
529 // if (port->p_m_txmix)
530 // ph_control(mISDNport, port, addr, CMX_MIX_ON, 0, "DSP-MIX", 1);
532 ph_control(mISDNport, port, addr, DTMF_TONE_START, 0, "DSP-DTMF", 1);
534 ph_control_block(mISDNport, port, addr, BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
538 * subfunction for bchannel_event
541 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
543 unsigned char buff[1024];
545 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
546 add_trace("channel", NULL, "%d", i+1+(i>=15));
547 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
548 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
550 /* remove our stack only if set */
551 if (mISDNport->b_addr[i])
553 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
554 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
555 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
556 mISDNport->b_addr[i] = 0;
565 A bchannel goes through the following states in this order:
568 No one is using the bchannel.
569 It is available and not linked to Port class, nor reserved.
572 The bchannel stack is created and an activation request is sent.
573 It MAY be linked to Port class, but already unlinked due to Port class removal.
576 The bchannel is active and cofigured to the Port class needs.
577 Also it is linked to a Port class, otherwhise it would be deactivated.
579 - B_STATE_DEACTIVATING
580 The bchannel is in deactivating state, due to deactivation request.
581 It may be linked to a Port class, that likes to reactivate it.
585 After deactivating bchannel, and if not used, the bchannel becomes idle again.
587 Also the bchannel may be exported, but only if the state is or becomes idle:
590 The bchannel assignment has been sent to the remove application.
593 The bchannel assignment is acknowledged by the remote application.
596 The bchannel is re-imported by mISDN port object.
600 After re-importing bchannel, and if not used, the bchannel becomes idle again.
603 A bchannel can have the following events:
606 A bchannel is required by a Port class.
607 The bchannel shall be exported to the remote application.
610 The bchannel beomes active.
613 The bchannel is not required by Port class anymore
615 - B_EVENT_DEACTIVATED
616 The bchannel becomes inactive.
619 The bchannel is now used by remote application.
622 The bchannel is not used by remote application.
624 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
626 if an export request is receive by remote application, p_m_exportremote is set.
627 the b_remotejoin[index] indicates if linked port shall be exported.
628 - set on export request from remote application (if port is assigned)
629 - set on channel use, if requested by remote application (p_m_exportremote)
630 - cleared on drop request
632 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
633 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
634 the bchannel import/export is acknowledged with stack given.
636 if exporting, b_remotesocket[index] is set to the remote socket id.
637 if importing has been acknowledged. b_remotesockt[index] is cleared.
642 * process bchannel events
643 * - mISDNport is a pointer to the port's structure
644 * - i is the index of the bchannel
645 * - event is the B_EVENT_* value
646 * - port is the PmISDN class pointer
648 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
650 class PmISDN *b_port = mISDNport->b_port[i];
651 int state = mISDNport->b_state[i];
652 unsigned long p_m_remote_ref = 0;
653 unsigned long p_m_remote_id = 0;
654 unsigned long addr = mISDNport->b_addr[i];
658 p_m_remote_id = b_port->p_m_remote_id;
659 p_m_remote_ref = b_port->p_m_remote_ref;
665 /* port must be linked in order to allow activation */
667 FATAL("bchannel must be linked to a Port class\n");
673 /* export bchannel */
674 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, addr);
675 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
676 add_trace("type", NULL, "assign");
677 add_trace("stack", "address", "%x", addr);
679 state = B_STATE_EXPORTING;
680 mISDNport->b_remote_id[i] = p_m_remote_id;
683 /* create stack and send activation request */
684 if (_bchannel_create(mISDNport, i))
686 _bchannel_activate(mISDNport, i, 1);
687 state = B_STATE_ACTIVATING;
692 case B_STATE_ACTIVATING:
693 case B_STATE_EXPORTING:
694 /* do nothing, because it is already activating */
697 case B_STATE_DEACTIVATING:
698 case B_STATE_IMPORTING:
699 /* do nothing, because we must wait until we can reactivate */
703 /* problems that might ocurr:
704 * B_EVENT_USE is received when channel already in use.
705 * bchannel exported, but not freed by other port
707 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
711 case B_EVENT_EXPORTREQUEST:
712 /* special case where the bchannel is requested by remote */
715 PERROR("export request without remote channel set, please correct.\n");
721 /* in case, the bchannel is exported right after seize_bchannel */
722 /* export bchannel */
723 /* p_m_remote_id is set, when this event happens. */
724 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, addr);
725 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
726 add_trace("type", NULL, "assign");
727 add_trace("stack", "address", "%x", addr);
729 state = B_STATE_EXPORTING;
730 mISDNport->b_remote_id[i] = p_m_remote_id;
733 case B_STATE_ACTIVATING:
734 case B_STATE_EXPORTING:
735 /* do nothing, because it is already activating */
738 case B_STATE_DEACTIVATING:
739 case B_STATE_IMPORTING:
740 /* do nothing, because we must wait until we can reactivate */
744 /* bchannel is active, so we deactivate */
745 _bchannel_activate(mISDNport, i, 0);
746 state = B_STATE_DEACTIVATING;
750 /* problems that might ocurr:
751 * ... when channel already in use.
752 * bchannel exported, but not freed by other port
754 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
758 case B_EVENT_ACTIVATED:
761 case B_STATE_ACTIVATING:
762 if (b_port && !p_m_remote_id)
764 /* bchannel is active and used by Port class, so we configure bchannel */
765 _bchannel_configure(mISDNport, i);
766 state = B_STATE_ACTIVE;
769 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
770 _bchannel_activate(mISDNport, i, 0);
771 state = B_STATE_DEACTIVATING;
776 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
780 case B_EVENT_EXPORTED:
783 case B_STATE_EXPORTING:
784 if (b_port && p_m_remote_id)
786 /* remote export done */
787 state = B_STATE_REMOTE;
790 /* bchannel is now exported, but we need bchannel back OR bchannel is not used anymore, so reimport, to later export to new remote */
791 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, addr);
792 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
793 add_trace("type", NULL, "remove");
794 add_trace("stack", "address", "%x", addr);
796 state = B_STATE_IMPORTING;
801 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
807 FATAL("bchannel must be linked to a Port class\n");
811 /* bchannel is idle due to an error, so we do nothing */
814 case B_STATE_ACTIVATING:
815 case B_STATE_EXPORTING:
816 /* do nothing because we must wait until bchanenl is active before deactivating */
820 /* bchannel is active, so we deactivate */
821 _bchannel_activate(mISDNport, i, 0);
822 state = B_STATE_DEACTIVATING;
826 /* bchannel is exported, so we re-import */
827 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, addr);
828 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
829 add_trace("type", NULL, "remove");
830 add_trace("stack", "address", "%x", addr);
832 state = B_STATE_IMPORTING;
835 case B_STATE_DEACTIVATING:
836 case B_STATE_IMPORTING:
837 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
841 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
845 case B_EVENT_DEACTIVATED:
849 /* ignore due to deactivation confirm after unloading */
852 case B_STATE_DEACTIVATING:
853 _bchannel_destroy(mISDNport, i);
854 state = B_STATE_IDLE;
857 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
860 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, addr);
861 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
862 add_trace("type", NULL, "assign");
863 add_trace("stack", "address", "%x", addr);
865 state = B_STATE_EXPORTING;
866 mISDNport->b_remote_id[i] = p_m_remote_id;
869 if (_bchannel_create(mISDNport, i))
871 _bchannel_activate(mISDNport, i, 1);
872 state = B_STATE_ACTIVATING;
879 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
883 case B_EVENT_IMPORTED:
886 case B_STATE_IMPORTING:
887 state = B_STATE_IDLE;
888 mISDNport->b_remote_id[i] = 0;
891 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
894 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, addr);
895 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
896 add_trace("type", NULL, "assign");
897 add_trace("stack", "address", "%x", addr);
899 state = B_STATE_EXPORTING;
900 mISDNport->b_remote_id[i] = p_m_remote_id;
903 if (_bchannel_create(mISDNport, i))
905 _bchannel_activate(mISDNport, i, 1);
906 state = B_STATE_ACTIVATING;
913 /* ignore, because not assigned */
919 PERROR("Illegal event %d, please correct.\n", event);
922 mISDNport->b_state[i] = state;
929 * check for available channel and reserve+set it.
930 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
932 * returns -(cause value) or x = channel x or 0 = no channel
933 * NOTE: no activation is done here
935 int PmISDN::seize_bchannel(int channel, int exclusive)
939 /* the channel is what we have */
940 if (p_m_b_channel == channel)
943 /* if channel already in use, release it */
948 if (channel==CHANNEL_NO || channel==0)
951 /* is channel in range ? */
953 || (channel>p_m_mISDNport->b_num && channel<16)
954 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
955 return(-6); /* channel unacceptable */
957 /* request exclusive channel */
958 if (exclusive && channel>0)
960 i = channel-1-(channel>16);
961 if (p_m_mISDNport->b_port[i])
962 return(-44); /* requested channel not available */
966 /* ask for channel */
969 i = channel-1-(channel>16);
970 if (p_m_mISDNport->b_port[i] == NULL)
974 /* search for channel */
976 while(i < p_m_mISDNport->b_num)
978 if (!p_m_mISDNport->b_port[i])
980 channel = i+1+(i>=15);
985 return(-34); /* no free channel */
988 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
991 p_m_mISDNport->b_port[i] = this;
993 p_m_b_channel = channel;
994 p_m_b_exclusive = exclusive;
996 /* reserve channel */
1000 p_m_mISDNport->b_reserved++;
1007 * drop reserved channel and unset it.
1008 * deactivation is also done
1010 void PmISDN::drop_bchannel(void)
1012 if (p_m_b_index < 0)
1015 /* unreserve channel */
1017 p_m_mISDNport->b_reserved--;
1024 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1026 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1027 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1028 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1031 p_m_b_exclusive = 0;
1034 /* process bchannel export/import message from join */
1035 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long addr)
1037 class Endpoint *epoint;
1039 class PmISDN *isdnport;
1040 struct mISDNport *mISDNport;
1045 case BCHANNEL_REQUEST:
1046 /* find the port object for the join object ref */
1047 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1049 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1052 if (!epoint->ep_portlist)
1054 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1057 if (epoint->ep_portlist->next)
1059 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);
1061 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1063 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1066 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1068 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1070 isdnport = (class PmISDN *)port;
1073 if (isdnport->p_m_remote_id)
1075 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1078 mISDNport = isdnport->p_m_mISDNport;
1079 i = isdnport->p_m_b_index;
1080 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1081 add_trace("type", NULL, "export request");
1082 isdnport->p_m_remote_ref = joinremote->j_serial;
1083 isdnport->p_m_remote_id = joinremote->j_remote_id;
1084 if (mISDNport && i>=0)
1086 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1091 case BCHANNEL_ASSIGN_ACK:
1092 case BCHANNEL_REMOVE_ACK:
1093 /* find mISDNport for stack ID */
1094 mISDNport = mISDNport_first;
1098 ii = mISDNport->b_num;
1101 if (mISDNport->b_addr[i] == addr)
1107 mISDNport = mISDNport->next;
1111 PERROR("received assign/remove ack for addr=%x, but address does not exist.\n", addr);
1114 /* mISDNport may now be set or NULL */
1117 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1118 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1119 if (mISDNport && i>=0)
1120 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1124 PERROR("received wrong bchannel message type %d from remote\n", type);
1132 audio transmission procedure:
1133 -----------------------------
1136 three sources of audio transmission:
1137 - crypto-data high priority
1138 - tones high priority (also high)
1139 - remote-data low priority
1142 a variable that temporarily shows the number of samples elapsed since last transmission process.
1143 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1146 a variable that is increased whenever data is transmitted.
1147 it is decreased while time elapses. it stores the number of samples that
1148 are currently loaded to dsp module.
1149 since clock in dsp module is the same clock for user space process, these
1153 there are two levels:
1154 ISDN_LOAD will give the load that have to be kept in dsp.
1155 ISDN_MAXLOAD will give the maximum load before dropping.
1157 * procedure for low priority data
1158 see txfromup() for procedure
1159 in short: remote data is ignored during high priority tones
1161 * procedure for high priority data
1162 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1163 if no more data is available, load becomes empty again.
1166 0 ISDN_LOAD ISDN_MAXLOAD
1167 +--------------------+----------------------+
1169 +--------------------+----------------------+
1171 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1172 0 ISDN_LOAD ISDN_MAXLOAD
1173 +--------------------+----------------------+
1174 |TTTTTTTTTTTTTTTTTTTT| |
1175 +--------------------+----------------------+
1177 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1178 0 ISDN_LOAD ISDN_MAXLOAD
1179 +--------------------+----------------------+
1180 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1181 +--------------------+----------------------+
1184 int PmISDN::handler(void)
1186 struct message *message;
1190 if ((ret = Port::handler()))
1194 if (p_m_last_tv_sec)
1196 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1197 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1200 /* set clock of first process ever in this instance */
1201 p_m_last_tv_sec = now_tv.tv_sec;
1202 p_m_last_tv_msec = now_tv.tv_usec/1000;
1204 /* process only if we have a minimum of samples, to make packets not too small */
1205 if (elapsed >= ISDN_TRANSMIT)
1207 /* set clock of last process! */
1208 p_m_last_tv_sec = now_tv.tv_sec;
1209 p_m_last_tv_msec = now_tv.tv_usec/1000;
1212 if (elapsed < p_m_load)
1213 p_m_load -= elapsed;
1217 /* to send data, tone must be active OR crypt messages must be on */
1218 if ((p_tone_name[0] || p_m_crypt_msg_loops) && p_m_load < ISDN_LOAD)
1220 int tosend = ISDN_LOAD - p_m_load, length;
1221 unsigned char buf[mISDN_HEADER_LEN+tosend];
1222 iframe_t *frm = (iframe_t *)buf;
1223 unsigned char *p = buf+mISDN_HEADER_LEN;
1225 /* copy crypto loops */
1226 while (p_m_crypt_msg_loops && tosend)
1228 /* how much do we have to send */
1229 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1232 if (length > tosend)
1235 /* copy message (part) to buffer */
1236 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1239 p_m_crypt_msg_current += length;
1240 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1243 p_m_crypt_msg_current = 0;
1244 p_m_crypt_msg_loops--;
1252 if (p_tone_name[0] && tosend)
1254 tosend -= read_audio(p, tosend);
1258 frm->prim = DL_DATA | REQUEST;
1259 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1261 frm->len = ISDN_LOAD - p_m_load - tosend;
1263 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1264 p_m_load += frm->len;
1268 // NOTE: deletion is done by the child class
1270 /* handle timeouts */
1273 if (p_m_timer+p_m_timeout < now_d)
1275 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1277 /* send timeout to endpoint */
1278 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1279 message->param.state = p_state;
1280 message_put(message);
1285 return(0); /* nothing done */
1290 * whenever we get audio data from bchannel, we process it here
1292 void PmISDN::bchannel_receive(iframe_t *frm)
1294 unsigned char *data_temp;
1295 unsigned long length_temp;
1296 struct message *message;
1301 if (frm->prim == (PH_CONTROL | INDICATION))
1305 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1308 cont = *((unsigned long *)&frm->data.p);
1309 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1311 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1312 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1314 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1315 message->param.dtmf = cont & DTMF_TONE_MASK;
1316 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1317 message_put(message);
1323 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1324 add_trace("DSP-CRYPT", NULL, "error");
1326 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1327 message->param.crypt.type = CC_ERROR_IND;
1328 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1329 message_put(message);
1333 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1334 add_trace("DSP-CRYPT", NULL, "ok");
1336 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1337 message->param.crypt.type = CC_ACTBF_CONF;
1338 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1339 message_put(message);
1345 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1346 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1350 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
1354 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1355 add_trace("unknown", NULL, "0x%x", cont);
1360 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1362 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1366 /* calls will not process any audio data unless
1367 * the call is connected OR interface features audio during call setup.
1369 //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);
1370 #ifndef DEBUG_COREBRIDGE
1371 if (p_state!=PORT_STATE_CONNECT
1372 && !p_m_mISDNport->earlyb)
1376 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1379 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1385 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1387 /* randomize and listen to crypt message if enabled */
1388 if (p_m_crypt_listen)
1390 /* the noisy randomizer */
1391 p = (unsigned char *)&frm->data.p;
1394 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1396 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1399 p = (unsigned char *)&frm->data.p;
1401 /* send data to epoint */
1402 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1404 length_temp = frm->len;
1408 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1409 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1410 memcpy(message->param.data.data, data_temp, message->param.data.len);
1411 message_put(message);
1412 if (length_temp <= sizeof(message->param.data.data))
1414 data_temp += sizeof(message->param.data.data);
1415 length_temp -= sizeof(message->param.data.data);
1424 void PmISDN::set_echotest(int echo)
1426 if (p_m_echo != echo)
1429 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1431 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1432 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);
1439 void PmISDN::set_tone(char *dir, char *tone)
1445 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1452 /* check if we NOT really have to use a dsp-tone */
1453 if (!options.dsptones)
1457 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1459 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1460 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1463 Port::set_tone(dir, tone);
1469 /* now we USE dsp-tone, convert name */
1470 else if (!strcmp(tone, "dialtone"))
1472 switch(options.dsptones) {
1473 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1474 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1475 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1477 } else if (!strcmp(tone, "dialpbx"))
1479 switch(options.dsptones) {
1480 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1481 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1482 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1484 } else if (!strcmp(tone, "ringing"))
1486 switch(options.dsptones) {
1487 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1488 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1489 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1491 } else if (!strcmp(tone, "ringpbx"))
1493 switch(options.dsptones) {
1494 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1495 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1496 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1498 } else if (!strcmp(tone, "busy"))
1501 switch(options.dsptones) {
1502 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1503 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1504 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1506 } else if (!strcmp(tone, "release"))
1509 switch(options.dsptones) {
1510 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1511 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1512 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1514 } else if (!strcmp(tone, "cause_10"))
1516 else if (!strcmp(tone, "cause_11"))
1518 else if (!strcmp(tone, "cause_22"))
1520 switch(options.dsptones) {
1521 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1522 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1523 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1525 } else if (!strncmp(tone, "cause_", 6))
1526 id = TONE_SPECIAL_INFO;
1530 /* if we have a tone that is not supported by dsp */
1531 if (id==TONE_OFF && tone[0])
1539 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1541 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1542 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);
1544 /* turn user-space tones off in cases of no tone OR dsp tone */
1545 Port::set_tone("",NULL);
1549 /* MESSAGE_mISDNSIGNAL */
1550 //extern struct message *dddebug;
1551 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1553 switch(param->mISDNsignal.message)
1555 case mISDNSIGNAL_VOLUME:
1556 if (p_m_txvol != param->mISDNsignal.txvol)
1558 p_m_txvol = param->mISDNsignal.txvol;
1559 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1561 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1562 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
1564 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1565 if (p_m_rxvol != param->mISDNsignal.rxvol)
1567 p_m_rxvol = param->mISDNsignal.rxvol;
1568 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1570 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1571 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
1573 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1576 case mISDNSIGNAL_CONF:
1577 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1578 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1579 if (p_m_conf != param->mISDNsignal.conf)
1581 p_m_conf = param->mISDNsignal.conf;
1582 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1584 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1585 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);
1587 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1588 /* we must set, even if currently tone forbids conf */
1589 p_m_conf = param->mISDNsignal.conf;
1590 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1593 case mISDNSIGNAL_JOINDATA:
1594 if (p_m_joindata != param->mISDNsignal.joindata)
1596 p_m_joindata = param->mISDNsignal.joindata;
1597 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1599 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1602 case mISDNSIGNAL_DELAY:
1603 if (p_m_delay != param->mISDNsignal.delay)
1605 p_m_delay = param->mISDNsignal.delay;
1606 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1608 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1609 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);
1611 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1615 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1620 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1622 struct message *message;
1624 switch(param->crypt.type)
1626 case CC_ACTBF_REQ: /* activate blowfish */
1628 p_m_crypt_key_len = param->crypt.len;
1629 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1631 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1632 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1633 message->param.crypt.type = CC_ERROR_IND;
1634 message_put(message);
1637 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1639 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1641 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1642 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);
1645 case CC_DACT_REQ: /* deactivate session encryption */
1650 case CR_LISTEN_REQ: /* start listening to messages */
1651 p_m_crypt_listen = 1;
1652 p_m_crypt_listen_state = 0;
1655 case CR_UNLISTEN_REQ: /* stop listening to messages */
1656 p_m_crypt_listen = 0;
1659 case CR_MESSAGE_REQ: /* send message */
1660 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1661 if (!p_m_crypt_msg_len)
1663 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1666 p_m_crypt_msg_current = 0; /* reset */
1667 p_m_crypt_msg_loops = 3; /* enable */
1669 /* disable txmix, or we get corrupt data due to audio process */
1672 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1673 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1679 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1685 * endpoint sends messages to the port
1687 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1689 if (Port::message_epoint(epoint_id, message_id, param))
1694 case MESSAGE_DATA: /* tx-data from upper layer */
1695 txfromup(param->data.data, param->data.len);
1698 case MESSAGE_mISDNSIGNAL: /* user command */
1699 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1700 message_mISDNsignal(epoint_id, message_id, param);
1703 case MESSAGE_CRYPT: /* crypt control command */
1704 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1705 message_crypt(epoint_id, message_id, param);
1714 * main loop for processing messages from mISDN device
1716 int mISDN_handler(void)
1721 struct mISDNport *mISDNport;
1722 class PmISDN *isdnport;
1725 mISDNuser_head_t *hh;
1728 /* the que avoids loopbacks when replying to stack after receiving
1730 mISDNport = mISDNport_first;
1733 /* process turning on/off rx */
1735 while(i < mISDNport->b_num)
1737 isdnport=mISDNport->b_port[i];
1740 /* call bridges in user space OR crypto OR recording */
1741 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1743 /* rx IS required */
1744 if (isdnport->p_m_rxoff)
1747 isdnport->p_m_rxoff = 0;
1748 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1749 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1750 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1755 /* rx NOT required */
1756 if (!isdnport->p_m_rxoff)
1759 isdnport->p_m_rxoff = 1;
1760 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1761 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1762 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1767 if (isdnport->p_record)
1769 /* txdata IS required */
1770 if (!isdnport->p_m_txdata)
1773 isdnport->p_m_txdata = 1;
1774 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1775 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1776 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1781 /* txdata NOT required */
1782 if (isdnport->p_m_txdata)
1785 isdnport->p_m_txdata = 0;
1786 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1787 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1788 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1796 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1798 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1799 mISDNport->l1timeout = 0;
1802 if (mISDNport->l2establish)
1804 if (now-mISDNport->l2establish > 5)
1806 if (mISDNport->ntmode)
1808 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1809 time(&mISDNport->l2establish);
1811 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1812 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1815 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1816 time(&mISDNport->l2establish);
1819 act.prim = DL_ESTABLISH | REQUEST;
1820 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1823 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1825 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1830 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1832 if (mISDNport->ntmode)
1834 hh = (mISDNuser_head_t *)dmsg->data;
1835 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);
1836 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1840 frm = (iframe_t *)dmsg->data;
1841 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1842 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1843 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);
1844 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1849 mISDNport = mISDNport->next;
1852 /* no device, no read */
1853 if (mISDNdevice < 0)
1856 /* get message from kernel */
1857 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1859 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1863 if (errno == EAGAIN)
1865 FATAL("Failed to do mISDN_read()\n");
1870 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1874 frm = (iframe_t *)msg->data;
1879 case MGR_DELLAYER | CONFIRM:
1880 case MGR_INITTIMER | CONFIRM:
1881 case MGR_ADDTIMER | CONFIRM:
1882 case MGR_DELTIMER | CONFIRM:
1883 case MGR_REMOVETIMER | CONFIRM:
1888 /* handle timer events from mISDN for NT-stack
1889 * note: they do not associate with a stack */
1890 if (frm->prim == (MGR_TIMER | INDICATION))
1894 /* find mISDNport */
1895 mISDNport = mISDNport_first;
1899 if (mISDNport->ntmode)
1901 it = mISDNport->nst.tlist;
1905 if (it->id == (int)frm->addr)
1912 mISDNport = mISDNport->next;
1916 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1917 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1919 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
1920 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1921 ret = it->function(it->data);
1924 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
1929 /* find the mISDNport that belongs to the stack */
1930 mISDNport = mISDNport_first;
1933 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
1935 mISDNport = mISDNport->next;
1939 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1944 if (!(frm->addr&FLG_CHILD_STACK))
1949 case MGR_SHORTSTATUS | INDICATION:
1950 case MGR_SHORTSTATUS | CONFIRM:
1951 switch(frm->dinfo) {
1952 case SSTATUS_L1_ACTIVATED:
1953 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1956 case SSTATUS_L1_DEACTIVATED:
1957 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1960 case SSTATUS_L2_ESTABLISHED:
1961 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1964 case SSTATUS_L2_RELEASED:
1965 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1971 case PH_ACTIVATE | CONFIRM:
1972 case PH_ACTIVATE | INDICATION:
1973 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1975 if (mISDNport->ntmode)
1977 mISDNport->l1link = 1;
1978 setup_queue(mISDNport, 1);
1982 mISDNport->l1link = 1;
1983 setup_queue(mISDNport, 1);
1986 case PH_DEACTIVATE | CONFIRM:
1987 case PH_DEACTIVATE | INDICATION:
1988 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1990 if (mISDNport->ntmode)
1992 mISDNport->l1link = 0;
1993 setup_queue(mISDNport, 0);
1997 mISDNport->l1link = 0;
1998 setup_queue(mISDNport, 0);
2001 case PH_CONTROL | CONFIRM:
2002 case PH_CONTROL | INDICATION:
2003 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2006 case DL_ESTABLISH | INDICATION:
2007 case DL_ESTABLISH | CONFIRM:
2008 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2010 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2012 if (mISDNport->l2establish)
2014 mISDNport->l2establish = 0;
2015 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2017 mISDNport->l2link = 1;
2020 case DL_RELEASE | INDICATION:
2021 case DL_RELEASE | CONFIRM:
2022 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2024 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2026 mISDNport->l2link = 0;
2029 time(&mISDNport->l2establish);
2030 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2036 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);
2037 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2039 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2042 if (mISDNport->ntmode)
2044 /* l1-data enters the nt-mode library */
2045 nst = &mISDNport->nst;
2046 if (nst->l1_l2(nst, msg))
2051 /* l3-data is sent to pbx */
2052 if (stack2manager_te(mISDNport, msg))
2063 /* we don't care about confirms, we use rx data to sync tx */
2064 case PH_DATA | CONFIRM:
2065 case DL_DATA | CONFIRM:
2068 /* we receive audio data, we respond to it AND we send tones */
2069 case PH_DATA | INDICATION:
2070 case DL_DATA | INDICATION:
2071 case PH_CONTROL | INDICATION:
2073 while(i < mISDNport->b_num)
2075 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2079 if (i == mISDNport->b_num)
2081 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2084 if (mISDNport->b_port[i])
2086 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2087 mISDNport->b_port[i]->bchannel_receive(frm);
2089 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2092 case PH_ACTIVATE | INDICATION:
2093 case DL_ESTABLISH | INDICATION:
2094 case PH_ACTIVATE | CONFIRM:
2095 case DL_ESTABLISH | CONFIRM:
2096 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2098 while(i < mISDNport->b_num)
2100 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2104 if (i == mISDNport->b_num)
2106 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2109 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2112 case PH_DEACTIVATE | INDICATION:
2113 case DL_RELEASE | INDICATION:
2114 case PH_DEACTIVATE | CONFIRM:
2115 case DL_RELEASE | CONFIRM:
2116 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2118 while(i < mISDNport->b_num)
2120 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2124 if (i == mISDNport->b_num)
2126 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2129 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2133 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2144 * global function to add a new card (port)
2146 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
2149 unsigned char buff[1025];
2150 iframe_t *frm = (iframe_t *)buff;
2151 struct mISDNport *mISDNport, **mISDNportp;
2156 // struct mlayer3 *layer3;
2158 // interface_info_t ii;
2162 stack_info_t *stinf;
2165 /* query port's requirements */
2166 cnt = mISDN_get_stack_count(mISDNdevice);
2169 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2172 if (port>cnt || port<1)
2174 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2177 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2180 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2183 stinf = (stack_info_t *)&frm->data.p;
2184 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2186 case ISDN_PID_L0_TE_S0:
2187 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2189 case ISDN_PID_L0_NT_S0:
2190 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2193 case ISDN_PID_L0_TE_E1:
2194 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2197 case ISDN_PID_L0_NT_E1:
2198 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2203 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2209 if (stinf->pid.protocol[1] == 0)
2211 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2214 if (stinf->pid.protocol[2])
2216 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2222 if (stinf->pid.protocol[1] == 0)
2224 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2227 if (stinf->pid.protocol[2] == 0)
2229 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2232 if (stinf->pid.protocol[3] == 0)
2234 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2238 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2240 case ISDN_PID_L3_DSS1USER:
2244 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2248 if (stinf->pid.protocol[4])
2250 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2255 /* add mISDNport structure */
2256 mISDNportp = &mISDNport_first;
2258 mISDNportp = &((*mISDNportp)->next);
2259 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2261 *mISDNportp = mISDNport;
2263 /* allocate ressources of port */
2266 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2271 prop |= FLG_FORCE_PTMP;
2272 mISDNport->layer3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2273 if (!mISDNport->layer3)
2275 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2279 #warning KKEIL: braucht man das noch?
2280 /* if ntmode, establish L1 to send the tei removal during start */
2281 if (mISDNport->ntmode)
2285 act.prim = PH_ACTIVATE | REQUEST;
2286 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2287 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2290 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2291 usleep(10000); /* to be sure, that l1 is up */
2295 msg_queue_init(&mISDNport->downqueue);
2296 mISDNport->d_stid = stinf->id;
2297 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2298 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2300 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2304 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
2309 /* create layer intance */
2310 memset(&li, 0, sizeof(li));
2311 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
2314 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
2315 li.pid.layermask = ISDN_LAYER((nt?2:4));
2316 li.st = mISDNport->d_stid;
2317 ret = mISDN_new_layer(mISDNdevice, &li);
2320 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
2322 mISDNport_close(mISDNport);
2325 mISDNport->upper_id = li.id;
2326 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
2329 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2332 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2333 if (mISDNport->lower_id < 0)
2335 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2338 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2339 if (mISDNport->upper_id < 0)
2341 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2344 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2346 /* if ntmode, establish L1 to send the tei removal during start */
2347 if (mISDNport->ntmode)
2351 act.prim = PH_ACTIVATE | REQUEST;
2352 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2353 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2356 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2357 usleep(10000); /* to be sure, that l1 is up */
2360 /* create nst (nt-mode only) */
2363 mgr = &mISDNport->mgr;
2364 nst = &mISDNport->nst;
2369 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2370 nst->device = mISDNdevice;
2372 nst->d_stid = mISDNport->d_stid;
2374 nst->feature = FEATURE_NET_HOLD;
2376 nst->feature |= FEATURE_NET_PTP;
2378 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2381 while(i < mISDNport->b_num)
2383 nst->b_stid[i] = mISDNport->b_stid[i];
2387 nst->l1_id = mISDNport->lower_id;
2388 nst->l2_id = mISDNport->upper_id;
2391 msg_queue_init(&nst->down_queue);
2398 // SCPY(mISDNport->name, "noname");
2399 mISDNport->portnum = port;
2400 mISDNport->ntmode = nt;
2401 mISDNport->pri = pri;
2402 mISDNport->ptp = ptp;
2403 mISDNport->b_num = stinf->childcnt;
2404 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2406 while(i < stinf->childcnt)
2408 mISDNport->b_stid[i] = stinf->child[i];
2409 mISDNport->b_state[i] = B_STATE_IDLE;
2410 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
2414 /* if te-mode, query state link */
2415 if (!mISDNport->ntmode)
2419 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2420 act.prim = MGR_SHORTSTATUS | REQUEST;
2421 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2422 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2424 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2426 /* if ptp AND te-mode, pull up the link */
2427 if (mISDNport->ptp && !mISDNport->ntmode)
2431 act.prim = DL_ESTABLISH | REQUEST;
2432 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2435 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2437 /* if ptp AND nt-mode, pull up the link */
2438 if (mISDNport->ptp && mISDNport->ntmode)
2442 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2443 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2446 /* initially, we assume that the link is down, exept for nt-ptmp */
2447 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2449 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2451 start_trace(mISDNport->portnum,
2459 add_trace("channels", NULL, "%d", mISDNport->b_num);
2466 * function to free ALL cards (ports)
2468 void mISDNport_close_all(void)
2470 /* free all ports */
2471 while(mISDNport_first)
2472 mISDNport_close(mISDNport_first);
2476 * free only one port
2478 void mISDNport_close(struct mISDNport *mISDNport)
2480 struct mISDNport **mISDNportp;
2482 class PmISDN *isdnport;
2484 unsigned char buf[32];
2487 /* remove all port instance that are linked to this mISDNport */
2491 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2493 isdnport = (class PmISDN *)port;
2494 if (isdnport->p_m_mISDNport)
2496 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2503 /* only if we are already part of interface */
2504 if (mISDNport->ifport)
2506 start_trace(mISDNport->portnum,
2507 mISDNport->ifport->interface,
2517 /* free bchannels */
2519 while(i < mISDNport->b_num)
2521 if (mISDNport->b_addr[i])
2523 _bchannel_destroy(mISDNport, i);
2524 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2529 /* free ressources of port */
2530 msg_queue_purge(&mISDNport->downqueue);
2533 if (mISDNport->ntmode)
2535 nst = &mISDNport->nst;
2536 if (nst->manager) /* to see if initialized */
2538 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");
2539 cleanup_Isdnl3(nst);
2540 cleanup_Isdnl2(nst);
2543 msg_queue_purge(&nst->down_queue);
2544 if (nst->phd_down_msg)
2545 FREE(nst->phd_down_msg, 0);
2549 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2550 if (mISDNport->d_stid)
2552 if (mISDNport->upper_id)
2553 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2556 /* remove from list */
2557 mISDNportp = &mISDNport_first;
2560 if (*mISDNportp == mISDNport)
2562 *mISDNportp = (*mISDNportp)->next;
2566 mISDNportp = &((*mISDNportp)->next);
2570 FATAL("mISDNport not in list\n");
2572 FREE(mISDNport, sizeof(struct mISDNport));
2579 * global function to show all available isdn ports
2581 void mISDN_port_info(void)
2585 int useable, nt, pri;
2586 unsigned char buff[1025];
2587 iframe_t *frm = (iframe_t *)buff;
2588 stack_info_t *stinf;
2592 if ((device = mISDN_open()) < 0)
2594 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));
2598 /* get number of stacks */
2600 ii = mISDN_get_stack_count(device);
2604 printf("Found no card. Please be sure to load card drivers.\n");
2607 /* loop the number of cards and get their info */
2610 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2613 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2616 stinf = (stack_info_t *)&frm->data.p;
2621 /* output the port info */
2622 printf("Port %2d: ", i);
2623 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2625 case ISDN_PID_L0_TE_S0:
2626 printf("TE-mode BRI S/T interface line (for phone lines)");
2628 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2629 printf(" HFC multiport card");
2632 case ISDN_PID_L0_NT_S0:
2634 printf("NT-mode BRI S/T interface port (for phones)");
2636 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2637 printf(" HFC multiport card");
2640 case ISDN_PID_L0_TE_E1:
2642 printf("TE-mode PRI E1 interface line (for phone lines)");
2644 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2645 printf(" HFC-E1 card");
2648 case ISDN_PID_L0_NT_E1:
2651 printf("NT-mode PRI E1 interface port (for phones)");
2653 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2654 printf(" HFC-E1 card");
2659 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2665 if (stinf->pid.protocol[1] == 0)
2668 printf(" -> Missing layer 1 NT-mode protocol.\n");
2671 while(p <= MAX_LAYER_NR) {
2672 if (stinf->pid.protocol[p])
2675 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2682 printf(" -> Interface is Point-To-Point (PRI).\n");
2684 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2688 if (stinf->pid.protocol[1] == 0)
2691 printf(" -> Missing layer 1 protocol.\n");
2693 if (stinf->pid.protocol[2] == 0)
2696 printf(" -> Missing layer 2 protocol.\n");
2698 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2700 printf(" -> Interface is Poin-To-Point.\n");
2702 if (stinf->pid.protocol[3] == 0)
2705 printf(" -> Missing layer 3 protocol.\n");
2708 printf(" -> Protocol: ");
2709 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2711 case ISDN_PID_L3_DSS1USER:
2712 printf("DSS1 (Euro ISDN)");
2717 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2722 while(p <= MAX_LAYER_NR) {
2723 if (stinf->pid.protocol[p])
2726 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2731 printf(" - %d B-channels\n", stinf->childcnt);
2734 printf(" * Port NOT useable for LCR\n");
2736 printf("--------\n");
2743 if ((err = mISDN_close(device)))
2744 FATAL("mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2749 * enque data from upper buffer
2751 void PmISDN::txfromup(unsigned char *data, int length)
2753 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2754 iframe_t *frm = (iframe_t *)buf;
2756 /* configure frame */
2757 frm->prim = DL_DATA | REQUEST;
2758 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
2761 /* check if high priority tones exist
2762 * ignore data in this case
2764 if (p_tone_name[0] || p_m_crypt_msg_loops)
2767 /* preload procedure
2768 * if transmit buffer in DSP module is empty,
2769 * preload it to DSP_LOAD to prevent jitter gaps.
2771 if (p_m_load==0 && ISDN_LOAD>0)
2774 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
2775 frm->len = ISDN_LOAD;
2776 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2777 p_m_load += frm->len;
2780 /* drop if load would exceed ISDN_MAXLOAD
2781 * this keeps the delay not too high
2783 if (p_m_load+length > ISDN_MAXLOAD)
2786 /* load data to buffer
2788 memcpy(buf+mISDN_HEADER_LEN, data, length);
2790 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2791 p_m_load += frm->len;