1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
28 #define ISDN_PID_L2_B_USER 0x420000ff
29 #define ISDN_PID_L3_B_USER 0x430000ff
30 #define ISDN_PID_L4_B_USER 0x440000ff
32 /* used for udevice */
35 /* noise randomizer */
36 unsigned char mISDN_rand[256];
37 int mISDN_rand_count = 0;
39 /* the device handler and port list */
42 /* list of mISDN ports */
43 struct mISDNport *mISDNport_first;
48 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
50 p_m_mISDNport = mISDNport;
51 p_m_portnum = mISDNport->portnum;
58 p_m_txvol = p_m_rxvol = 0;
66 p_m_dtmf = !mISDNport->ifport->nodtmf;
77 p_m_crypt_msg_loops = 0;
78 p_m_crypt_msg_loops = 0;
79 p_m_crypt_msg_len = 0;
80 p_m_crypt_msg[0] = '\0';
81 p_m_crypt_msg_current = 0;
82 p_m_crypt_key[0] = '\0';
83 p_m_crypt_key_len = 0;
85 p_m_crypt_listen_state = 0;
86 p_m_crypt_listen_len = 0;
87 p_m_crypt_listen_msg[0] = '\0';
88 p_m_crypt_listen_crc = 0;
90 /* if any channel requested by constructor */
91 if (channel == CHANNEL_ANY)
95 mISDNport->b_reserved++;
99 if (channel > 0) // only if constructor was called with a channel resevation
100 seize_bchannel(channel, exclusive);
102 /* we increase the number of objects: */
104 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
113 struct message *message;
115 /* remove bchannel relation */
121 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
122 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
123 message->param.disconnectinfo.cause = 16;
124 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
125 message_put(message);
126 /* remove from list */
127 free_epointlist(p_epointlist);
130 /* we decrease the number of objects: */
131 p_m_mISDNport->use--;
132 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
139 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
141 /* init trace with given values */
142 start_trace(mISDNport?mISDNport->portnum:0,
143 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
144 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
145 port?port->p_dialinginfo.id:NULL,
148 port?port->p_serial:0,
156 static struct isdn_message {
160 {"TIMEOUT", CC_TIMEOUT},
162 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
163 {"PROCEEDING", CC_PROCEEDING},
164 {"ALERTING", CC_ALERTING},
165 {"CONNECT", CC_CONNECT},
166 {"CONNECT RES", CC_CONNECT},
167 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
168 {"DISCONNECT", CC_DISCONNECT},
169 {"RELEASE", CC_RELEASE},
170 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
171 {"INFORMATION", CC_INFORMATION},
172 {"PROGRESS", CC_PROGRESS},
173 {"NOTIFY", CC_NOTIFY},
174 {"SUSPEND", CC_SUSPEND},
175 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
176 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
177 {"RESUME", CC_RESUME},
178 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
179 {"RESUME_REJ", CC_RESUME_REJECT},
181 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
182 {"HOLD_REJ", CC_HOLD_REJECT},
183 {"RETRIEVE", CC_RETRIEVE},
184 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
185 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
186 {"FACILITY", CC_FACILITY},
187 {"STATUS", CC_STATUS},
188 {"RESTART", CC_RESTART},
189 {"RELEASE_CR", CC_RELEASE_CR},
190 {"NEW_CR", CC_NEW_CR},
191 {"DL_ESTABLISH", DL_ESTABLISH},
192 {"DL_RELEASE", DL_RELEASE},
193 {"PH_ACTIVATE", PH_ACTIVATE},
194 {"PH_DEACTIVATE", PH_DEACTIVATE},
198 static char *isdn_prim[4] = {
204 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
207 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
209 /* select message and primitive text */
211 while(isdn_message[i].name)
213 if (isdn_message[i].value == (prim&0xffffff00))
215 SCPY(msgtext, isdn_message[i].name);
220 SCAT(msgtext, isdn_prim[prim&0x00000003]);
223 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
227 if (mISDNport->ntmode)
229 if (direction == DIRECTION_OUT)
230 SCAT(msgtext, " N->U");
232 SCAT(msgtext, " N<-U");
235 if (direction == DIRECTION_OUT)
236 SCAT(msgtext, " U->N");
238 SCAT(msgtext, " U<-N");
243 /* init trace with given values */
244 start_trace(mISDNport?mISDNport->portnum:0,
245 mISDNport?mISDNport->ifport->interface:NULL,
246 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
247 port?port->p_dialinginfo.id:NULL,
250 port?port->p_serial:0,
256 * send control information to the channel (dsp-module)
258 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, int c2, char *trace_name, int trace_value)
260 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
261 iframe_t *ctrl = (iframe_t *)buffer;
262 unsigned long *d = (unsigned long *)&ctrl->data.p;
264 ctrl->prim = PH_CONTROL | REQUEST;
265 ctrl->addr = b_addr | FLG_MSG_DOWN;
267 ctrl->len = sizeof(int)*2;
270 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
271 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
272 if (c1 == CMX_CONF_JOIN)
273 add_trace(trace_name, NULL, "0x%08x", trace_value);
275 add_trace(trace_name, NULL, "%d", trace_value);
279 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)
281 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
282 iframe_t *ctrl = (iframe_t *)buffer;
283 unsigned long *d = (unsigned long *)&ctrl->data.p;
285 ctrl->prim = PH_CONTROL | REQUEST;
286 ctrl->addr = b_addr | FLG_MSG_DOWN;
288 ctrl->len = sizeof(int)+c2_len;
290 memcpy(d, c2, c2_len);
291 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
292 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
293 add_trace(trace_name, NULL, "%d", trace_value);
299 * subfunction for bchannel_event
302 static int _bchannel_create(struct mISDNport *mISDNport, int i)
304 unsigned char buff[1024];
309 if (!mISDNport->b_stid[i])
311 PERROR("Error: no stack for index %d\n", i);
314 if (mISDNport->b_addr[i])
316 PERROR("Error: stack already created for index %d\n", i);
320 /* create new layer */
321 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
322 memset(&li, 0, sizeof(li));
323 memset(&pid, 0, sizeof(pid));
326 li.st = mISDNport->b_stid[i];
327 UCPY(li.name, "B L4");
328 li.pid.layermask = ISDN_LAYER((4));
329 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
330 ret = mISDN_new_layer(mISDNdevice, &li);
334 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
337 mISDNport->b_addr[i] = li.id;
340 goto failed_new_layer;
342 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
344 /* create new stack */
345 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
346 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
347 pid.protocol[3] = ISDN_PID_L3_B_DSP;
348 pid.protocol[4] = ISDN_PID_L4_B_USER;
349 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
350 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
354 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
355 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
358 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
363 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
364 if (!mISDNport->b_addr[i])
366 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
367 add_trace("channel", NULL, "%d", i+1+(i>=15));
368 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
369 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
375 mISDNport->b_addr[i] = 0;
381 * subfunction for bchannel_event
384 static void _bchannel_activate(struct mISDNport *mISDNport, int i)
388 /* activate bchannel */
389 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL activate", DIRECTION_OUT);
390 add_trace("channel", NULL, "%d", i+1+(i>=15));
392 act.prim = DL_ESTABLISH | REQUEST;
393 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
396 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
401 * subfunction for bchannel_event
404 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
409 port = mISDNport->b_port[i];
410 addr = mISDNport->b_addr[i];
413 PERROR("bchannel index i=%d not associated with a port object\n", i);
417 /* set dsp features */
418 if (port->p_m_txdata)
419 ph_control(mISDNport, port, addr, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
421 ph_control(mISDNport, port, addr, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
423 ph_control(mISDNport, port, addr, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
425 ph_control(mISDNport, port, addr, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
427 ph_control(mISDNport, port, addr, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
429 ph_control(mISDNport, port, addr, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
431 ph_control(mISDNport, port, addr, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
433 ph_control(mISDNport, port, addr, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
434 // if (port->p_m_txmix)
435 // ph_control(mISDNport, port, addr, CMX_MIX_ON, 0, "DSP-MIX", 1);
437 ph_control(mISDNport, port, addr, DTMF_TONE_START, 0, "DSP-DTMF", 1);
439 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);
443 * subfunction for bchannel_event
446 static void _bchannel_deactivate(struct mISDNport *mISDNport, int i)
450 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL deactivate", DIRECTION_OUT);
451 add_trace("channel", NULL, "%d", i+1+(i>=15));
453 dact.prim = DL_RELEASE | REQUEST;
454 dact.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
457 mISDN_write(mISDNdevice, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC);
461 * subfunction for bchannel_event
464 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
466 unsigned char buff[1024];
468 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
469 add_trace("channel", NULL, "%d", i+1+(i>=15));
470 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
471 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
473 /* remove our stack only if set */
474 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
475 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
476 if (mISDNport->b_addr[i])
477 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
478 mISDNport->b_addr[i] = 0;
486 A bchannel goes through the following states in this order:
489 No one is using the bchannel.
490 It is available and not linked to Port class, nor reserved.
493 The bchannel stack is created and an activation request is sent.
494 It MAY be linked to Port class, but already unlinked due to Port class removal.
497 The bchannel is active and cofigured to the Port class needs.
498 Also it is linked to a Port class, otherwhise it would be deactivated.
500 - B_STATE_DEACTIVATING
501 The bchannel is in deactivating state, due to deactivation request.
502 It may be linked to a Port class, that likes to reactivate it.
506 After deactivating bchannel, and if not used, the bchannel becomes idle again.
509 A bchannel can have the following events:
512 A bchannel is required by a Port class.
515 The bchannel beomes active.
518 The bchannel is not required by Port class anymore
520 - B_EVENT_DEACTIVATED
521 The bchannel becomes inactive.
523 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
528 * process bchannel events
529 * - mISDNport is a pointer to the port's structure
530 * - i is the index of the bchannel
531 * - event is the B_EVENT_* value
532 * - port is the PmISDN class pointer
534 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
536 int state = mISDNport->b_state[i];
540 case B_EVENT_ACTIVATE:
541 /* port must be linked in order to allow activation */
542 if (!mISDNport->b_port[i])
543 FATAL("bchannel must be linked to a Port class\n");
547 /* create stack and send activation request */
548 if (_bchannel_create(mISDNport, i))
550 _bchannel_activate(mISDNport, i);
551 state = B_STATE_ACTIVATING;
555 case B_STATE_ACTIVATING:
556 /* do nothing, because it is already activating */
559 case B_STATE_DEACTIVATING:
560 /* do nothing, because we must wait until we can reactivate */
564 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
568 case B_EVENT_ACTIVATED:
571 case B_STATE_ACTIVATING:
572 if (mISDNport->b_port[i])
574 /* bchannel is active and used by Port class, so we configure bchannel */
575 _bchannel_configure(mISDNport, i);
576 state = B_STATE_ACTIVE;
579 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
580 _bchannel_deactivate(mISDNport, i);
581 state = B_STATE_DEACTIVATING;
586 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
590 case B_EVENT_DEACTIVATE:
591 if (!mISDNport->b_port[i])
592 FATAL("bchannel must be linked to a Port class\n");
596 /* bchannel is idle due to an error, so we do nothing */
599 case B_STATE_ACTIVATING:
600 /* do nothing because we must wait until bchanenl is active before deactivating */
604 /* bchannel is active, so we deactivate */
605 _bchannel_deactivate(mISDNport, i);
606 state = B_STATE_DEACTIVATING;
609 case B_STATE_DEACTIVATING:
610 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
614 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
618 case B_EVENT_DEACTIVATED:
622 /* ignore due to deactivation confirm after unloading */
625 case B_STATE_DEACTIVATING:
626 _bchannel_destroy(mISDNport, i);
627 state = B_STATE_IDLE;
628 if (mISDNport->b_port[i])
630 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
631 if (_bchannel_create(mISDNport, i))
633 _bchannel_activate(mISDNport, i);
634 state = B_STATE_ACTIVATING;
640 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
645 PERROR("Illegal event %d, please correct.\n", event);
648 mISDNport->b_state[i] = state;
655 * check for available channel and reserve+set it.
656 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
658 * returns -(cause value) or x = channel x or 0 = no channel
659 * NOTE: no activation is done here
661 int PmISDN::seize_bchannel(int channel, int exclusive)
665 /* the channel is what we have */
666 if (p_m_b_channel == channel)
669 /* if channel already in use, release it */
674 if (channel==CHANNEL_NO || channel==0)
677 /* is channel in range ? */
679 || (channel>p_m_mISDNport->b_num && channel<16)
680 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
681 return(-6); /* channel unacceptable */
683 /* request exclusive channel */
684 if (exclusive && channel>0)
686 i = channel-1-(channel>16);
687 if (p_m_mISDNport->b_port[i])
688 return(-44); /* requested channel not available */
692 /* ask for channel */
695 i = channel-1-(channel>16);
696 if (p_m_mISDNport->b_port[i] == NULL)
700 /* search for channel */
702 while(i < p_m_mISDNport->b_num)
704 if (!p_m_mISDNport->b_port[i])
706 channel = i+1+(i>=15);
711 return(-34); /* no free channel */
714 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
717 p_m_mISDNport->b_port[i] = this;
719 p_m_b_channel = channel;
720 p_m_b_exclusive = exclusive;
722 /* reserve channel */
726 p_m_mISDNport->b_reserved++;
733 * drop reserved channel and unset it.
734 * deactivation is also done
736 void PmISDN::drop_bchannel(void)
741 /* unreserve channel */
743 p_m_mISDNport->b_reserved--;
750 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
752 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
753 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DEACTIVATE);
754 p_m_mISDNport->b_port[p_m_b_index] = NULL;
764 audio transmission procedure:
765 -----------------------------
768 three sources of audio transmission:
769 - crypto-data high priority
770 - tones high priority (also high)
771 - remote-data low priority
774 a variable that temporarily shows the number of samples elapsed since last transmission process.
775 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
778 a variable that is increased whenever data is transmitted.
779 it is decreased while time elapses. it stores the number of samples that
780 are currently loaded to dsp module.
781 since clock in dsp module is the same clock for user space process, these
785 there are two levels:
786 ISDN_LOAD will give the load that have to be kept in dsp.
787 ISDN_MAXLOAD will give the maximum load before dropping.
789 * procedure for low priority data
790 see txfromup() for procedure
791 in short: remote data is ignored during high priority tones
793 * procedure for high priority data
794 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
795 if no more data is available, load becomes empty again.
798 0 ISDN_LOAD ISDN_MAXLOAD
799 +--------------------+----------------------+
801 +--------------------+----------------------+
803 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
804 0 ISDN_LOAD ISDN_MAXLOAD
805 +--------------------+----------------------+
806 |TTTTTTTTTTTTTTTTTTTT| |
807 +--------------------+----------------------+
809 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
810 0 ISDN_LOAD ISDN_MAXLOAD
811 +--------------------+----------------------+
812 |TTTTTTTTTTTTTTTTTTTTRRRRR |
813 +--------------------+----------------------+
816 int PmISDN::handler(void)
818 struct message *message;
822 if ((ret = Port::handler()))
828 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
829 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
832 /* set clock of first process ever in this instance */
833 p_m_last_tv_sec = now_tv.tv_sec;
834 p_m_last_tv_msec = now_tv.tv_usec/1000;
836 /* process only if we have a minimum of samples, to make packets not too small */
837 if (elapsed >= ISDN_TRANSMIT)
839 /* set clock of last process! */
840 p_m_last_tv_sec = now_tv.tv_sec;
841 p_m_last_tv_msec = now_tv.tv_usec/1000;
844 if (elapsed < p_m_load)
849 /* to send data, tone must be active OR crypt messages must be on */
850 if ((p_tone_name[0] || p_m_crypt_msg_loops) && p_m_load < ISDN_LOAD)
852 int tosend = ISDN_LOAD - p_m_load, length;
853 unsigned char buf[mISDN_HEADER_LEN+tosend];
854 iframe_t *frm = (iframe_t *)buf;
855 unsigned char *p = buf+mISDN_HEADER_LEN;
857 /* copy crypto loops */
858 while (p_m_crypt_msg_loops && tosend)
860 /* how much do we have to send */
861 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
867 /* copy message (part) to buffer */
868 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
871 p_m_crypt_msg_current += length;
872 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
875 p_m_crypt_msg_current = 0;
876 p_m_crypt_msg_loops--;
884 if (p_tone_name[0] && tosend)
886 tosend -= read_audio(p, tosend);
890 frm->prim = DL_DATA | REQUEST;
891 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
893 frm->len = ISDN_LOAD - p_m_load - tosend;
895 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
896 p_m_load += frm->len;
900 // NOTE: deletion is done by the child class
902 /* handle timeouts */
905 if (p_m_timer+p_m_timeout < now_d)
907 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
909 /* send timeout to endpoint */
910 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
911 message->param.state = p_state;
912 message_put(message);
917 return(0); /* nothing done */
922 * whenever we get audio data from bchannel, we process it here
924 void PmISDN::bchannel_receive(iframe_t *frm)
926 unsigned char *data_temp;
927 unsigned long length_temp;
928 struct message *message;
933 if (frm->prim == (PH_CONTROL | INDICATION))
937 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
940 cont = *((unsigned long *)&frm->data.p);
941 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
943 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
944 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
946 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
947 message->param.dtmf = cont & DTMF_TONE_MASK;
948 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
949 message_put(message);
955 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
956 add_trace("DSP-CRYPT", NULL, "error");
958 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
959 message->param.crypt.type = CC_ERROR_IND;
960 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
961 message_put(message);
965 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
966 add_trace("DSP-CRYPT", NULL, "ok");
968 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
969 message->param.crypt.type = CC_ACTBF_CONF;
970 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
971 message_put(message);
977 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
978 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
982 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
986 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
987 add_trace("unknown", NULL, "0x%x", cont);
992 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
994 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
998 /* calls will not process any audio data unless
999 * the call is connected OR interface features audio during call setup.
1001 //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);
1002 #ifndef DEBUG_COREBRIDGE
1003 if (p_state!=PORT_STATE_CONNECT
1004 && !p_m_mISDNport->earlyb)
1008 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1011 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1017 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1019 /* randomize and listen to crypt message if enabled */
1020 if (p_m_crypt_listen)
1022 /* the noisy randomizer */
1023 p = (unsigned char *)&frm->data.p;
1026 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1028 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1031 p = (unsigned char *)&frm->data.p;
1033 /* send data to epoint */
1034 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1036 length_temp = frm->len;
1040 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1041 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1042 memcpy(message->param.data.data, data_temp, message->param.data.len);
1043 message_put(message);
1044 if (length_temp <= sizeof(message->param.data.data))
1046 data_temp += sizeof(message->param.data.data);
1047 length_temp -= sizeof(message->param.data.data);
1056 void PmISDN::set_echotest(int echo)
1058 if (p_m_echo != echo)
1061 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1063 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1064 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);
1071 void PmISDN::set_tone(char *dir, char *tone)
1077 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1084 /* check if we NOT really have to use a dsp-tone */
1085 if (!options.dsptones)
1089 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1091 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1092 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1095 Port::set_tone(dir, tone);
1101 /* now we USE dsp-tone, convert name */
1102 else if (!strcmp(tone, "dialtone"))
1104 switch(options.dsptones) {
1105 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1106 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1107 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1109 } else if (!strcmp(tone, "dialpbx"))
1111 switch(options.dsptones) {
1112 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1113 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1114 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1116 } else if (!strcmp(tone, "ringing"))
1118 switch(options.dsptones) {
1119 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1120 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1121 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1123 } else if (!strcmp(tone, "ringpbx"))
1125 switch(options.dsptones) {
1126 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1127 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1128 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1130 } else if (!strcmp(tone, "busy"))
1133 switch(options.dsptones) {
1134 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1135 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1136 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1138 } else if (!strcmp(tone, "release"))
1141 switch(options.dsptones) {
1142 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1143 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1144 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1146 } else if (!strcmp(tone, "cause_10"))
1148 else if (!strcmp(tone, "cause_11"))
1150 else if (!strcmp(tone, "cause_22"))
1152 switch(options.dsptones) {
1153 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1154 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1155 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1157 } else if (!strncmp(tone, "cause_", 6))
1158 id = TONE_SPECIAL_INFO;
1162 /* if we have a tone that is not supported by dsp */
1163 if (id==TONE_OFF && tone[0])
1171 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1173 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1174 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);
1176 /* turn user-space tones off in cases of no tone OR dsp tone */
1177 Port::set_tone("",NULL);
1181 /* MESSAGE_mISDNSIGNAL */
1182 //extern struct message *dddebug;
1183 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1185 switch(param->mISDNsignal.message)
1187 case mISDNSIGNAL_VOLUME:
1188 if (p_m_txvol != param->mISDNsignal.txvol)
1190 p_m_txvol = param->mISDNsignal.txvol;
1191 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1193 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1194 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);
1196 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1197 if (p_m_rxvol != param->mISDNsignal.rxvol)
1199 p_m_rxvol = param->mISDNsignal.rxvol;
1200 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1202 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1203 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);
1205 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1208 case mISDNSIGNAL_CONF:
1209 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1210 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1211 if (p_m_conf != param->mISDNsignal.conf)
1213 p_m_conf = param->mISDNsignal.conf;
1214 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1216 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1217 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);
1219 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1220 /* we must set, even if currently tone forbids conf */
1221 p_m_conf = param->mISDNsignal.conf;
1222 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1225 case mISDNSIGNAL_JOINDATA:
1226 if (p_m_joindata != param->mISDNsignal.joindata)
1228 p_m_joindata = param->mISDNsignal.joindata;
1229 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1231 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1234 case mISDNSIGNAL_DELAY:
1235 if (p_m_delay != param->mISDNsignal.delay)
1237 p_m_delay = param->mISDNsignal.delay;
1238 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1240 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1241 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);
1243 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1247 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1252 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1254 struct message *message;
1256 switch(param->crypt.type)
1258 case CC_ACTBF_REQ: /* activate blowfish */
1260 p_m_crypt_key_len = param->crypt.len;
1261 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1263 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1264 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1265 message->param.crypt.type = CC_ERROR_IND;
1266 message_put(message);
1269 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1271 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1273 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1274 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);
1277 case CC_DACT_REQ: /* deactivate session encryption */
1282 case CR_LISTEN_REQ: /* start listening to messages */
1283 p_m_crypt_listen = 1;
1284 p_m_crypt_listen_state = 0;
1287 case CR_UNLISTEN_REQ: /* stop listening to messages */
1288 p_m_crypt_listen = 0;
1291 case CR_MESSAGE_REQ: /* send message */
1292 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1293 if (!p_m_crypt_msg_len)
1295 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1298 p_m_crypt_msg_current = 0; /* reset */
1299 p_m_crypt_msg_loops = 3; /* enable */
1301 /* disable txmix, or we get corrupt data due to audio process */
1304 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1305 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1311 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1317 * endpoint sends messages to the port
1319 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1321 if (Port::message_epoint(epoint_id, message_id, param))
1326 case MESSAGE_DATA: /* tx-data from upper layer */
1327 txfromup(param->data.data, param->data.len);
1330 case MESSAGE_mISDNSIGNAL: /* user command */
1331 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1332 message_mISDNsignal(epoint_id, message_id, param);
1335 case MESSAGE_CRYPT: /* crypt control command */
1336 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1337 message_crypt(epoint_id, message_id, param);
1346 * main loop for processing messages from mISDN device
1348 int mISDN_handler(void)
1353 struct mISDNport *mISDNport;
1354 class PmISDN *isdnport;
1357 mISDNuser_head_t *hh;
1360 /* the que avoids loopbacks when replying to stack after receiving
1362 mISDNport = mISDNport_first;
1365 /* process turning on/off rx */
1367 while(i < mISDNport->b_num)
1369 isdnport=mISDNport->b_port[i];
1372 /* call bridges in user space OR crypto OR recording */
1373 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1375 /* rx IS required */
1376 if (isdnport->p_m_rxoff)
1379 isdnport->p_m_rxoff = 0;
1380 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1381 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1382 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1387 /* rx NOT required */
1388 if (!isdnport->p_m_rxoff)
1391 isdnport->p_m_rxoff = 1;
1392 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1393 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1394 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1399 if (isdnport->p_record)
1401 /* txdata IS required */
1402 if (!isdnport->p_m_txdata)
1405 isdnport->p_m_txdata = 1;
1406 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1407 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1408 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1413 /* txdata NOT required */
1414 if (isdnport->p_m_txdata)
1417 isdnport->p_m_txdata = 0;
1418 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1419 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1420 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1428 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1430 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1431 mISDNport->l1timeout = 0;
1434 if (mISDNport->l2establish)
1436 if (now-mISDNport->l2establish > 5)
1438 if (mISDNport->ntmode)
1440 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1441 time(&mISDNport->l2establish);
1443 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1444 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1447 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1448 time(&mISDNport->l2establish);
1451 act.prim = DL_ESTABLISH | REQUEST;
1452 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1455 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1457 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1462 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1464 if (mISDNport->ntmode)
1466 hh = (mISDNuser_head_t *)dmsg->data;
1467 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);
1468 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1472 frm = (iframe_t *)dmsg->data;
1473 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1474 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1475 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);
1476 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1481 mISDNport = mISDNport->next;
1484 /* no device, no read */
1485 if (mISDNdevice < 0)
1488 /* get message from kernel */
1489 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1491 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1495 if (errno == EAGAIN)
1497 FATAL("Failed to do mISDN_read()\n");
1502 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1506 frm = (iframe_t *)msg->data;
1511 case MGR_DELLAYER | CONFIRM:
1512 case MGR_INITTIMER | CONFIRM:
1513 case MGR_ADDTIMER | CONFIRM:
1514 case MGR_DELTIMER | CONFIRM:
1515 case MGR_REMOVETIMER | CONFIRM:
1520 /* handle timer events from mISDN for NT-stack
1521 * note: they do not associate with a stack */
1522 if (frm->prim == (MGR_TIMER | INDICATION))
1526 /* find mISDNport */
1527 mISDNport = mISDNport_first;
1531 if (mISDNport->ntmode)
1533 it = mISDNport->nst.tlist;
1537 if (it->id == (int)frm->addr)
1544 mISDNport = mISDNport->next;
1548 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1549 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1551 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
1552 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1553 ret = it->function(it->data);
1556 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
1561 /* find the mISDNport that belongs to the stack */
1562 mISDNport = mISDNport_first;
1565 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
1567 mISDNport = mISDNport->next;
1571 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1576 if (!(frm->addr&FLG_CHILD_STACK))
1581 case MGR_SHORTSTATUS | INDICATION:
1582 case MGR_SHORTSTATUS | CONFIRM:
1583 switch(frm->dinfo) {
1584 case SSTATUS_L1_ACTIVATED:
1585 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1588 case SSTATUS_L1_DEACTIVATED:
1589 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1592 case SSTATUS_L2_ESTABLISHED:
1593 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1596 case SSTATUS_L2_RELEASED:
1597 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1603 case PH_ACTIVATE | CONFIRM:
1604 case PH_ACTIVATE | INDICATION:
1605 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1607 if (mISDNport->ntmode)
1609 mISDNport->l1link = 1;
1610 setup_queue(mISDNport, 1);
1614 mISDNport->l1link = 1;
1615 setup_queue(mISDNport, 1);
1618 case PH_DEACTIVATE | CONFIRM:
1619 case PH_DEACTIVATE | INDICATION:
1620 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1622 if (mISDNport->ntmode)
1624 mISDNport->l1link = 0;
1625 setup_queue(mISDNport, 0);
1629 mISDNport->l1link = 0;
1630 setup_queue(mISDNport, 0);
1633 case PH_CONTROL | CONFIRM:
1634 case PH_CONTROL | INDICATION:
1635 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1638 case DL_ESTABLISH | INDICATION:
1639 case DL_ESTABLISH | CONFIRM:
1640 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1642 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1644 if (mISDNport->l2establish)
1646 mISDNport->l2establish = 0;
1647 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1649 mISDNport->l2link = 1;
1652 case DL_RELEASE | INDICATION:
1653 case DL_RELEASE | CONFIRM:
1654 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1656 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1658 mISDNport->l2link = 0;
1661 time(&mISDNport->l2establish);
1662 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
1668 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);
1669 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
1671 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
1674 if (mISDNport->ntmode)
1676 /* l1-data enters the nt-mode library */
1677 nst = &mISDNport->nst;
1678 if (nst->l1_l2(nst, msg))
1683 /* l3-data is sent to pbx */
1684 if (stack2manager_te(mISDNport, msg))
1695 /* we don't care about confirms, we use rx data to sync tx */
1696 case PH_DATA | CONFIRM:
1697 case DL_DATA | CONFIRM:
1700 /* we receive audio data, we respond to it AND we send tones */
1701 case PH_DATA | INDICATION:
1702 case DL_DATA | INDICATION:
1703 case PH_CONTROL | INDICATION:
1705 while(i < mISDNport->b_num)
1707 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1711 if (i == mISDNport->b_num)
1713 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1716 if (mISDNport->b_port[i])
1718 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
1719 mISDNport->b_port[i]->bchannel_receive(frm);
1721 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
1724 case PH_ACTIVATE | INDICATION:
1725 case DL_ESTABLISH | INDICATION:
1726 case PH_ACTIVATE | CONFIRM:
1727 case DL_ESTABLISH | CONFIRM:
1728 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
1730 while(i < mISDNport->b_num)
1732 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1736 if (i == mISDNport->b_num)
1738 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1741 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1744 case PH_DEACTIVATE | INDICATION:
1745 case DL_RELEASE | INDICATION:
1746 case PH_DEACTIVATE | CONFIRM:
1747 case DL_RELEASE | CONFIRM:
1748 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
1750 while(i < mISDNport->b_num)
1752 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1756 if (i == mISDNport->b_num)
1758 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1761 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1765 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1776 * global function to add a new card (port)
1778 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
1781 unsigned char buff[1025];
1782 iframe_t *frm = (iframe_t *)buff;
1783 stack_info_t *stinf;
1784 struct mISDNport *mISDNport, **mISDNportp;
1786 // interface_info_t ii;
1793 /* open mISDNdevice if not already open */
1794 if (mISDNdevice < 0)
1799 PERROR("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));
1803 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
1805 /* create entity for layer 3 TE-mode */
1806 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1807 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
1808 if (ret < (int)mISDN_HEADER_LEN)
1811 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
1813 entity = frm->dinfo & 0xffff;
1816 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
1819 /* query port's requirements */
1820 cnt = mISDN_get_stack_count(mISDNdevice);
1823 PERROR("Found no card. Please be sure to load card drivers.\n");
1826 if (port>cnt || port<1)
1828 PERROR("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
1831 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
1834 PERROR("Cannot get stack info for port %d (ret=%d)\n", port, ret);
1837 stinf = (stack_info_t *)&frm->data.p;
1838 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
1840 case ISDN_PID_L0_TE_S0:
1841 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
1843 case ISDN_PID_L0_NT_S0:
1844 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
1847 case ISDN_PID_L0_TE_E1:
1848 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
1851 case ISDN_PID_L0_NT_E1:
1852 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
1857 PERROR("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
1863 if (stinf->pid.protocol[1] == 0)
1865 PERROR("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
1868 if (stinf->pid.protocol[2])
1870 PERROR("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
1876 if (stinf->pid.protocol[1] == 0)
1878 PERROR("Given port %d: Missing layer 1 protocol.\n", port);
1881 if (stinf->pid.protocol[2] == 0)
1883 PERROR("Given port %d: Missing layer 2 protocol.\n", port);
1886 if (stinf->pid.protocol[3] == 0)
1888 PERROR("Given port %d: Missing layer 3 protocol.\n", port);
1892 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
1894 case ISDN_PID_L3_DSS1USER:
1898 PERROR("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
1902 if (stinf->pid.protocol[4])
1904 PERROR("Given port %d: Layer 4 protocol not allowed.\n", port);
1909 /* add mISDNport structure */
1910 mISDNportp = &mISDNport_first;
1912 mISDNportp = &((*mISDNportp)->next);
1913 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
1915 *mISDNportp = mISDNport;
1917 /* allocate ressources of port */
1918 msg_queue_init(&mISDNport->downqueue);
1919 // SCPY(mISDNport->name, "noname");
1920 mISDNport->portnum = port;
1921 mISDNport->ntmode = nt;
1922 mISDNport->pri = pri;
1923 mISDNport->d_stid = stinf->id;
1924 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
1925 mISDNport->b_num = stinf->childcnt;
1926 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
1927 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
1929 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
1930 mISDNport->ptp = ptp = 1;
1933 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
1934 mISDNport->ptp = ptp = 0;
1938 while(i < stinf->childcnt)
1940 mISDNport->b_stid[i] = stinf->child[i];
1941 mISDNport->b_state[i] = B_STATE_IDLE;
1942 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
1945 memset(&li, 0, sizeof(li));
1946 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
1949 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1950 li.pid.layermask = ISDN_LAYER((nt?2:4));
1951 li.st = mISDNport->d_stid;
1952 ret = mISDN_new_layer(mISDNdevice, &li);
1955 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
1957 mISDNport_close(mISDNport);
1960 mISDNport->upper_id = li.id;
1961 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
1964 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
1967 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
1968 if (mISDNport->lower_id < 0)
1970 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
1973 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
1974 if (mISDNport->upper_id < 0)
1976 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
1979 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
1981 /* if ntmode, establish L1 to send the tei removal during start */
1982 if (mISDNport->ntmode)
1986 act.prim = PH_ACTIVATE | REQUEST;
1987 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
1988 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
1991 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1992 usleep(10000); /* to be sure, that l1 is up */
1995 /* create nst (nt-mode only) */
1998 mgr = &mISDNport->mgr;
1999 nst = &mISDNport->nst;
2004 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2005 nst->device = mISDNdevice;
2007 nst->d_stid = mISDNport->d_stid;
2009 nst->feature = FEATURE_NET_HOLD;
2011 nst->feature |= FEATURE_NET_PTP;
2013 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2016 while(i < mISDNport->b_num)
2018 nst->b_stid[i] = mISDNport->b_stid[i];
2022 nst->l1_id = mISDNport->lower_id;
2023 nst->l2_id = mISDNport->upper_id;
2026 msg_queue_init(&nst->down_queue);
2032 /* if te-mode, query state link */
2033 if (!mISDNport->ntmode)
2037 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2038 act.prim = MGR_SHORTSTATUS | REQUEST;
2039 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2040 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2042 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2044 /* if ptp AND te-mode, pull up the link */
2045 if (mISDNport->ptp && !mISDNport->ntmode)
2049 act.prim = DL_ESTABLISH | REQUEST;
2050 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2053 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2055 /* if ptp AND nt-mode, pull up the link */
2056 if (mISDNport->ptp && mISDNport->ntmode)
2060 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2061 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2064 /* initially, we assume that the link is down, exept for nt-ptmp */
2065 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2067 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2069 start_trace(mISDNport->portnum,
2077 add_trace("channels", NULL, "%d", mISDNport->b_num);
2084 * function to free ALL cards (ports)
2086 void mISDNport_close_all(void)
2088 /* free all ports */
2089 while(mISDNport_first)
2090 mISDNport_close(mISDNport_first);
2094 * free only one port
2096 void mISDNport_close(struct mISDNport *mISDNport)
2098 struct mISDNport **mISDNportp;
2100 class PmISDN *isdnport;
2102 unsigned char buf[32];
2105 /* remove all port instance that are linked to this mISDNport */
2109 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2111 isdnport = (class PmISDN *)port;
2112 if (isdnport->p_m_mISDNport)
2114 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2121 /* only if we are already part of interface */
2122 if (mISDNport->ifport)
2124 start_trace(mISDNport->portnum,
2125 mISDNport->ifport->interface,
2135 /* free bchannels */
2137 while(i < mISDNport->b_num)
2139 if (mISDNport->b_addr[i])
2141 _bchannel_destroy(mISDNport, i);
2142 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2147 /* free ressources of port */
2148 msg_queue_purge(&mISDNport->downqueue);
2151 if (mISDNport->ntmode)
2153 nst = &mISDNport->nst;
2154 if (nst->manager) /* to see if initialized */
2156 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");
2157 cleanup_Isdnl3(nst);
2158 cleanup_Isdnl2(nst);
2161 msg_queue_purge(&nst->down_queue);
2162 if (nst->phd_down_msg)
2163 FREE(nst->phd_down_msg, 0);
2167 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2168 if (mISDNport->d_stid)
2170 if (mISDNport->upper_id)
2171 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2174 /* remove from list */
2175 mISDNportp = &mISDNport_first;
2178 if (*mISDNportp == mISDNport)
2180 *mISDNportp = (*mISDNportp)->next;
2184 mISDNportp = &((*mISDNportp)->next);
2188 FATAL("mISDNport not in list\n");
2190 FREE(mISDNport, sizeof(struct mISDNport));
2193 /* close mISDNdevice, if no port */
2194 if (mISDNdevice>=0 && mISDNport_first==NULL)
2197 mISDN_write_frame(mISDNdevice, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2199 mISDN_close(mISDNdevice);
2201 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
2207 * global function to show all available isdn ports
2209 void mISDN_port_info(void)
2213 int useable, nt, pri;
2214 unsigned char buff[1025];
2215 iframe_t *frm = (iframe_t *)buff;
2216 stack_info_t *stinf;
2220 if ((device = mISDN_open()) < 0)
2222 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));
2226 /* get number of stacks */
2228 ii = mISDN_get_stack_count(device);
2232 printf("Found no card. Please be sure to load card drivers.\n");
2235 /* loop the number of cards and get their info */
2238 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2241 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2244 stinf = (stack_info_t *)&frm->data.p;
2249 /* output the port info */
2250 printf("Port %2d: ", i);
2251 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2253 case ISDN_PID_L0_TE_S0:
2254 printf("TE-mode BRI S/T interface line (for phone lines)");
2256 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2257 printf(" HFC multiport card");
2260 case ISDN_PID_L0_NT_S0:
2262 printf("NT-mode BRI S/T interface port (for phones)");
2264 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2265 printf(" HFC multiport card");
2268 case ISDN_PID_L0_TE_E1:
2270 printf("TE-mode PRI E1 interface line (for phone lines)");
2272 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2273 printf(" HFC-E1 card");
2276 case ISDN_PID_L0_NT_E1:
2279 printf("NT-mode PRI E1 interface port (for phones)");
2281 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2282 printf(" HFC-E1 card");
2287 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2293 if (stinf->pid.protocol[1] == 0)
2296 printf(" -> Missing layer 1 NT-mode protocol.\n");
2299 while(p <= MAX_LAYER_NR) {
2300 if (stinf->pid.protocol[p])
2303 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
2310 printf(" -> Interface is Point-To-Point (PRI).\n");
2312 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2316 if (stinf->pid.protocol[1] == 0)
2319 printf(" -> Missing layer 1 protocol.\n");
2321 if (stinf->pid.protocol[2] == 0)
2324 printf(" -> Missing layer 2 protocol.\n");
2326 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2328 printf(" -> Interface is Poin-To-Point.\n");
2330 if (stinf->pid.protocol[3] == 0)
2333 printf(" -> Missing layer 3 protocol.\n");
2336 printf(" -> Protocol: ");
2337 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2339 case ISDN_PID_L3_DSS1USER:
2340 printf("DSS1 (Euro ISDN)");
2345 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2350 while(p <= MAX_LAYER_NR) {
2351 if (stinf->pid.protocol[p])
2354 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
2359 printf(" - %d B-channels\n", stinf->childcnt);
2362 printf(" * Port NOT useable for PBX\n");
2364 printf("--------\n");
2371 if ((err = mISDN_close(device)))
2372 FATAL("mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2377 * enque data from upper buffer
2379 void PmISDN::txfromup(unsigned char *data, int length)
2381 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2382 iframe_t *frm = (iframe_t *)buf;
2384 /* configure frame */
2385 frm->prim = DL_DATA | REQUEST;
2386 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
2389 /* check if high priority tones exist
2390 * ignore data in this case
2392 if (p_tone_name[0] || p_m_crypt_msg_loops)
2395 /* preload procedure
2396 * if transmit buffer in DSP module is empty,
2397 * preload it to DSP_LOAD to prevent jitter gaps.
2399 if (p_m_load==0 && ISDN_LOAD>0)
2402 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
2403 frm->len = ISDN_LOAD;
2404 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2405 p_m_load += frm->len;
2408 /* drop if load would exceed ISDN_MAXLOAD
2409 * this keeps the delay not too high
2411 if (p_m_load+length > ISDN_MAXLOAD)
2414 /* load data to buffer
2416 memcpy(buf+mISDN_HEADER_LEN, data, length);
2418 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2419 p_m_load += frm->len;