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_remote_* is set.
627 the b_remote_*[index] indicates if and where the channel is exported to. (set from the point on, where export is initiated, until imported is acknowledged.)
628 - set on export request from remote application (if port is assigned)
629 - set on channel use, if requested by remote application (p_m_remote_*)
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_remote_*[index] is set to the remote socket id.
637 if importing has been acknowledged. b_remote_*[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;
681 mISDNport->b_remote_ref[i] = p_m_remote_ref;
684 /* create stack and send activation request */
685 if (_bchannel_create(mISDNport, i))
687 _bchannel_activate(mISDNport, i, 1);
688 state = B_STATE_ACTIVATING;
693 case B_STATE_ACTIVATING:
694 case B_STATE_EXPORTING:
695 /* do nothing, because it is already activating */
698 case B_STATE_DEACTIVATING:
699 case B_STATE_IMPORTING:
700 /* do nothing, because we must wait until we can reactivate */
704 /* problems that might ocurr:
705 * B_EVENT_USE is received when channel already in use.
706 * bchannel exported, but not freed by other port
708 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
712 case B_EVENT_EXPORTREQUEST:
713 /* special case where the bchannel is requested by remote */
716 PERROR("export request without remote channel set, please correct.\n");
722 /* in case, the bchannel is exported right after seize_bchannel */
723 /* export bchannel */
724 /* p_m_remote_id is set, when this event happens. */
725 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, addr);
726 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
727 add_trace("type", NULL, "assign");
728 add_trace("stack", "address", "%x", addr);
730 state = B_STATE_EXPORTING;
731 mISDNport->b_remote_id[i] = p_m_remote_id;
732 mISDNport->b_remote_ref[i] = p_m_remote_ref;
735 case B_STATE_ACTIVATING:
736 case B_STATE_EXPORTING:
737 /* do nothing, because it is already activating */
740 case B_STATE_DEACTIVATING:
741 case B_STATE_IMPORTING:
742 /* do nothing, because we must wait until we can reactivate */
746 /* bchannel is active, so we deactivate */
747 _bchannel_activate(mISDNport, i, 0);
748 state = B_STATE_DEACTIVATING;
752 /* problems that might ocurr:
753 * ... when channel already in use.
754 * bchannel exported, but not freed by other port
756 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
760 case B_EVENT_ACTIVATED:
763 case B_STATE_ACTIVATING:
764 if (b_port && !p_m_remote_id)
766 /* bchannel is active and used by Port class, so we configure bchannel */
767 _bchannel_configure(mISDNport, i);
768 state = B_STATE_ACTIVE;
771 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
772 _bchannel_activate(mISDNport, i, 0);
773 state = B_STATE_DEACTIVATING;
778 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
782 case B_EVENT_EXPORTED:
785 case B_STATE_EXPORTING:
786 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
788 /* remote export done */
789 state = B_STATE_REMOTE;
792 /* bchannel is now exported, but we need bchannel back
793 * OR bchannel is not used anymore
794 * OR bchannel has been exported to an obsolete ref,
795 * so reimport, to later export to new remote */
796 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, addr);
797 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
798 add_trace("type", NULL, "remove");
799 add_trace("stack", "address", "%x", addr);
801 state = B_STATE_IMPORTING;
806 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
812 FATAL("bchannel must be linked to a Port class\n");
816 /* bchannel is idle due to an error, so we do nothing */
819 case B_STATE_ACTIVATING:
820 case B_STATE_EXPORTING:
821 /* do nothing because we must wait until bchanenl is active before deactivating */
825 /* bchannel is active, so we deactivate */
826 _bchannel_activate(mISDNport, i, 0);
827 state = B_STATE_DEACTIVATING;
831 /* bchannel is exported, so we re-import */
832 message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, addr);
833 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
834 add_trace("type", NULL, "remove");
835 add_trace("stack", "address", "%x", addr);
837 state = B_STATE_IMPORTING;
840 case B_STATE_DEACTIVATING:
841 case B_STATE_IMPORTING:
842 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
846 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
850 case B_EVENT_DEACTIVATED:
854 /* ignore due to deactivation confirm after unloading */
857 case B_STATE_DEACTIVATING:
858 _bchannel_destroy(mISDNport, i);
859 state = B_STATE_IDLE;
862 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
865 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, addr);
866 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
867 add_trace("type", NULL, "assign");
868 add_trace("stack", "address", "%x", addr);
870 state = B_STATE_EXPORTING;
871 mISDNport->b_remote_id[i] = p_m_remote_id;
872 mISDNport->b_remote_ref[i] = p_m_remote_ref;
875 if (_bchannel_create(mISDNport, i))
877 _bchannel_activate(mISDNport, i, 1);
878 state = B_STATE_ACTIVATING;
885 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
889 case B_EVENT_IMPORTED:
892 case B_STATE_IMPORTING:
893 state = B_STATE_IDLE;
894 mISDNport->b_remote_id[i] = 0;
895 mISDNport->b_remote_ref[i] = 0;
898 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
901 message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, addr);
902 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
903 add_trace("type", NULL, "assign");
904 add_trace("stack", "address", "%x", addr);
906 state = B_STATE_EXPORTING;
907 mISDNport->b_remote_id[i] = p_m_remote_id;
908 mISDNport->b_remote_ref[i] = p_m_remote_ref;
911 if (_bchannel_create(mISDNport, i))
913 _bchannel_activate(mISDNport, i, 1);
914 state = B_STATE_ACTIVATING;
921 /* ignore, because not assigned */
927 PERROR("Illegal event %d, please correct.\n", event);
930 mISDNport->b_state[i] = state;
937 * check for available channel and reserve+set it.
938 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
940 * returns -(cause value) or x = channel x or 0 = no channel
941 * NOTE: no activation is done here
943 int PmISDN::seize_bchannel(int channel, int exclusive)
947 /* the channel is what we have */
948 if (p_m_b_channel == channel)
951 /* if channel already in use, release it */
956 if (channel==CHANNEL_NO || channel==0)
959 /* is channel in range ? */
961 || (channel>p_m_mISDNport->b_num && channel<16)
962 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
963 return(-6); /* channel unacceptable */
965 /* request exclusive channel */
966 if (exclusive && channel>0)
968 i = channel-1-(channel>16);
969 if (p_m_mISDNport->b_port[i])
970 return(-44); /* requested channel not available */
974 /* ask for channel */
977 i = channel-1-(channel>16);
978 if (p_m_mISDNport->b_port[i] == NULL)
982 /* search for channel */
984 while(i < p_m_mISDNport->b_num)
986 if (!p_m_mISDNport->b_port[i])
988 channel = i+1+(i>=15);
993 return(-34); /* no free channel */
996 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
999 p_m_mISDNport->b_port[i] = this;
1001 p_m_b_channel = channel;
1002 p_m_b_exclusive = exclusive;
1004 /* reserve channel */
1008 p_m_mISDNport->b_reserved++;
1015 * drop reserved channel and unset it.
1016 * deactivation is also done
1018 void PmISDN::drop_bchannel(void)
1020 if (p_m_b_index < 0)
1023 /* unreserve channel */
1025 p_m_mISDNport->b_reserved--;
1032 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1034 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1035 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1036 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1039 p_m_b_exclusive = 0;
1042 /* process bchannel export/import message from join */
1043 void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long addr)
1045 class Endpoint *epoint;
1047 class PmISDN *isdnport;
1048 struct mISDNport *mISDNport;
1053 case BCHANNEL_REQUEST:
1054 /* find the port object for the join object ref */
1055 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1057 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1060 if (!epoint->ep_portlist)
1062 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1065 if (epoint->ep_portlist->next)
1067 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);
1069 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1071 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1074 if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
1076 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1078 isdnport = (class PmISDN *)port;
1081 if (isdnport->p_m_remote_id)
1083 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1086 mISDNport = isdnport->p_m_mISDNport;
1087 i = isdnport->p_m_b_index;
1088 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1089 add_trace("type", NULL, "export request");
1090 isdnport->p_m_remote_ref = joinremote->j_serial;
1091 isdnport->p_m_remote_id = joinremote->j_remote_id;
1092 if (mISDNport && i>=0)
1094 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1099 case BCHANNEL_ASSIGN_ACK:
1100 case BCHANNEL_REMOVE_ACK:
1101 /* find mISDNport for stack ID */
1102 mISDNport = mISDNport_first;
1106 ii = mISDNport->b_num;
1109 if (mISDNport->b_addr[i] == addr)
1115 mISDNport = mISDNport->next;
1119 PERROR("received assign/remove ack for addr=%x, but address does not exist.\n", addr);
1122 /* mISDNport may now be set or NULL */
1125 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1126 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1127 if (mISDNport && i>=0)
1128 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1132 PERROR("received wrong bchannel message type %d from remote\n", type);
1140 audio transmission procedure:
1141 -----------------------------
1144 three sources of audio transmission:
1145 - crypto-data high priority
1146 - tones high priority (also high)
1147 - remote-data low priority
1150 a variable that temporarily shows the number of samples elapsed since last transmission process.
1151 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1154 a variable that is increased whenever data is transmitted.
1155 it is decreased while time elapses. it stores the number of samples that
1156 are currently loaded to dsp module.
1157 since clock in dsp module is the same clock for user space process, these
1161 there are two levels:
1162 ISDN_LOAD will give the load that have to be kept in dsp.
1163 ISDN_MAXLOAD will give the maximum load before dropping.
1165 * procedure for low priority data
1166 see txfromup() for procedure
1167 in short: remote data is ignored during high priority tones
1169 * procedure for high priority data
1170 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1171 if no more data is available, load becomes empty again.
1174 0 ISDN_LOAD ISDN_MAXLOAD
1175 +--------------------+----------------------+
1177 +--------------------+----------------------+
1179 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1180 0 ISDN_LOAD ISDN_MAXLOAD
1181 +--------------------+----------------------+
1182 |TTTTTTTTTTTTTTTTTTTT| |
1183 +--------------------+----------------------+
1185 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1186 0 ISDN_LOAD ISDN_MAXLOAD
1187 +--------------------+----------------------+
1188 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1189 +--------------------+----------------------+
1192 int PmISDN::handler(void)
1194 struct message *message;
1198 if ((ret = Port::handler()))
1202 if (p_m_last_tv_sec)
1204 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1205 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1208 /* set clock of first process ever in this instance */
1209 p_m_last_tv_sec = now_tv.tv_sec;
1210 p_m_last_tv_msec = now_tv.tv_usec/1000;
1212 /* process only if we have a minimum of samples, to make packets not too small */
1213 if (elapsed >= ISDN_TRANSMIT)
1215 /* set clock of last process! */
1216 p_m_last_tv_sec = now_tv.tv_sec;
1217 p_m_last_tv_msec = now_tv.tv_usec/1000;
1220 if (elapsed < p_m_load)
1221 p_m_load -= elapsed;
1225 /* to send data, tone must be active OR crypt messages must be on */
1226 if ((p_tone_name[0] || p_m_crypt_msg_loops) && p_m_load < ISDN_LOAD)
1228 int tosend = ISDN_LOAD - p_m_load, length;
1229 unsigned char buf[mISDN_HEADER_LEN+tosend];
1230 iframe_t *frm = (iframe_t *)buf;
1231 unsigned char *p = buf+mISDN_HEADER_LEN;
1233 /* copy crypto loops */
1234 while (p_m_crypt_msg_loops && tosend)
1236 /* how much do we have to send */
1237 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1240 if (length > tosend)
1243 /* copy message (part) to buffer */
1244 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1247 p_m_crypt_msg_current += length;
1248 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1251 p_m_crypt_msg_current = 0;
1252 p_m_crypt_msg_loops--;
1260 if (p_tone_name[0] && tosend)
1262 tosend -= read_audio(p, tosend);
1266 frm->prim = DL_DATA | REQUEST;
1267 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
1269 frm->len = ISDN_LOAD - p_m_load - tosend;
1271 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
1272 p_m_load += frm->len;
1276 // NOTE: deletion is done by the child class
1278 /* handle timeouts */
1281 if (p_m_timer+p_m_timeout < now_d)
1283 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1285 /* send timeout to endpoint */
1286 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1287 message->param.state = p_state;
1288 message_put(message);
1293 return(0); /* nothing done */
1298 * whenever we get audio data from bchannel, we process it here
1300 void PmISDN::bchannel_receive(iframe_t *frm)
1302 unsigned char *data_temp;
1303 unsigned long length_temp;
1304 struct message *message;
1309 if (frm->prim == (PH_CONTROL | INDICATION))
1313 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1316 cont = *((unsigned long *)&frm->data.p);
1317 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1319 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1320 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1322 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1323 message->param.dtmf = cont & DTMF_TONE_MASK;
1324 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1325 message_put(message);
1331 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1332 add_trace("DSP-CRYPT", NULL, "error");
1334 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1335 message->param.crypt.type = CC_ERROR_IND;
1336 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1337 message_put(message);
1341 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1342 add_trace("DSP-CRYPT", NULL, "ok");
1344 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1345 message->param.crypt.type = CC_ACTBF_CONF;
1346 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1347 message_put(message);
1353 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1354 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1358 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
1362 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1363 add_trace("unknown", NULL, "0x%x", cont);
1368 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1370 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1374 /* calls will not process any audio data unless
1375 * the call is connected OR interface features audio during call setup.
1377 //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);
1378 #ifndef DEBUG_COREBRIDGE
1379 if (p_state!=PORT_STATE_CONNECT
1380 && !p_m_mISDNport->earlyb)
1384 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1387 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1393 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1395 /* randomize and listen to crypt message if enabled */
1396 if (p_m_crypt_listen)
1398 /* the noisy randomizer */
1399 p = (unsigned char *)&frm->data.p;
1402 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1404 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1407 p = (unsigned char *)&frm->data.p;
1409 /* send data to epoint */
1410 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1412 length_temp = frm->len;
1416 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1417 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1418 memcpy(message->param.data.data, data_temp, message->param.data.len);
1419 message_put(message);
1420 if (length_temp <= sizeof(message->param.data.data))
1422 data_temp += sizeof(message->param.data.data);
1423 length_temp -= sizeof(message->param.data.data);
1432 void PmISDN::set_echotest(int echo)
1434 if (p_m_echo != echo)
1437 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1439 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1440 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);
1447 void PmISDN::set_tone(char *dir, char *tone)
1453 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1460 /* check if we NOT really have to use a dsp-tone */
1461 if (!options.dsptones)
1465 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1467 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1468 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1471 Port::set_tone(dir, tone);
1477 /* now we USE dsp-tone, convert name */
1478 else if (!strcmp(tone, "dialtone"))
1480 switch(options.dsptones) {
1481 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1482 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1483 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1485 } else if (!strcmp(tone, "dialpbx"))
1487 switch(options.dsptones) {
1488 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1489 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1490 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1492 } else if (!strcmp(tone, "ringing"))
1494 switch(options.dsptones) {
1495 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1496 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1497 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1499 } else if (!strcmp(tone, "ringpbx"))
1501 switch(options.dsptones) {
1502 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1503 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1504 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1506 } else if (!strcmp(tone, "busy"))
1509 switch(options.dsptones) {
1510 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1511 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1512 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1514 } else if (!strcmp(tone, "release"))
1517 switch(options.dsptones) {
1518 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1519 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1520 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1522 } else if (!strcmp(tone, "cause_10"))
1524 else if (!strcmp(tone, "cause_11"))
1526 else if (!strcmp(tone, "cause_22"))
1528 switch(options.dsptones) {
1529 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1530 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1531 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1533 } else if (!strncmp(tone, "cause_", 6))
1534 id = TONE_SPECIAL_INFO;
1538 /* if we have a tone that is not supported by dsp */
1539 if (id==TONE_OFF && tone[0])
1547 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1549 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1550 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);
1552 /* turn user-space tones off in cases of no tone OR dsp tone */
1553 Port::set_tone("",NULL);
1557 /* MESSAGE_mISDNSIGNAL */
1558 //extern struct message *dddebug;
1559 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1561 switch(param->mISDNsignal.message)
1563 case mISDNSIGNAL_VOLUME:
1564 if (p_m_txvol != param->mISDNsignal.txvol)
1566 p_m_txvol = param->mISDNsignal.txvol;
1567 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1569 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1570 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);
1572 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1573 if (p_m_rxvol != param->mISDNsignal.rxvol)
1575 p_m_rxvol = param->mISDNsignal.rxvol;
1576 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1578 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1579 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);
1581 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1584 case mISDNSIGNAL_CONF:
1585 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1586 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1587 if (p_m_conf != param->mISDNsignal.conf)
1589 p_m_conf = param->mISDNsignal.conf;
1590 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1592 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1593 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);
1595 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1596 /* we must set, even if currently tone forbids conf */
1597 p_m_conf = param->mISDNsignal.conf;
1598 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1601 case mISDNSIGNAL_JOINDATA:
1602 if (p_m_joindata != param->mISDNsignal.joindata)
1604 p_m_joindata = param->mISDNsignal.joindata;
1605 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1607 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1610 case mISDNSIGNAL_DELAY:
1611 if (p_m_delay != param->mISDNsignal.delay)
1613 p_m_delay = param->mISDNsignal.delay;
1614 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1616 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1617 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);
1619 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1623 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1628 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1630 struct message *message;
1632 switch(param->crypt.type)
1634 case CC_ACTBF_REQ: /* activate blowfish */
1636 p_m_crypt_key_len = param->crypt.len;
1637 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1639 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1640 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1641 message->param.crypt.type = CC_ERROR_IND;
1642 message_put(message);
1645 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1647 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1649 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1650 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);
1653 case CC_DACT_REQ: /* deactivate session encryption */
1658 case CR_LISTEN_REQ: /* start listening to messages */
1659 p_m_crypt_listen = 1;
1660 p_m_crypt_listen_state = 0;
1663 case CR_UNLISTEN_REQ: /* stop listening to messages */
1664 p_m_crypt_listen = 0;
1667 case CR_MESSAGE_REQ: /* send message */
1668 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1669 if (!p_m_crypt_msg_len)
1671 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1674 p_m_crypt_msg_current = 0; /* reset */
1675 p_m_crypt_msg_loops = 3; /* enable */
1677 /* disable txmix, or we get corrupt data due to audio process */
1680 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1681 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1687 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1693 * endpoint sends messages to the port
1695 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1697 if (Port::message_epoint(epoint_id, message_id, param))
1702 case MESSAGE_DATA: /* tx-data from upper layer */
1703 txfromup(param->data.data, param->data.len);
1706 case MESSAGE_mISDNSIGNAL: /* user command */
1707 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1708 message_mISDNsignal(epoint_id, message_id, param);
1711 case MESSAGE_CRYPT: /* crypt control command */
1712 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1713 message_crypt(epoint_id, message_id, param);
1722 * main loop for processing messages from mISDN device
1724 int mISDN_handler(void)
1729 struct mISDNport *mISDNport;
1730 class PmISDN *isdnport;
1733 mISDNuser_head_t *hh;
1736 /* the que avoids loopbacks when replying to stack after receiving
1738 mISDNport = mISDNport_first;
1741 /* process turning on/off rx */
1743 while(i < mISDNport->b_num)
1745 isdnport=mISDNport->b_port[i];
1748 /* call bridges in user space OR crypto OR recording */
1749 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1751 /* rx IS required */
1752 if (isdnport->p_m_rxoff)
1755 isdnport->p_m_rxoff = 0;
1756 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1757 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1758 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1763 /* rx NOT required */
1764 if (!isdnport->p_m_rxoff)
1767 isdnport->p_m_rxoff = 1;
1768 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1769 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1770 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1775 if (isdnport->p_record)
1777 /* txdata IS required */
1778 if (!isdnport->p_m_txdata)
1781 isdnport->p_m_txdata = 1;
1782 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1783 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1784 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1789 /* txdata NOT required */
1790 if (isdnport->p_m_txdata)
1793 isdnport->p_m_txdata = 0;
1794 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1795 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1796 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1804 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1806 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1807 mISDNport->l1timeout = 0;
1810 if (mISDNport->l2establish)
1812 if (now-mISDNport->l2establish > 5)
1814 if (mISDNport->ntmode)
1816 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1817 time(&mISDNport->l2establish);
1819 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1820 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1823 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1824 time(&mISDNport->l2establish);
1827 act.prim = DL_ESTABLISH | REQUEST;
1828 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1831 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1833 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1838 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1840 if (mISDNport->ntmode)
1842 hh = (mISDNuser_head_t *)dmsg->data;
1843 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);
1844 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1848 frm = (iframe_t *)dmsg->data;
1849 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1850 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1851 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);
1852 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1857 mISDNport = mISDNport->next;
1860 /* no device, no read */
1861 if (mISDNdevice < 0)
1864 /* get message from kernel */
1865 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1867 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1871 if (errno == EAGAIN)
1873 FATAL("Failed to do mISDN_read()\n");
1878 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1882 frm = (iframe_t *)msg->data;
1887 case MGR_DELLAYER | CONFIRM:
1888 case MGR_INITTIMER | CONFIRM:
1889 case MGR_ADDTIMER | CONFIRM:
1890 case MGR_DELTIMER | CONFIRM:
1891 case MGR_REMOVETIMER | CONFIRM:
1896 /* handle timer events from mISDN for NT-stack
1897 * note: they do not associate with a stack */
1898 if (frm->prim == (MGR_TIMER | INDICATION))
1902 /* find mISDNport */
1903 mISDNport = mISDNport_first;
1907 if (mISDNport->ntmode)
1909 it = mISDNport->nst.tlist;
1913 if (it->id == (int)frm->addr)
1920 mISDNport = mISDNport->next;
1924 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1925 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1927 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
1928 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1929 ret = it->function(it->data);
1932 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
1937 /* find the mISDNport that belongs to the stack */
1938 mISDNport = mISDNport_first;
1941 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
1943 mISDNport = mISDNport->next;
1947 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1952 if (!(frm->addr&FLG_CHILD_STACK))
1957 case MGR_SHORTSTATUS | INDICATION:
1958 case MGR_SHORTSTATUS | CONFIRM:
1959 switch(frm->dinfo) {
1960 case SSTATUS_L1_ACTIVATED:
1961 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1964 case SSTATUS_L1_DEACTIVATED:
1965 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1968 case SSTATUS_L2_ESTABLISHED:
1969 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1972 case SSTATUS_L2_RELEASED:
1973 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1979 case PH_ACTIVATE | CONFIRM:
1980 case PH_ACTIVATE | INDICATION:
1981 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1983 if (mISDNport->ntmode)
1985 mISDNport->l1link = 1;
1986 setup_queue(mISDNport, 1);
1990 mISDNport->l1link = 1;
1991 setup_queue(mISDNport, 1);
1994 case PH_DEACTIVATE | CONFIRM:
1995 case PH_DEACTIVATE | INDICATION:
1996 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1998 if (mISDNport->ntmode)
2000 mISDNport->l1link = 0;
2001 setup_queue(mISDNport, 0);
2005 mISDNport->l1link = 0;
2006 setup_queue(mISDNport, 0);
2009 case PH_CONTROL | CONFIRM:
2010 case PH_CONTROL | INDICATION:
2011 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
2014 case DL_ESTABLISH | INDICATION:
2015 case DL_ESTABLISH | CONFIRM:
2016 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2018 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2020 if (mISDNport->l2establish)
2022 mISDNport->l2establish = 0;
2023 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2025 mISDNport->l2link = 1;
2028 case DL_RELEASE | INDICATION:
2029 case DL_RELEASE | CONFIRM:
2030 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
2032 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
2034 mISDNport->l2link = 0;
2037 time(&mISDNport->l2establish);
2038 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
2044 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);
2045 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
2047 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
2050 if (mISDNport->ntmode)
2052 /* l1-data enters the nt-mode library */
2053 nst = &mISDNport->nst;
2054 if (nst->l1_l2(nst, msg))
2059 /* l3-data is sent to pbx */
2060 if (stack2manager_te(mISDNport, msg))
2071 /* we don't care about confirms, we use rx data to sync tx */
2072 case PH_DATA | CONFIRM:
2073 case DL_DATA | CONFIRM:
2076 /* we receive audio data, we respond to it AND we send tones */
2077 case PH_DATA | INDICATION:
2078 case DL_DATA | INDICATION:
2079 case PH_CONTROL | INDICATION:
2081 while(i < mISDNport->b_num)
2083 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2087 if (i == mISDNport->b_num)
2089 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2092 if (mISDNport->b_port[i])
2094 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
2095 mISDNport->b_port[i]->bchannel_receive(frm);
2097 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
2100 case PH_ACTIVATE | INDICATION:
2101 case DL_ESTABLISH | INDICATION:
2102 case PH_ACTIVATE | CONFIRM:
2103 case DL_ESTABLISH | CONFIRM:
2104 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
2106 while(i < mISDNport->b_num)
2108 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2112 if (i == mISDNport->b_num)
2114 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2117 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2120 case PH_DEACTIVATE | INDICATION:
2121 case DL_RELEASE | INDICATION:
2122 case PH_DEACTIVATE | CONFIRM:
2123 case DL_RELEASE | CONFIRM:
2124 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
2126 while(i < mISDNport->b_num)
2128 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
2132 if (i == mISDNport->b_num)
2134 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
2137 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2141 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
2152 * global function to add a new card (port)
2154 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
2157 unsigned char buff[1025];
2158 iframe_t *frm = (iframe_t *)buff;
2159 struct mISDNport *mISDNport, **mISDNportp;
2164 // struct mlayer3 *layer3;
2166 // interface_info_t ii;
2170 stack_info_t *stinf;
2173 /* query port's requirements */
2174 cnt = mISDN_get_stack_count(mISDNdevice);
2177 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2180 if (port>cnt || port<1)
2182 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
2185 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
2188 PERROR_RUNTIME("Cannot get stack info for port %d (ret=%d)\n", port, ret);
2191 stinf = (stack_info_t *)&frm->data.p;
2192 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2194 case ISDN_PID_L0_TE_S0:
2195 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
2197 case ISDN_PID_L0_NT_S0:
2198 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
2201 case ISDN_PID_L0_TE_E1:
2202 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
2205 case ISDN_PID_L0_NT_E1:
2206 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
2211 PERROR_RUNTIME("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
2217 if (stinf->pid.protocol[1] == 0)
2219 PERROR_RUNTIME("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
2222 if (stinf->pid.protocol[2])
2224 PERROR_RUNTIME("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
2230 if (stinf->pid.protocol[1] == 0)
2232 PERROR_RUNTIME("Given port %d: Missing layer 1 protocol.\n", port);
2235 if (stinf->pid.protocol[2] == 0)
2237 PERROR_RUNTIME("Given port %d: Missing layer 2 protocol.\n", port);
2240 if (stinf->pid.protocol[3] == 0)
2242 PERROR_RUNTIME("Given port %d: Missing layer 3 protocol.\n", port);
2246 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2248 case ISDN_PID_L3_DSS1USER:
2252 PERROR_RUNTIME("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
2256 if (stinf->pid.protocol[4])
2258 PERROR_RUNTIME("Given port %d: Layer 4 protocol not allowed.\n", port);
2263 /* add mISDNport structure */
2264 mISDNportp = &mISDNport_first;
2266 mISDNportp = &((*mISDNportp)->next);
2267 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2269 *mISDNportp = mISDNport;
2271 /* allocate ressources of port */
2274 protocol = (nt)?L3_PROTOCOL_DSS1_USER:L3_PROTOCOL_DSS1_NETWORK;
2279 prop |= FLG_FORCE_PTMP;
2280 mISDNport->layer3 = open_layer3(port-1, protocol, prop , do_dchannel, mISDNport);
2281 if (!mISDNport->layer3)
2283 PERROR_RUNTIME("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2287 #warning KKEIL: braucht man das noch?
2288 /* if ntmode, establish L1 to send the tei removal during start */
2289 if (mISDNport->ntmode)
2293 act.prim = PH_ACTIVATE | REQUEST;
2294 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2295 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2298 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2299 usleep(10000); /* to be sure, that l1 is up */
2303 msg_queue_init(&mISDNport->downqueue);
2304 mISDNport->d_stid = stinf->id;
2305 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
2306 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
2308 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
2312 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
2317 /* create layer intance */
2318 memset(&li, 0, sizeof(li));
2319 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
2322 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
2323 li.pid.layermask = ISDN_LAYER((nt?2:4));
2324 li.st = mISDNport->d_stid;
2325 ret = mISDN_new_layer(mISDNdevice, &li);
2328 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
2330 mISDNport_close(mISDNport);
2333 mISDNport->upper_id = li.id;
2334 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
2337 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2340 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2341 if (mISDNport->lower_id < 0)
2343 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2346 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2347 if (mISDNport->upper_id < 0)
2349 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2352 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2354 /* if ntmode, establish L1 to send the tei removal during start */
2355 if (mISDNport->ntmode)
2359 act.prim = PH_ACTIVATE | REQUEST;
2360 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2361 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2364 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2365 usleep(10000); /* to be sure, that l1 is up */
2368 /* create nst (nt-mode only) */
2371 mgr = &mISDNport->mgr;
2372 nst = &mISDNport->nst;
2377 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2378 nst->device = mISDNdevice;
2380 nst->d_stid = mISDNport->d_stid;
2382 nst->feature = FEATURE_NET_HOLD;
2384 nst->feature |= FEATURE_NET_PTP;
2386 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2389 while(i < mISDNport->b_num)
2391 nst->b_stid[i] = mISDNport->b_stid[i];
2395 nst->l1_id = mISDNport->lower_id;
2396 nst->l2_id = mISDNport->upper_id;
2399 msg_queue_init(&nst->down_queue);
2406 // SCPY(mISDNport->name, "noname");
2407 mISDNport->portnum = port;
2408 mISDNport->ntmode = nt;
2409 mISDNport->pri = pri;
2410 mISDNport->ptp = ptp;
2411 mISDNport->b_num = stinf->childcnt;
2412 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2414 while(i < stinf->childcnt)
2416 mISDNport->b_stid[i] = stinf->child[i];
2417 mISDNport->b_state[i] = B_STATE_IDLE;
2418 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
2422 /* if te-mode, query state link */
2423 if (!mISDNport->ntmode)
2427 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2428 act.prim = MGR_SHORTSTATUS | REQUEST;
2429 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2430 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2432 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2434 /* if ptp AND te-mode, pull up the link */
2435 if (mISDNport->ptp && !mISDNport->ntmode)
2439 act.prim = DL_ESTABLISH | REQUEST;
2440 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2443 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2445 /* if ptp AND nt-mode, pull up the link */
2446 if (mISDNport->ptp && mISDNport->ntmode)
2450 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2451 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2454 /* initially, we assume that the link is down, exept for nt-ptmp */
2455 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2457 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2459 start_trace(mISDNport->portnum,
2467 add_trace("channels", NULL, "%d", mISDNport->b_num);
2474 * function to free ALL cards (ports)
2476 void mISDNport_close_all(void)
2478 /* free all ports */
2479 while(mISDNport_first)
2480 mISDNport_close(mISDNport_first);
2484 * free only one port
2486 void mISDNport_close(struct mISDNport *mISDNport)
2488 struct mISDNport **mISDNportp;
2490 class PmISDN *isdnport;
2492 unsigned char buf[32];
2495 /* remove all port instance that are linked to this mISDNport */
2499 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2501 isdnport = (class PmISDN *)port;
2502 if (isdnport->p_m_mISDNport)
2504 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2511 /* only if we are already part of interface */
2512 if (mISDNport->ifport)
2514 start_trace(mISDNport->portnum,
2515 mISDNport->ifport->interface,
2525 /* free bchannels */
2527 while(i < mISDNport->b_num)
2529 if (mISDNport->b_addr[i])
2531 _bchannel_destroy(mISDNport, i);
2532 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2537 /* free ressources of port */
2538 msg_queue_purge(&mISDNport->downqueue);
2541 if (mISDNport->ntmode)
2543 nst = &mISDNport->nst;
2544 if (nst->manager) /* to see if initialized */
2546 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");
2547 cleanup_Isdnl3(nst);
2548 cleanup_Isdnl2(nst);
2551 msg_queue_purge(&nst->down_queue);
2552 if (nst->phd_down_msg)
2553 FREE(nst->phd_down_msg, 0);
2557 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2558 if (mISDNport->d_stid)
2560 if (mISDNport->upper_id)
2561 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2564 /* remove from list */
2565 mISDNportp = &mISDNport_first;
2568 if (*mISDNportp == mISDNport)
2570 *mISDNportp = (*mISDNportp)->next;
2574 mISDNportp = &((*mISDNportp)->next);
2578 FATAL("mISDNport not in list\n");
2580 FREE(mISDNport, sizeof(struct mISDNport));
2587 * global function to show all available isdn ports
2589 void mISDN_port_info(void)
2593 int useable, nt, pri;
2594 unsigned char buff[1025];
2595 iframe_t *frm = (iframe_t *)buff;
2596 stack_info_t *stinf;
2600 if ((device = mISDN_open()) < 0)
2602 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));
2606 /* get number of stacks */
2608 ii = mISDN_get_stack_count(device);
2612 printf("Found no card. Please be sure to load card drivers.\n");
2615 /* loop the number of cards and get their info */
2618 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2621 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2624 stinf = (stack_info_t *)&frm->data.p;
2629 /* output the port info */
2630 printf("Port %2d: ", i);
2631 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2633 case ISDN_PID_L0_TE_S0:
2634 printf("TE-mode BRI S/T interface line (for phone lines)");
2636 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2637 printf(" HFC multiport card");
2640 case ISDN_PID_L0_NT_S0:
2642 printf("NT-mode BRI S/T interface port (for phones)");
2644 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2645 printf(" HFC multiport card");
2648 case ISDN_PID_L0_TE_E1:
2650 printf("TE-mode PRI E1 interface line (for phone lines)");
2652 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2653 printf(" HFC-E1 card");
2656 case ISDN_PID_L0_NT_E1:
2659 printf("NT-mode PRI E1 interface port (for phones)");
2661 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2662 printf(" HFC-E1 card");
2667 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2673 if (stinf->pid.protocol[1] == 0)
2676 printf(" -> Missing layer 1 NT-mode protocol.\n");
2679 while(p <= MAX_LAYER_NR) {
2680 if (stinf->pid.protocol[p])
2683 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2690 printf(" -> Interface is Point-To-Point (PRI).\n");
2692 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2696 if (stinf->pid.protocol[1] == 0)
2699 printf(" -> Missing layer 1 protocol.\n");
2701 if (stinf->pid.protocol[2] == 0)
2704 printf(" -> Missing layer 2 protocol.\n");
2706 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2708 printf(" -> Interface is Poin-To-Point.\n");
2710 if (stinf->pid.protocol[3] == 0)
2713 printf(" -> Missing layer 3 protocol.\n");
2716 printf(" -> Protocol: ");
2717 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2719 case ISDN_PID_L3_DSS1USER:
2720 printf("DSS1 (Euro ISDN)");
2725 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2730 while(p <= MAX_LAYER_NR) {
2731 if (stinf->pid.protocol[p])
2734 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2739 printf(" - %d B-channels\n", stinf->childcnt);
2742 printf(" * Port NOT useable for LCR\n");
2744 printf("--------\n");
2751 if ((err = mISDN_close(device)))
2752 FATAL("mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2757 * enque data from upper buffer
2759 void PmISDN::txfromup(unsigned char *data, int length)
2761 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2762 iframe_t *frm = (iframe_t *)buf;
2764 /* configure frame */
2765 frm->prim = DL_DATA | REQUEST;
2766 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
2769 /* check if high priority tones exist
2770 * ignore data in this case
2772 if (p_tone_name[0] || p_m_crypt_msg_loops)
2775 /* preload procedure
2776 * if transmit buffer in DSP module is empty,
2777 * preload it to DSP_LOAD to prevent jitter gaps.
2779 if (p_m_load==0 && ISDN_LOAD>0)
2782 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
2783 frm->len = ISDN_LOAD;
2784 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2785 p_m_load += frm->len;
2788 /* drop if load would exceed ISDN_MAXLOAD
2789 * this keeps the delay not too high
2791 if (p_m_load+length > ISDN_MAXLOAD)
2794 /* load data to buffer
2796 memcpy(buf+mISDN_HEADER_LEN, data, length);
2798 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2799 p_m_load += frm->len;