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_exportremote = 0; /* channel shall be exported to given remote */
170 p_m_crypt_listen = 0;
171 p_m_crypt_msg_loops = 0;
172 p_m_crypt_msg_loops = 0;
173 p_m_crypt_msg_len = 0;
174 p_m_crypt_msg[0] = '\0';
175 p_m_crypt_msg_current = 0;
176 p_m_crypt_key[0] = '\0';
177 p_m_crypt_key_len = 0;
178 p_m_crypt_listen = 0;
179 p_m_crypt_listen_state = 0;
180 p_m_crypt_listen_len = 0;
181 p_m_crypt_listen_msg[0] = '\0';
182 p_m_crypt_listen_crc = 0;
184 /* if any channel requested by constructor */
185 if (channel == CHANNEL_ANY)
187 /* reserve channel */
189 mISDNport->b_reserved++;
192 /* reserve channel */
193 if (channel > 0) // only if constructor was called with a channel resevation
194 seize_bchannel(channel, exclusive);
196 /* we increase the number of objects: */
198 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
207 struct message *message;
209 /* remove bchannel relation */
215 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
216 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
217 message->param.disconnectinfo.cause = 16;
218 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
219 message_put(message);
220 /* remove from list */
221 free_epointlist(p_epointlist);
224 /* we decrease the number of objects: */
225 p_m_mISDNport->use--;
226 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
233 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
235 /* init trace with given values */
236 start_trace(mISDNport?mISDNport->portnum:0,
237 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
238 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
239 port?port->p_dialinginfo.id:NULL,
242 port?port->p_serial:0,
250 static struct isdn_message {
254 {"TIMEOUT", CC_TIMEOUT},
256 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
257 {"PROCEEDING", CC_PROCEEDING},
258 {"ALERTING", CC_ALERTING},
259 {"CONNECT", CC_CONNECT},
260 {"CONNECT RES", CC_CONNECT},
261 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
262 {"DISCONNECT", CC_DISCONNECT},
263 {"RELEASE", CC_RELEASE},
264 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
265 {"INFORMATION", CC_INFORMATION},
266 {"PROGRESS", CC_PROGRESS},
267 {"NOTIFY", CC_NOTIFY},
268 {"SUSPEND", CC_SUSPEND},
269 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
270 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
271 {"RESUME", CC_RESUME},
272 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
273 {"RESUME_REJ", CC_RESUME_REJECT},
275 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
276 {"HOLD_REJ", CC_HOLD_REJECT},
277 {"RETRIEVE", CC_RETRIEVE},
278 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
279 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
280 {"FACILITY", CC_FACILITY},
281 {"STATUS", CC_STATUS},
282 {"RESTART", CC_RESTART},
283 {"RELEASE_CR", CC_RELEASE_CR},
284 {"NEW_CR", CC_NEW_CR},
285 {"DL_ESTABLISH", DL_ESTABLISH},
286 {"DL_RELEASE", DL_RELEASE},
287 {"PH_ACTIVATE", PH_ACTIVATE},
288 {"PH_DEACTIVATE", PH_DEACTIVATE},
292 static char *isdn_prim[4] = {
298 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
301 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
303 /* select message and primitive text */
305 while(isdn_message[i].name)
307 if (isdn_message[i].value == (prim&0xffffff00))
309 SCPY(msgtext, isdn_message[i].name);
314 SCAT(msgtext, isdn_prim[prim&0x00000003]);
317 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
321 if (mISDNport->ntmode)
323 if (direction == DIRECTION_OUT)
324 SCAT(msgtext, " N->U");
326 SCAT(msgtext, " N<-U");
329 if (direction == DIRECTION_OUT)
330 SCAT(msgtext, " U->N");
332 SCAT(msgtext, " U<-N");
337 /* init trace with given values */
338 start_trace(mISDNport?mISDNport->portnum:0,
339 mISDNport?mISDNport->ifport->interface:NULL,
340 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
341 port?port->p_dialinginfo.id:NULL,
344 port?port->p_serial:0,
350 * send control information to the channel (dsp-module)
352 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, int c2, char *trace_name, int trace_value)
354 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
355 iframe_t *ctrl = (iframe_t *)buffer;
356 unsigned long *d = (unsigned long *)&ctrl->data.p;
358 ctrl->prim = PH_CONTROL | REQUEST;
359 ctrl->addr = b_addr | FLG_MSG_DOWN;
361 ctrl->len = sizeof(int)*2;
364 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
365 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
366 if (c1 == CMX_CONF_JOIN)
367 add_trace(trace_name, NULL, "0x%08x", trace_value);
369 add_trace(trace_name, NULL, "%d", trace_value);
373 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)
375 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
376 iframe_t *ctrl = (iframe_t *)buffer;
377 unsigned long *d = (unsigned long *)&ctrl->data.p;
379 ctrl->prim = PH_CONTROL | REQUEST;
380 ctrl->addr = b_addr | FLG_MSG_DOWN;
382 ctrl->len = sizeof(int)+c2_len;
384 memcpy(d, c2, c2_len);
385 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
386 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
387 add_trace(trace_name, NULL, "%d", trace_value);
393 * subfunction for bchannel_event
396 static int _bchannel_create(struct mISDNport *mISDNport, int i)
398 unsigned char buff[1024];
403 if (!mISDNport->b_stid[i])
405 PERROR("Error: no stack for index %d\n", i);
408 if (mISDNport->b_addr[i])
410 PERROR("Error: stack already created for index %d\n", i);
414 /* create new layer */
415 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
416 memset(&li, 0, sizeof(li));
417 memset(&pid, 0, sizeof(pid));
420 li.st = mISDNport->b_stid[i];
421 UCPY(li.name, "B L4");
422 li.pid.layermask = ISDN_LAYER((4));
423 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
424 ret = mISDN_new_layer(mISDNdevice, &li);
428 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
431 mISDNport->b_addr[i] = li.id;
434 goto failed_new_layer;
436 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
438 /* create new stack */
439 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
440 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
441 pid.protocol[3] = ISDN_PID_L3_B_DSP;
442 pid.protocol[4] = ISDN_PID_L4_B_USER;
443 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
444 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
448 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
449 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
452 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
457 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
458 if (!mISDNport->b_addr[i])
460 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
461 add_trace("channel", NULL, "%d", i+1+(i>=15));
462 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
463 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
469 mISDNport->b_addr[i] = 0;
475 * subfunction for bchannel_event
476 * activate / deactivate request
478 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
482 /* activate bchannel */
483 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
484 add_trace("channel", NULL, "%d", i+1+(i>=15));
486 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
487 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
490 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
495 * subfunction for bchannel_event
498 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
503 port = mISDNport->b_port[i];
504 addr = mISDNport->b_addr[i];
507 PERROR("bchannel index i=%d not associated with a port object\n", i);
511 /* set dsp features */
512 if (port->p_m_txdata)
513 ph_control(mISDNport, port, addr, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
515 ph_control(mISDNport, port, addr, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
517 ph_control(mISDNport, port, addr, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
519 ph_control(mISDNport, port, addr, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
521 ph_control(mISDNport, port, addr, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
523 ph_control(mISDNport, port, addr, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
525 ph_control(mISDNport, port, addr, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
527 ph_control(mISDNport, port, addr, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
528 // if (port->p_m_txmix)
529 // ph_control(mISDNport, port, addr, CMX_MIX_ON, 0, "DSP-MIX", 1);
531 ph_control(mISDNport, port, addr, DTMF_TONE_START, 0, "DSP-DTMF", 1);
533 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);
537 * subfunction for bchannel_event
540 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
542 unsigned char buff[1024];
544 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
545 add_trace("channel", NULL, "%d", i+1+(i>=15));
546 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
547 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
549 /* remove our stack only if set */
550 if (mISDNport->b_addr[i])
552 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
553 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
554 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
555 mISDNport->b_addr[i] = 0;
564 A bchannel goes through the following states in this order:
567 No one is using the bchannel.
568 It is available and not linked to Port class, nor reserved.
571 The bchannel stack is created and an activation request is sent.
572 It MAY be linked to Port class, but already unlinked due to Port class removal.
575 The bchannel is active and cofigured to the Port class needs.
576 Also it is linked to a Port class, otherwhise it would be deactivated.
578 - B_STATE_DEACTIVATING
579 The bchannel is in deactivating state, due to deactivation request.
580 It may be linked to a Port class, that likes to reactivate it.
584 After deactivating bchannel, and if not used, the bchannel becomes idle again.
586 Also the bchannel may be exported, but only if the state is or becomes idle:
589 The bchannel assignment has been sent to the remove application.
592 The bchannel assignment is acknowledged by the remote application.
595 The bchannel is re-imported by mISDN port object.
599 After re-importing bchannel, and if not used, the bchannel becomes idle again.
602 A bchannel can have the following events:
605 A bchannel is required by a Port class.
606 The bchannel shall be exported to the remote application.
609 The bchannel beomes active.
612 The bchannel is not required by Port class anymore
614 - B_EVENT_DEACTIVATED
615 The bchannel becomes inactive.
618 The bchannel is now used by remote application.
621 The bchannel is not used by remote application.
623 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
628 * process bchannel events
629 * - mISDNport is a pointer to the port's structure
630 * - i is the index of the bchannel
631 * - event is the B_EVENT_* value
632 * - port is the PmISDN class pointer
634 void bchannel_event(struct mISDNport *mISDNport, int i, int event, unsigned long to_remote)
636 class PmISDN *b_port = mISDNport->b_port[i];
637 int state = mISDNport->b_state[i];
638 unsigned long remote = mISDNport->b_remote[i];
639 unsigned long addr = mISDNport->b_addr[i];
644 /* port must be linked in order to allow activation */
646 FATAL("bchannel must be linked to a Port class\n");
651 PDEBUG(DEBUG_BCHANNEL, "idle channels don't have remote link.\n");
654 /* export bchannel */
655 mISDNport->b_remote[i] = remote = to_remote;
657 message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
658 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
659 add_trace("type", NULL, "assign");
660 add_trace("stack", "address", "%x", addr);
662 state = B_STATE_EXPORTING;
665 /* create stack and send activation request */
666 if (_bchannel_create(mISDNport, i))
668 _bchannel_activate(mISDNport, i, 1);
669 state = B_STATE_ACTIVATING;
674 case B_STATE_ACTIVATING:
675 case B_STATE_EXPORTING:
676 /* do nothing, because it is already activating */
679 case B_STATE_DEACTIVATING:
680 case B_STATE_IMPORTING:
681 /* do nothing, because we must wait until we can reactivate */
685 /* problems that might ocurr:
686 * B_EVENT_USE is received when channel already in use.
687 * bchannel exported, but not freed by other port
689 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
693 case B_EVENT_EXPORTREQUEST:
694 /* special case where the bchannel is requested by remote */
697 PERROR("channel for join %d already exported to join %d, please correct.\n", to_remote, remote);
699 mISDNport->b_remote[i] = remote = to_remote;
704 /* export bchannel */
705 message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
706 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
707 add_trace("type", NULL, "assign");
708 add_trace("stack", "address", "%x", addr);
710 state = B_STATE_EXPORTING;
713 case B_STATE_ACTIVATING:
714 case B_STATE_EXPORTING:
715 /* do nothing, because it is already activating */
718 case B_STATE_DEACTIVATING:
719 case B_STATE_IMPORTING:
720 /* do nothing, because we must wait until we can reactivate */
724 /* bchannel is active, so we deactivate */
725 _bchannel_activate(mISDNport, i, 0);
726 state = B_STATE_DEACTIVATING;
730 /* problems that might ocurr:
731 * ... when channel already in use.
732 * bchannel exported, but not freed by other port
734 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
738 case B_EVENT_ACTIVATED:
741 case B_STATE_ACTIVATING:
742 if (b_port && !remote)
744 /* bchannel is active and used by Port class, so we configure bchannel */
745 _bchannel_configure(mISDNport, i);
746 state = B_STATE_ACTIVE;
749 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
750 _bchannel_activate(mISDNport, i, 0);
751 state = B_STATE_DEACTIVATING;
756 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
760 case B_EVENT_EXPORTED:
763 case B_STATE_EXPORTING:
764 if (b_port && remote && to_remote==remote)
766 /* remote export done */
767 state = B_STATE_REMOTE;
770 /* bchannel is now exported, but we need bchannel back OR bchannel is not used anymore OR remote has changed, so reimport, to later export to new remote */
771 message_bchannel_to_join(remote, BCHANNEL_REMOVE, addr);
772 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
773 add_trace("type", NULL, "remove");
774 add_trace("stack", "address", "%x", addr);
776 state = B_STATE_IMPORTING;
781 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
787 FATAL("bchannel must be linked to a Port class\n");
791 /* bchannel is idle due to an error, so we do nothing */
794 case B_STATE_ACTIVATING:
795 case B_STATE_EXPORTING:
796 /* do nothing because we must wait until bchanenl is active before deactivating */
800 /* bchannel is active, so we deactivate */
801 _bchannel_activate(mISDNport, i, 0);
802 state = B_STATE_DEACTIVATING;
806 /* bchannel is exported, so we re-import */
807 message_bchannel_to_join(remote, BCHANNEL_REMOVE, addr);
808 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
809 add_trace("type", NULL, "remove");
810 add_trace("stack", "address", "%x", addr);
812 state = B_STATE_IMPORTING;
815 case B_STATE_DEACTIVATING:
816 case B_STATE_IMPORTING:
817 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
821 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
825 case B_EVENT_DEACTIVATED:
829 /* ignore due to deactivation confirm after unloading */
832 case B_STATE_DEACTIVATING:
833 _bchannel_destroy(mISDNport, i);
834 state = B_STATE_IDLE;
837 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
840 message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
841 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
842 add_trace("type", NULL, "assign");
843 add_trace("stack", "address", "%x", addr);
845 state = B_STATE_EXPORTING;
848 if (_bchannel_create(mISDNport, i))
850 _bchannel_activate(mISDNport, i, 1);
851 state = B_STATE_ACTIVATING;
858 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
862 case B_EVENT_IMPORTED:
865 case B_STATE_IMPORTING:
866 state = B_STATE_IDLE;
869 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
872 message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
873 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
874 add_trace("type", NULL, "assign");
875 add_trace("stack", "address", "%x", addr);
877 state = B_STATE_EXPORTING;
880 if (_bchannel_create(mISDNport, i))
882 _bchannel_activate(mISDNport, i, 1);
883 state = B_STATE_ACTIVATING;
888 /* not exported anymore */
889 mISDNport->b_remote[i] = 0;
894 /* ignore, because not assigned */
900 PERROR("Illegal event %d, please correct.\n", event);
903 mISDNport->b_state[i] = state;
910 * check for available channel and reserve+set it.
911 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
913 * returns -(cause value) or x = channel x or 0 = no channel
914 * NOTE: no activation is done here
916 int PmISDN::seize_bchannel(int channel, int exclusive)
920 /* the channel is what we have */
921 if (p_m_b_channel == channel)
924 /* if channel already in use, release it */
929 if (channel==CHANNEL_NO || channel==0)
932 /* is channel in range ? */
934 || (channel>p_m_mISDNport->b_num && channel<16)
935 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
936 return(-6); /* channel unacceptable */
938 /* request exclusive channel */
939 if (exclusive && channel>0)
941 i = channel-1-(channel>16);
942 if (p_m_mISDNport->b_port[i])
943 return(-44); /* requested channel not available */
947 /* ask for channel */
950 i = channel-1-(channel>16);
951 if (p_m_mISDNport->b_port[i] == NULL)
955 /* search for channel */
957 while(i < p_m_mISDNport->b_num)
959 if (!p_m_mISDNport->b_port[i])
961 channel = i+1+(i>=15);
966 return(-34); /* no free channel */
969 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
972 p_m_mISDNport->b_port[i] = this;
973 p_m_mISDNport->b_remote[i] = p_m_exportremote;
975 p_m_b_channel = channel;
976 p_m_b_exclusive = exclusive;
978 /* reserve channel */
982 p_m_mISDNport->b_reserved++;
989 * drop reserved channel and unset it.
990 * deactivation is also done
992 void PmISDN::drop_bchannel(void)
997 /* unreserve channel */
999 p_m_mISDNport->b_reserved--;
1006 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1008 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1009 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP, 0);
1010 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1013 p_m_b_exclusive = 0;
1016 /* process bchannel export/import message from join */
1017 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long addr)
1019 class Endpoint *epoint;
1021 class PmISDN *isdnport;
1022 struct mISDNport *mISDNport;
1027 case BCHANNEL_REQUEST:
1028 /* find the port object for the join object ref */
1029 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1031 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1034 if (!epoint->ep_portlist)
1036 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1039 if (epoint->ep_portlist->next)
1041 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);
1043 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1045 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1048 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1050 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1052 isdnport = (class PmISDN *)port;
1055 if (isdnport->p_m_exportremote)
1057 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1060 chan_trace_header(isdnport->p_m_mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1061 add_trace("type", NULL, "export request");
1062 isdnport->p_m_exportremote = joinremote->j_serial;
1063 if (isdnport->p_m_mISDNport && isdnport->p_m_b_index>=0)
1064 bchannel_event(isdnport->p_m_mISDNport, isdnport->p_m_b_index, B_EVENT_EXPORTREQUEST, joinremote->j_serial);
1068 case BCHANNEL_ASSIGN_ACK:
1069 case BCHANNEL_REMOVE_ACK:
1070 /* find mISDNport for stack ID */
1071 mISDNport = mISDNport_first;
1075 ii = mISDNport->b_num;
1078 if (mISDNport->b_addr[i] == addr)
1084 mISDNport = mISDNport->next;
1086 /* mISDNport may now be set or NULL */
1089 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1090 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1091 if (mISDNport && i>=0)
1092 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED, 0);
1096 PERROR("received wrong bchannel message type %d from remote\n", type);
1104 audio transmission procedure:
1105 -----------------------------
1108 three sources of audio transmission:
1109 - crypto-data high priority
1110 - tones high priority (also high)
1111 - remote-data low priority
1114 a variable that temporarily shows the number of samples elapsed since last transmission process.
1115 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1118 a variable that is increased whenever data is transmitted.
1119 it is decreased while time elapses. it stores the number of samples that
1120 are currently loaded to dsp module.
1121 since clock in dsp module is the same clock for user space process, these
1125 there are two levels:
1126 ISDN_LOAD will give the load that have to be kept in dsp.
1127 ISDN_MAXLOAD will give the maximum load before dropping.
1129 * procedure for low priority data
1130 see txfromup() for procedure
1131 in short: remote data is ignored during high priority tones
1133 * procedure for high priority data
1134 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1135 if no more data is available, load becomes empty again.
1138 0 ISDN_LOAD ISDN_MAXLOAD
1139 +--------------------+----------------------+
1141 +--------------------+----------------------+
1143 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1144 0 ISDN_LOAD ISDN_MAXLOAD
1145 +--------------------+----------------------+
1146 |TTTTTTTTTTTTTTTTTTTT| |
1147 +--------------------+----------------------+
1149 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1150 0 ISDN_LOAD ISDN_MAXLOAD
1151 +--------------------+----------------------+
1152 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1153 +--------------------+----------------------+
1156 int PmISDN::handler(void)
1158 struct message *message;
1162 if ((ret = Port::handler()))
1166 if (p_m_last_tv_sec)
1168 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1169 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1172 /* set clock of first process ever in this instance */
1173 p_m_last_tv_sec = now_tv.tv_sec;
1174 p_m_last_tv_msec = now_tv.tv_usec/1000;
1176 /* process only if we have a minimum of samples, to make packets not too small */
1177 if (elapsed >= ISDN_TRANSMIT)
1179 /* set clock of last process! */
1180 p_m_last_tv_sec = now_tv.tv_sec;
1181 p_m_last_tv_msec = now_tv.tv_usec/1000;
1184 if (elapsed < p_m_load)
1185 p_m_load -= elapsed;
1189 /* to send data, tone must be active OR crypt messages must be on */
1190 if ((p_tone_name[0] || p_m_crypt_msg_loops) && p_m_load < ISDN_LOAD)
1192 int tosend = ISDN_LOAD - p_m_load, length;
1193 unsigned char buf[mISDN_HEADER_LEN+tosend];
1194 iframe_t *frm = (iframe_t *)buf;
1195 unsigned char *p = buf+mISDN_HEADER_LEN;
1197 /* copy crypto loops */
1198 while (p_m_crypt_msg_loops && tosend)
1200 /* how much do we have to send */
1201 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1204 if (length > tosend)
1207 /* copy message (part) to buffer */
1208 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1211 p_m_crypt_msg_current += length;
1212 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1215 p_m_crypt_msg_current = 0;
1216 p_m_crypt_msg_loops--;
1224 if (p_tone_name[0] && tosend)
1226 tosend -= read_audio(p, tosend);
1230 frm->prim = DL_DATA | REQUEST;
1231 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1233 frm->len = ISDN_LOAD - p_m_load - tosend;
1235 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1236 p_m_load += frm->len;
1240 // NOTE: deletion is done by the child class
1242 /* handle timeouts */
1245 if (p_m_timer+p_m_timeout < now_d)
1247 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1249 /* send timeout to endpoint */
1250 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1251 message->param.state = p_state;
1252 message_put(message);
1257 return(0); /* nothing done */
1262 * whenever we get audio data from bchannel, we process it here
1264 void PmISDN::bchannel_receive(iframe_t *frm)
1266 unsigned char *data_temp;
1267 unsigned long length_temp;
1268 struct message *message;
1273 if (frm->prim == (PH_CONTROL | INDICATION))
1277 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1280 cont = *((unsigned long *)&frm->data.p);
1281 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1283 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1284 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1286 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1287 message->param.dtmf = cont & DTMF_TONE_MASK;
1288 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1289 message_put(message);
1295 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1296 add_trace("DSP-CRYPT", NULL, "error");
1298 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1299 message->param.crypt.type = CC_ERROR_IND;
1300 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1301 message_put(message);
1305 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1306 add_trace("DSP-CRYPT", NULL, "ok");
1308 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1309 message->param.crypt.type = CC_ACTBF_CONF;
1310 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1311 message_put(message);
1317 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1318 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1322 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
1326 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1327 add_trace("unknown", NULL, "0x%x", cont);
1332 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1334 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1338 /* calls will not process any audio data unless
1339 * the call is connected OR interface features audio during call setup.
1341 //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);
1342 #ifndef DEBUG_COREBRIDGE
1343 if (p_state!=PORT_STATE_CONNECT
1344 && !p_m_mISDNport->earlyb)
1348 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1351 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1357 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1359 /* randomize and listen to crypt message if enabled */
1360 if (p_m_crypt_listen)
1362 /* the noisy randomizer */
1363 p = (unsigned char *)&frm->data.p;
1366 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1368 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1371 p = (unsigned char *)&frm->data.p;
1373 /* send data to epoint */
1374 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1376 length_temp = frm->len;
1380 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1381 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1382 memcpy(message->param.data.data, data_temp, message->param.data.len);
1383 message_put(message);
1384 if (length_temp <= sizeof(message->param.data.data))
1386 data_temp += sizeof(message->param.data.data);
1387 length_temp -= sizeof(message->param.data.data);
1396 void PmISDN::set_echotest(int echo)
1398 if (p_m_echo != echo)
1401 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1403 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1404 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);
1411 void PmISDN::set_tone(char *dir, char *tone)
1417 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1424 /* check if we NOT really have to use a dsp-tone */
1425 if (!options.dsptones)
1429 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1431 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1432 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1435 Port::set_tone(dir, tone);
1441 /* now we USE dsp-tone, convert name */
1442 else if (!strcmp(tone, "dialtone"))
1444 switch(options.dsptones) {
1445 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1446 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1447 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1449 } else if (!strcmp(tone, "dialpbx"))
1451 switch(options.dsptones) {
1452 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1453 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1454 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1456 } else if (!strcmp(tone, "ringing"))
1458 switch(options.dsptones) {
1459 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1460 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1461 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1463 } else if (!strcmp(tone, "ringpbx"))
1465 switch(options.dsptones) {
1466 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1467 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1468 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1470 } else if (!strcmp(tone, "busy"))
1473 switch(options.dsptones) {
1474 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1475 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1476 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1478 } else if (!strcmp(tone, "release"))
1481 switch(options.dsptones) {
1482 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1483 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1484 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1486 } else if (!strcmp(tone, "cause_10"))
1488 else if (!strcmp(tone, "cause_11"))
1490 else if (!strcmp(tone, "cause_22"))
1492 switch(options.dsptones) {
1493 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1494 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1495 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1497 } else if (!strncmp(tone, "cause_", 6))
1498 id = TONE_SPECIAL_INFO;
1502 /* if we have a tone that is not supported by dsp */
1503 if (id==TONE_OFF && tone[0])
1511 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1513 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1514 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);
1516 /* turn user-space tones off in cases of no tone OR dsp tone */
1517 Port::set_tone("",NULL);
1521 /* MESSAGE_mISDNSIGNAL */
1522 //extern struct message *dddebug;
1523 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1525 switch(param->mISDNsignal.message)
1527 case mISDNSIGNAL_VOLUME:
1528 if (p_m_txvol != param->mISDNsignal.txvol)
1530 p_m_txvol = param->mISDNsignal.txvol;
1531 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1533 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1534 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);
1536 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1537 if (p_m_rxvol != param->mISDNsignal.rxvol)
1539 p_m_rxvol = param->mISDNsignal.rxvol;
1540 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1542 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1543 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);
1545 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1548 case mISDNSIGNAL_CONF:
1549 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1550 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1551 if (p_m_conf != param->mISDNsignal.conf)
1553 p_m_conf = param->mISDNsignal.conf;
1554 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1556 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1557 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);
1559 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1560 /* we must set, even if currently tone forbids conf */
1561 p_m_conf = param->mISDNsignal.conf;
1562 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1565 case mISDNSIGNAL_JOINDATA:
1566 if (p_m_joindata != param->mISDNsignal.joindata)
1568 p_m_joindata = param->mISDNsignal.joindata;
1569 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1571 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1574 case mISDNSIGNAL_DELAY:
1575 if (p_m_delay != param->mISDNsignal.delay)
1577 p_m_delay = param->mISDNsignal.delay;
1578 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1580 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1581 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);
1583 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1587 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1592 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1594 struct message *message;
1596 switch(param->crypt.type)
1598 case CC_ACTBF_REQ: /* activate blowfish */
1600 p_m_crypt_key_len = param->crypt.len;
1601 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1603 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1604 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1605 message->param.crypt.type = CC_ERROR_IND;
1606 message_put(message);
1609 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1611 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1613 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1614 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);
1617 case CC_DACT_REQ: /* deactivate session encryption */
1622 case CR_LISTEN_REQ: /* start listening to messages */
1623 p_m_crypt_listen = 1;
1624 p_m_crypt_listen_state = 0;
1627 case CR_UNLISTEN_REQ: /* stop listening to messages */
1628 p_m_crypt_listen = 0;
1631 case CR_MESSAGE_REQ: /* send message */
1632 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1633 if (!p_m_crypt_msg_len)
1635 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1638 p_m_crypt_msg_current = 0; /* reset */
1639 p_m_crypt_msg_loops = 3; /* enable */
1641 /* disable txmix, or we get corrupt data due to audio process */
1644 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1645 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1651 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1657 * endpoint sends messages to the port
1659 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1661 if (Port::message_epoint(epoint_id, message_id, param))
1666 case MESSAGE_DATA: /* tx-data from upper layer */
1667 txfromup(param->data.data, param->data.len);
1670 case MESSAGE_mISDNSIGNAL: /* user command */
1671 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1672 message_mISDNsignal(epoint_id, message_id, param);
1675 case MESSAGE_CRYPT: /* crypt control command */
1676 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1677 message_crypt(epoint_id, message_id, param);
1686 * main loop for processing messages from mISDN device
1688 int mISDN_handler(void)
1693 struct mISDNport *mISDNport;
1694 class PmISDN *isdnport;
1697 mISDNuser_head_t *hh;
1700 /* the que avoids loopbacks when replying to stack after receiving
1702 mISDNport = mISDNport_first;
1705 /* process turning on/off rx */
1707 while(i < mISDNport->b_num)
1709 isdnport=mISDNport->b_port[i];
1712 /* call bridges in user space OR crypto OR recording */
1713 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1715 /* rx IS required */
1716 if (isdnport->p_m_rxoff)
1719 isdnport->p_m_rxoff = 0;
1720 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1721 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1722 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1727 /* rx NOT required */
1728 if (!isdnport->p_m_rxoff)
1731 isdnport->p_m_rxoff = 1;
1732 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1733 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1734 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1739 if (isdnport->p_record)
1741 /* txdata IS required */
1742 if (!isdnport->p_m_txdata)
1745 isdnport->p_m_txdata = 1;
1746 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1747 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1748 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1753 /* txdata NOT required */
1754 if (isdnport->p_m_txdata)
1757 isdnport->p_m_txdata = 0;
1758 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1759 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1760 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1768 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1770 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1771 mISDNport->l1timeout = 0;
1774 if (mISDNport->l2establish)
1776 if (now-mISDNport->l2establish > 5)
1778 if (mISDNport->ntmode)
1780 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1781 time(&mISDNport->l2establish);
1783 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1784 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1787 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1788 time(&mISDNport->l2establish);
1791 act.prim = DL_ESTABLISH | REQUEST;
1792 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1795 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1797 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1802 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1804 if (mISDNport->ntmode)
1806 hh = (mISDNuser_head_t *)dmsg->data;
1807 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);
1808 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1812 frm = (iframe_t *)dmsg->data;
1813 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1814 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1815 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);
1816 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1821 mISDNport = mISDNport->next;
1824 /* no device, no read */
1825 if (mISDNdevice < 0)
1828 /* get message from kernel */
1829 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1831 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1835 if (errno == EAGAIN)
1837 FATAL("Failed to do mISDN_read()\n");
1842 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1846 frm = (iframe_t *)msg->data;
1851 case MGR_DELLAYER | CONFIRM:
1852 case MGR_INITTIMER | CONFIRM:
1853 case MGR_ADDTIMER | CONFIRM:
1854 case MGR_DELTIMER | CONFIRM:
1855 case MGR_REMOVETIMER | CONFIRM:
1860 /* handle timer events from mISDN for NT-stack
1861 * note: they do not associate with a stack */
1862 if (frm->prim == (MGR_TIMER | INDICATION))
1866 /* find mISDNport */
1867 mISDNport = mISDNport_first;
1871 if (mISDNport->ntmode)
1873 it = mISDNport->nst.tlist;
1877 if (it->id == (int)frm->addr)
1884 mISDNport = mISDNport->next;
1888 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1889 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1891 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
1892 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1893 ret = it->function(it->data);
1896 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
1901 /* find the mISDNport that belongs to the stack */
1902 mISDNport = mISDNport_first;
1905 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
1907 mISDNport = mISDNport->next;
1911 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1916 if (!(frm->addr&FLG_CHILD_STACK))
1921 case MGR_SHORTSTATUS | INDICATION:
1922 case MGR_SHORTSTATUS | CONFIRM:
1923 switch(frm->dinfo) {
1924 case SSTATUS_L1_ACTIVATED:
1925 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1928 case SSTATUS_L1_DEACTIVATED:
1929 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1932 case SSTATUS_L2_ESTABLISHED:
1933 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1936 case SSTATUS_L2_RELEASED:
1937 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1943 case PH_ACTIVATE | CONFIRM:
1944 case PH_ACTIVATE | INDICATION:
1945 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1947 if (mISDNport->ntmode)
1949 mISDNport->l1link = 1;
1950 setup_queue(mISDNport, 1);
1954 mISDNport->l1link = 1;
1955 setup_queue(mISDNport, 1);
1958 case PH_DEACTIVATE | CONFIRM:
1959 case PH_DEACTIVATE | INDICATION:
1960 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1962 if (mISDNport->ntmode)
1964 mISDNport->l1link = 0;
1965 setup_queue(mISDNport, 0);
1969 mISDNport->l1link = 0;
1970 setup_queue(mISDNport, 0);
1973 case PH_CONTROL | CONFIRM:
1974 case PH_CONTROL | INDICATION:
1975 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1978 case DL_ESTABLISH | INDICATION:
1979 case DL_ESTABLISH | CONFIRM:
1980 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1982 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1984 if (mISDNport->l2establish)
1986 mISDNport->l2establish = 0;
1987 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1989 mISDNport->l2link = 1;
1992 case DL_RELEASE | INDICATION:
1993 case DL_RELEASE | CONFIRM:
1994 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1996 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1998 mISDNport->l2link = 0;
2001 time(&mISDNport->l2establish);
2002 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2008 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);
2009 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2011 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2014 if (mISDNport->ntmode)
2016 /* l1-data enters the nt-mode library */
2017 nst = &mISDNport->nst;
2018 if (nst->l1_l2(nst, msg))
2023 /* l3-data is sent to pbx */
2024 if (stack2manager_te(mISDNport, msg))
2035 /* we don't care about confirms, we use rx data to sync tx */
2036 case PH_DATA | CONFIRM:
2037 case DL_DATA | CONFIRM:
2040 /* we receive audio data, we respond to it AND we send tones */
2041 case PH_DATA | INDICATION:
2042 case DL_DATA | INDICATION:
2043 case PH_CONTROL | INDICATION:
2045 while(i < mISDNport->b_num)
2047 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2051 if (i == mISDNport->b_num)
2053 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2056 if (mISDNport->b_port[i])
2058 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2059 mISDNport->b_port[i]->bchannel_receive(frm);
2061 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2064 case PH_ACTIVATE | INDICATION:
2065 case DL_ESTABLISH | INDICATION:
2066 case PH_ACTIVATE | CONFIRM:
2067 case DL_ESTABLISH | CONFIRM:
2068 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2070 while(i < mISDNport->b_num)
2072 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2076 if (i == mISDNport->b_num)
2078 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2081 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED, 0);
2084 case PH_DEACTIVATE | INDICATION:
2085 case DL_RELEASE | INDICATION:
2086 case PH_DEACTIVATE | CONFIRM:
2087 case DL_RELEASE | CONFIRM:
2088 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2090 while(i < mISDNport->b_num)
2092 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2096 if (i == mISDNport->b_num)
2098 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2101 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED, 0);
2105 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2116 * global function to add a new card (port)
2118 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
2121 unsigned char buff[1025];
2122 iframe_t *frm = (iframe_t *)buff;
2123 struct mISDNport *mISDNport, **mISDNportp;
2128 // struct mlayer3 *layer3;
2130 // interface_info_t ii;
2134 stack_info_t *stinf;
2137 /* query port's requirements */
2138 cnt = mISDN_get_stack_count(mISDNdevice);
2141 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2144 if (port>cnt || port<1)
2146 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2149 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2152 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2155 stinf = (stack_info_t *)&frm->data.p;
2156 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2158 case ISDN_PID_L0_TE_S0:
2159 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2161 case ISDN_PID_L0_NT_S0:
2162 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2165 case ISDN_PID_L0_TE_E1:
2166 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2169 case ISDN_PID_L0_NT_E1:
2170 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2175 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2181 if (stinf->pid.protocol[1] == 0)
2183 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2186 if (stinf->pid.protocol[2])
2188 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2194 if (stinf->pid.protocol[1] == 0)
2196 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2199 if (stinf->pid.protocol[2] == 0)
2201 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2204 if (stinf->pid.protocol[3] == 0)
2206 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2210 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2212 case ISDN_PID_L3_DSS1USER:
2216 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2220 if (stinf->pid.protocol[4])
2222 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2227 /* add mISDNport structure */
2228 mISDNportp = &mISDNport_first;
2230 mISDNportp = &((*mISDNportp)->next);
2231 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2233 *mISDNportp = mISDNport;
2235 /* allocate ressources of port */
2238 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2243 prop |= FLG_FORCE_PTMP;
2244 mISDNport->layer3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2245 if (!mISDNport->layer3)
2247 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2251 #warning KKEIL: braucht man das noch?
2252 /* if ntmode, establish L1 to send the tei removal during start */
2253 if (mISDNport->ntmode)
2257 act.prim = PH_ACTIVATE | REQUEST;
2258 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2259 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2262 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2263 usleep(10000); /* to be sure, that l1 is up */
2267 msg_queue_init(&mISDNport->downqueue);
2268 mISDNport->d_stid = stinf->id;
2269 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2270 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2272 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2276 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
2281 /* create layer intance */
2282 memset(&li, 0, sizeof(li));
2283 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
2286 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
2287 li.pid.layermask = ISDN_LAYER((nt?2:4));
2288 li.st = mISDNport->d_stid;
2289 ret = mISDN_new_layer(mISDNdevice, &li);
2292 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
2294 mISDNport_close(mISDNport);
2297 mISDNport->upper_id = li.id;
2298 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
2301 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2304 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2305 if (mISDNport->lower_id < 0)
2307 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2310 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2311 if (mISDNport->upper_id < 0)
2313 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2316 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2318 /* if ntmode, establish L1 to send the tei removal during start */
2319 if (mISDNport->ntmode)
2323 act.prim = PH_ACTIVATE | REQUEST;
2324 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2325 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2328 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2329 usleep(10000); /* to be sure, that l1 is up */
2332 /* create nst (nt-mode only) */
2335 mgr = &mISDNport->mgr;
2336 nst = &mISDNport->nst;
2341 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2342 nst->device = mISDNdevice;
2344 nst->d_stid = mISDNport->d_stid;
2346 nst->feature = FEATURE_NET_HOLD;
2348 nst->feature |= FEATURE_NET_PTP;
2350 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2353 while(i < mISDNport->b_num)
2355 nst->b_stid[i] = mISDNport->b_stid[i];
2359 nst->l1_id = mISDNport->lower_id;
2360 nst->l2_id = mISDNport->upper_id;
2363 msg_queue_init(&nst->down_queue);
2370 // SCPY(mISDNport->name, "noname");
2371 mISDNport->portnum = port;
2372 mISDNport->ntmode = nt;
2373 mISDNport->pri = pri;
2374 mISDNport->ptp = ptp;
2375 mISDNport->b_num = stinf->childcnt;
2376 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2378 while(i < stinf->childcnt)
2380 mISDNport->b_stid[i] = stinf->child[i];
2381 mISDNport->b_state[i] = B_STATE_IDLE;
2382 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
2386 /* if te-mode, query state link */
2387 if (!mISDNport->ntmode)
2391 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2392 act.prim = MGR_SHORTSTATUS | REQUEST;
2393 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2394 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2396 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2398 /* if ptp AND te-mode, pull up the link */
2399 if (mISDNport->ptp && !mISDNport->ntmode)
2403 act.prim = DL_ESTABLISH | REQUEST;
2404 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2407 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2409 /* if ptp AND nt-mode, pull up the link */
2410 if (mISDNport->ptp && mISDNport->ntmode)
2414 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2415 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2418 /* initially, we assume that the link is down, exept for nt-ptmp */
2419 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2421 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2423 start_trace(mISDNport->portnum,
2431 add_trace("channels", NULL, "%d", mISDNport->b_num);
2438 * function to free ALL cards (ports)
2440 void mISDNport_close_all(void)
2442 /* free all ports */
2443 while(mISDNport_first)
2444 mISDNport_close(mISDNport_first);
2448 * free only one port
2450 void mISDNport_close(struct mISDNport *mISDNport)
2452 struct mISDNport **mISDNportp;
2454 class PmISDN *isdnport;
2456 unsigned char buf[32];
2459 /* remove all port instance that are linked to this mISDNport */
2463 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2465 isdnport = (class PmISDN *)port;
2466 if (isdnport->p_m_mISDNport)
2468 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2475 /* only if we are already part of interface */
2476 if (mISDNport->ifport)
2478 start_trace(mISDNport->portnum,
2479 mISDNport->ifport->interface,
2489 /* free bchannels */
2491 while(i < mISDNport->b_num)
2493 if (mISDNport->b_addr[i])
2495 _bchannel_destroy(mISDNport, i);
2496 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2501 /* free ressources of port */
2502 msg_queue_purge(&mISDNport->downqueue);
2505 if (mISDNport->ntmode)
2507 nst = &mISDNport->nst;
2508 if (nst->manager) /* to see if initialized */
2510 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");
2511 cleanup_Isdnl3(nst);
2512 cleanup_Isdnl2(nst);
2515 msg_queue_purge(&nst->down_queue);
2516 if (nst->phd_down_msg)
2517 FREE(nst->phd_down_msg, 0);
2521 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2522 if (mISDNport->d_stid)
2524 if (mISDNport->upper_id)
2525 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2528 /* remove from list */
2529 mISDNportp = &mISDNport_first;
2532 if (*mISDNportp == mISDNport)
2534 *mISDNportp = (*mISDNportp)->next;
2538 mISDNportp = &((*mISDNportp)->next);
2542 FATAL("mISDNport not in list\n");
2544 FREE(mISDNport, sizeof(struct mISDNport));
2551 * global function to show all available isdn ports
2553 void mISDN_port_info(void)
2557 int useable, nt, pri;
2558 unsigned char buff[1025];
2559 iframe_t *frm = (iframe_t *)buff;
2560 stack_info_t *stinf;
2564 if ((device = mISDN_open()) < 0)
2566 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));
2570 /* get number of stacks */
2572 ii = mISDN_get_stack_count(device);
2576 printf("Found no card. Please be sure to load card drivers.\n");
2579 /* loop the number of cards and get their info */
2582 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2585 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2588 stinf = (stack_info_t *)&frm->data.p;
2593 /* output the port info */
2594 printf("Port %2d: ", i);
2595 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2597 case ISDN_PID_L0_TE_S0:
2598 printf("TE-mode BRI S/T interface line (for phone lines)");
2600 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2601 printf(" HFC multiport card");
2604 case ISDN_PID_L0_NT_S0:
2606 printf("NT-mode BRI S/T interface port (for phones)");
2608 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2609 printf(" HFC multiport card");
2612 case ISDN_PID_L0_TE_E1:
2614 printf("TE-mode PRI E1 interface line (for phone lines)");
2616 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2617 printf(" HFC-E1 card");
2620 case ISDN_PID_L0_NT_E1:
2623 printf("NT-mode PRI E1 interface port (for phones)");
2625 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2626 printf(" HFC-E1 card");
2631 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2637 if (stinf->pid.protocol[1] == 0)
2640 printf(" -> Missing layer 1 NT-mode protocol.\n");
2643 while(p <= MAX_LAYER_NR) {
2644 if (stinf->pid.protocol[p])
2647 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2654 printf(" -> Interface is Point-To-Point (PRI).\n");
2656 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2660 if (stinf->pid.protocol[1] == 0)
2663 printf(" -> Missing layer 1 protocol.\n");
2665 if (stinf->pid.protocol[2] == 0)
2668 printf(" -> Missing layer 2 protocol.\n");
2670 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2672 printf(" -> Interface is Poin-To-Point.\n");
2674 if (stinf->pid.protocol[3] == 0)
2677 printf(" -> Missing layer 3 protocol.\n");
2680 printf(" -> Protocol: ");
2681 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2683 case ISDN_PID_L3_DSS1USER:
2684 printf("DSS1 (Euro ISDN)");
2689 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2694 while(p <= MAX_LAYER_NR) {
2695 if (stinf->pid.protocol[p])
2698 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2703 printf(" - %d B-channels\n", stinf->childcnt);
2706 printf(" * Port NOT useable for LCR\n");
2708 printf("--------\n");
2715 if ((err = mISDN_close(device)))
2716 FATAL("mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2721 * enque data from upper buffer
2723 void PmISDN::txfromup(unsigned char *data, int length)
2725 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2726 iframe_t *frm = (iframe_t *)buf;
2728 /* configure frame */
2729 frm->prim = DL_DATA | REQUEST;
2730 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
2733 /* check if high priority tones exist
2734 * ignore data in this case
2736 if (p_tone_name[0] || p_m_crypt_msg_loops)
2739 /* preload procedure
2740 * if transmit buffer in DSP module is empty,
2741 * preload it to DSP_LOAD to prevent jitter gaps.
2743 if (p_m_load==0 && ISDN_LOAD>0)
2746 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
2747 frm->len = ISDN_LOAD;
2748 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2749 p_m_load += frm->len;
2752 /* drop if load would exceed ISDN_MAXLOAD
2753 * this keeps the delay not too high
2755 if (p_m_load+length > ISDN_MAXLOAD)
2758 /* load data to buffer
2760 memcpy(buf+mISDN_HEADER_LEN, data, length);
2762 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2763 p_m_load += frm->len;