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;
59 p_m_txvol = p_m_rxvol = 0;
67 p_m_dtmf = !mISDNport->ifport->nodtmf;
72 p_m_fromup_buffer_readp = 0;
73 p_m_fromup_buffer_writep = 0;
78 p_m_crypt_msg_loops = 0;
79 p_m_crypt_msg_loops = 0;
80 p_m_crypt_msg_len = 0;
81 p_m_crypt_msg[0] = '\0';
82 p_m_crypt_msg_current = 0;
83 p_m_crypt_key[0] = '\0';
84 p_m_crypt_key_len = 0;
86 p_m_crypt_listen_state = 0;
87 p_m_crypt_listen_len = 0;
88 p_m_crypt_listen_msg[0] = '\0';
89 p_m_crypt_listen_crc = 0;
91 /* if any channel requested by constructor */
92 if (channel == CHANNEL_ANY)
96 mISDNport->b_reserved++;
100 if (channel > 0) // only if constructor was called with a channel resevation
101 seize_bchannel(channel, exclusive);
103 /* we increase the number of objects: */
105 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
114 struct message *message;
116 /* remove bchannel relation */
122 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
123 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
124 message->param.disconnectinfo.cause = 16;
125 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
126 message_put(message);
127 /* remove from list */
128 free_epointlist(p_epointlist);
131 /* we decrease the number of objects: */
132 p_m_mISDNport->use--;
133 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
140 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
142 /* init trace with given values */
143 start_trace(mISDNport?mISDNport->portnum:0,
144 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
145 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
146 port?port->p_dialinginfo.id:NULL,
149 port?port->p_serial:0,
157 static struct isdn_message {
161 {"TIMEOUT", CC_TIMEOUT},
163 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
164 {"PROCEEDING", CC_PROCEEDING},
165 {"ALERTING", CC_ALERTING},
166 {"CONNECT", CC_CONNECT},
167 {"CONNECT RES", CC_CONNECT},
168 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
169 {"DISCONNECT", CC_DISCONNECT},
170 {"RELEASE", CC_RELEASE},
171 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
172 {"INFORMATION", CC_INFORMATION},
173 {"PROGRESS", CC_PROGRESS},
174 {"NOTIFY", CC_NOTIFY},
175 {"SUSPEND", CC_SUSPEND},
176 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
177 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
178 {"RESUME", CC_RESUME},
179 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
180 {"RESUME_REJ", CC_RESUME_REJECT},
182 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
183 {"HOLD_REJ", CC_HOLD_REJECT},
184 {"RETRIEVE", CC_RETRIEVE},
185 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
186 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
187 {"FACILITY", CC_FACILITY},
188 {"STATUS", CC_STATUS},
189 {"RESTART", CC_RESTART},
190 {"RELEASE_CR", CC_RELEASE_CR},
191 {"NEW_CR", CC_NEW_CR},
192 {"DL_ESTABLISH", DL_ESTABLISH},
193 {"DL_RELEASE", DL_RELEASE},
194 {"PH_ACTIVATE", PH_ACTIVATE},
195 {"PH_DEACTIVATE", PH_DEACTIVATE},
199 static char *isdn_prim[4] = {
205 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
208 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
210 /* select message and primitive text */
212 while(isdn_message[i].name)
214 if (isdn_message[i].value == (prim&0xffffff00))
216 SCPY(msgtext, isdn_message[i].name);
221 SCAT(msgtext, isdn_prim[prim&0x00000003]);
224 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
228 if (mISDNport->ntmode)
230 if (direction == DIRECTION_OUT)
231 SCAT(msgtext, " N->U");
233 SCAT(msgtext, " N<-U");
236 if (direction == DIRECTION_OUT)
237 SCAT(msgtext, " U->N");
239 SCAT(msgtext, " U<-N");
244 /* init trace with given values */
245 start_trace(mISDNport?mISDNport->portnum:0,
246 mISDNport?mISDNport->ifport->interface:NULL,
247 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
248 port?port->p_dialinginfo.id:NULL,
251 port?port->p_serial:0,
257 * send control information to the channel (dsp-module)
259 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, int c2, char *trace_name, int trace_value)
261 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
262 iframe_t *ctrl = (iframe_t *)buffer;
263 unsigned long *d = (unsigned long *)&ctrl->data.p;
265 ctrl->prim = PH_CONTROL | REQUEST;
266 ctrl->addr = b_addr | FLG_MSG_DOWN;
268 ctrl->len = sizeof(int)*2;
271 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
272 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
273 add_trace(trace_name, NULL, "%d", trace_value);
277 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)
279 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
280 iframe_t *ctrl = (iframe_t *)buffer;
281 unsigned long *d = (unsigned long *)&ctrl->data.p;
283 ctrl->prim = PH_CONTROL | REQUEST;
284 ctrl->addr = b_addr | FLG_MSG_DOWN;
286 ctrl->len = sizeof(int)+c2_len;
288 memcpy(d, c2, c2_len);
289 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
290 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
291 add_trace(trace_name, NULL, "%d", trace_value);
297 * subfunction for bchannel_event
300 static int _bchannel_create(struct mISDNport *mISDNport, int i)
302 unsigned char buff[1024];
307 if (!mISDNport->b_stid[i])
309 PERROR("Error: no stack for index %d\n", i);
312 if (mISDNport->b_addr[i])
314 PERROR("Error: stack already created for index %d\n", i);
318 /* create new layer */
319 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
320 memset(&li, 0, sizeof(li));
321 memset(&pid, 0, sizeof(pid));
324 li.st = mISDNport->b_stid[i];
325 UCPY(li.name, "B L4");
326 li.pid.layermask = ISDN_LAYER((4));
327 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
328 ret = mISDN_new_layer(mISDNdevice, &li);
332 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
335 mISDNport->b_addr[i] = li.id;
338 goto failed_new_layer;
340 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
342 /* create new stack */
343 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
344 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
345 pid.protocol[3] = ISDN_PID_L3_B_DSP;
346 pid.protocol[4] = ISDN_PID_L4_B_USER;
347 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
348 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
352 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
353 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
356 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
361 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
362 if (!mISDNport->b_addr[i])
364 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
365 add_trace("channel", NULL, "%d", i+1+(i>=15));
366 add_trace("stack", "id", "0x%8x", mISDNport->b_stid[i]);
367 add_trace("stack", "address", "0x%8x", mISDNport->b_addr[i]);
373 mISDNport->b_addr[i] = 0;
379 * subfunction for bchannel_event
382 static void _bchannel_activate(struct mISDNport *mISDNport, int i)
386 /* activate bchannel */
387 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL activate", DIRECTION_OUT);
388 add_trace("channel", NULL, "%d", i+1+(i>=15));
390 act.prim = DL_ESTABLISH | REQUEST;
391 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
394 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
399 * subfunction for bchannel_event
402 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
407 port = mISDNport->b_port[i];
408 addr = mISDNport->b_addr[i];
411 PERROR("bchannel index i=%d not associated with a port object\n", i);
415 /* set dsp features */
416 if (port->p_m_txdata)
417 ph_control(mISDNport, port, addr, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
419 ph_control(mISDNport, port, addr, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
421 ph_control(mISDNport, port, addr, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
423 ph_control(mISDNport, port, addr, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
425 ph_control(mISDNport, port, addr, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
427 ph_control(mISDNport, port, addr, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
429 ph_control(mISDNport, port, addr, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
431 ph_control(mISDNport, port, addr, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
432 // if (port->p_m_txmix)
433 // ph_control(mISDNport, port, addr, CMX_MIX_ON, 0, "DSP-MIX", 1);
435 ph_control(mISDNport, port, addr, DTMF_TONE_START, 0, "DSP-DTMF", 1);
437 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);
441 * subfunction for bchannel_event
444 static void _bchannel_deactivate(struct mISDNport *mISDNport, int i)
449 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL deactivate", DIRECTION_OUT);
450 add_trace("channel", NULL, "%d", i+1+(i>=15));
452 dact.prim = DL_RELEASE | REQUEST;
453 dact.addr = addr | FLG_MSG_DOWN;
456 mISDN_write(mISDNdevice, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC);
460 * subfunction for bchannel_event
463 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
465 unsigned char buff[1024];
467 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
468 add_trace("channel", NULL, "%d", i+1+(i>=15));
469 add_trace("stack", "id", "0x%8x", mISDNport->b_stid[i]);
470 add_trace("stack", "address", "0x%8x", mISDNport->b_addr[i]);
472 /* remove our stack only if set */
473 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
474 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
475 if (mISDNport->b_addr[i])
476 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
477 mISDNport->b_addr[i] = 0;
485 A bchannel goes through the following states in this order:
488 No one is using the bchannel.
489 It is available and not linked to Port class, nor reserved.
492 The bchannel stack is created and an activation request is sent.
493 It MAY be linked to Port class, but already unlinked due to Port class removal.
496 The bchannel is active and cofigured to the Port class needs.
497 Also it is linked to a Port class, otherwhise it would be deactivated.
499 - B_STATE_DEACTIVATING
500 The bchannel is in deactivating state, due to deactivation request.
501 It may be linked to a Port class, that likes to reactivate it.
505 After deactivating bchannel, and if not used, the bchannel becomes idle again.
508 A bchannel can have the following events:
511 A bchannel is required by a Port class.
514 The bchannel beomes active.
517 The bchannel is not required by Port class anymore
519 - B_EVENT_DEACTIVATED
520 The bchannel becomes inactive.
522 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
527 * process bchannel events
528 * - mISDNport is a pointer to the port's structure
529 * - i is the index of the bchannel
530 * - event is the B_EVENT_* value
531 * - port is the PmISDN class pointer
533 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
535 int state = mISDNport->b_state[i];
537 printf("event=%d state=%d\n", event, state);
540 case B_EVENT_ACTIVATE:
541 /* port must be linked in order to allow activation */
542 if (!mISDNport->b_port[i])
544 PERROR("SOFTWARE ERROR: bchannel must be linked to a Port class\n");
550 /* create stack and send activation request */
551 if (_bchannel_create(mISDNport, i))
553 _bchannel_activate(mISDNport, i);
554 state = B_STATE_ACTIVATING;
558 case B_STATE_ACTIVATING:
559 /* do nothing, because it is already activating */
562 case B_STATE_DEACTIVATING:
563 /* do nothing, because we must wait until we can reactivate */
567 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
571 case B_EVENT_ACTIVATED:
574 case B_STATE_ACTIVATING:
575 if (mISDNport->b_port[i])
577 /* bchannel is active and used by Port class, so we configure bchannel */
578 _bchannel_configure(mISDNport, i);
579 state = B_STATE_ACTIVE;
582 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
583 _bchannel_deactivate(mISDNport, i);
584 state = B_STATE_DEACTIVATING;
589 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
593 case B_EVENT_DEACTIVATE:
594 if (!mISDNport->b_port[i])
596 PERROR("SOFTWARE ERROR: bchannel must be linked to a Port class\n");
602 /* bchannel is idle due to an error, so we do nothing */
605 case B_STATE_ACTIVATING:
606 /* do nothing because we must wait until bchanenl is active before deactivating */
610 /* bchannel is active, so we deactivate */
611 _bchannel_deactivate(mISDNport, i);
612 state = B_STATE_DEACTIVATING;
615 case B_STATE_DEACTIVATING:
616 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
620 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
624 case B_EVENT_DEACTIVATED:
625 _bchannel_destroy(mISDNport, i);
626 state = B_STATE_IDLE;
629 case B_STATE_DEACTIVATING:
630 if (mISDNport->b_port[i])
632 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
633 if (_bchannel_create(mISDNport, i))
635 _bchannel_activate(mISDNport, i);
636 state = B_STATE_ACTIVATING;
642 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
647 PERROR("Illegal event %d, please correct.\n", event);
650 mISDNport->b_state[i] = state;
657 * check for available channel and reserve+set it.
658 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
660 * returns -(cause value) or x = channel x or 0 = no channel
661 * NOTE: no activation is done here
663 int PmISDN::seize_bchannel(int channel, int exclusive)
667 /* the channel is what we have */
668 if (p_m_b_channel == channel)
671 /* if channel already in use, release it */
676 if (channel==CHANNEL_NO || channel==0)
679 /* is channel in range ? */
681 || (channel>p_m_mISDNport->b_num && channel<16)
682 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
683 return(-6); /* channel unacceptable */
685 /* request exclusive channel */
686 if (exclusive && channel>0)
688 i = channel-1-(channel>16);
689 if (p_m_mISDNport->b_port[i])
690 return(-44); /* requested channel not available */
694 /* ask for channel */
697 i = channel-1-(channel>16);
698 if (p_m_mISDNport->b_port[i] == NULL)
702 /* search for channel */
704 while(i < p_m_mISDNport->b_num)
706 if (!p_m_mISDNport->b_port[i])
708 channel = i+1+(i>=15);
713 return(-34); /* no free channel */
716 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
719 p_m_mISDNport->b_port[i] = this;
721 p_m_b_channel = channel;
722 p_m_b_exclusive = exclusive;
725 /* reserve channel */
729 p_m_mISDNport->b_reserved++;
736 * drop reserved channel and unset it.
737 * deactivation is also done
739 void PmISDN::drop_bchannel(void)
744 /* unreserve channel */
746 p_m_mISDNport->b_reserved--;
753 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
755 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
756 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DEACTIVATE);
757 p_m_mISDNport->b_port[p_m_b_index] = NULL;
767 int PmISDN::handler(void)
769 struct message *message;
774 if ((ret = Port::handler()))
777 inbuffer = (p_m_fromup_buffer_writep - p_m_fromup_buffer_readp) & FROMUP_BUFFER_MASK;
778 /* send tone data to isdn device only if we have data */
779 if (p_tone_name[0] || p_m_crypt_msg_loops || inbuffer)
781 /* calculate how much to transmit */
784 elapsed = ISDN_PRELOAD; /* preload for the first time */
787 elapsed = 8000 * (now_tv.tv_sec - p_last_tv_sec)
788 + 8 * (now_tv.tv_usec/1000 - p_last_tv_msec);
789 /* gap was greater preload, so only fill up to preload level */
790 if (elapsed > ISDN_PRELOAD)
792 elapsed = ISDN_PRELOAD;
795 if (elapsed >= ISDN_TRANSMIT)
797 unsigned char buf[mISDN_HEADER_LEN+ISDN_PRELOAD];
798 iframe_t *frm = (iframe_t *)buf;
799 unsigned char *p = buf+mISDN_HEADER_LEN;
801 p_last_tv_sec = now_tv.tv_sec;
802 p_last_tv_msec = now_tv.tv_usec/1000;
804 /* read tones or fill with silence */
805 length = read_audio(p, elapsed);
809 * the fromup_buffer data is written to the beginning of the buffer
810 * the part that is filles with tones (length) is skipped, so tones have priority
811 * the length value is increased by the number of data copied from fromup_buffer
816 /* inbuffer might be less than we skip due to audio */
817 if (inbuffer <= length)
820 p_m_fromup_buffer_readp = p_m_fromup_buffer_writep;
824 /* skip what we already have with tones */
825 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + length) & FROMUP_BUFFER_MASK;
829 /* if we have more in buffer, than we send this time */
830 if (inbuffer > (elapsed-length))
831 inbuffer = elapsed - length;
832 /* set length to what we actually have */
833 length = length + inbuffer;
834 /* now fill up with fromup_buffer */
837 *p++ = p_m_fromup_buffer[p_m_fromup_buffer_readp];
838 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + 1) & FROMUP_BUFFER_MASK;
843 /* overwrite buffer with crypto stuff */
844 if (p_m_crypt_msg_loops)
847 /* send pending message */
850 /* how much do we have to send */
851 tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
852 if (tosend > elapsed)
855 /* our length increases, if less */
859 /* copy message (part) to buffer */
860 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
861 p_m_crypt_msg_current += tosend;
862 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
864 p_m_crypt_msg_current = 0;
865 p_m_crypt_msg_loops--;
868 frm->prim = DL_DATA | REQUEST;
869 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
872 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
874 if (p_debug_nothingtosend)
876 p_debug_nothingtosend = 0;
877 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
883 if (!p_debug_nothingtosend)
885 p_debug_nothingtosend = 1;
886 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
890 // NOTE: deletion is done by the child class
892 /* handle timeouts */
895 if (p_m_timer+p_m_timeout < now_d)
897 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
899 /* send timeout to endpoint */
900 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
901 message->param.state = p_state;
902 message_put(message);
907 return(0); /* nothing done */
912 * whenever we get audio data from bchannel, we process it here
914 void PmISDN::bchannel_receive(iframe_t *frm)
916 unsigned char *data_temp;
917 unsigned long length_temp;
918 struct message *message;
922 // iframe_t rsp; /* response to possible indication */
924 #warning BCHANNEL-DEBUG
926 // check if we are part of all ports */
927 class Port *port = port_first;
936 PERROR_RUNTIME("**************************************************\n");
937 PERROR_RUNTIME("*** BCHANNEL-DEBUG: !this! is not in list of ports\n");
938 PERROR_RUNTIME("**************************************************\n");
945 if (frm->prim == (PH_CONTROL | INDICATION))
949 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
952 cont = *((unsigned long *)&frm->data.p);
953 // PDEBUG(DEBUG_PORT, "PmISDN(%s) received a PH_CONTROL INDICATION 0x%x\n", p_name, cont);
954 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
956 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
957 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
959 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
960 message->param.dtmf = cont & DTMF_TONE_MASK;
961 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
962 message_put(message);
968 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
969 add_trace("DSP-CRYPT", NULL, "error");
971 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
972 message->param.crypt.type = CC_ERROR_IND;
973 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
974 message_put(message);
978 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
979 add_trace("DSP-CRYPT", NULL, "ok");
981 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
982 message->param.crypt.type = CC_ACTBF_CONF;
983 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
984 message_put(message);
990 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
991 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring rx data, because 'txdata' is turned off\n", p_name);
995 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
999 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1000 add_trace("unknown", NULL, "0x%x", cont);
1005 if (frm->prim != (PH_DATA | INDICATION))
1007 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1011 /* calls will not process any audio data unless
1012 * the call is connected OR tones feature is enabled.
1014 if (p_state!=PORT_STATE_CONNECT
1015 && !p_m_mISDNport->tones)
1019 /* the bearer capability must be audio in order to send and receive
1020 * audio prior or after connect.
1022 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1026 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1029 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1035 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1037 /* randomize and listen to crypt message if enabled */
1038 if (p_m_crypt_listen)
1040 /* the noisy randomizer */
1041 p = (unsigned char *)&frm->data.p;
1044 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1046 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1049 p = (unsigned char *)&frm->data.p;
1051 /* send data to epoint */
1052 if (p_m_calldata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1054 //printf("we are port %s and sending to epoint %d\n", p_m_cardname, p_epoint->serial);
1055 length_temp = frm->len;
1059 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1060 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1061 memcpy(message->param.data.data, data_temp, message->param.data.len);
1062 message_put(message);
1063 if (length_temp <= sizeof(message->param.data.data))
1065 data_temp += sizeof(message->param.data.data);
1066 length_temp -= sizeof(message->param.data.data);
1070 /* response to the data indication */
1071 rsp.prim = frm->prim & 0xfffffffc | RESPONSE;
1072 rsp.addr = frm->addr & INST_ID_MASK | FLG_MSG_DOWN;
1073 rsp.dinfo = frm->dinfo;
1075 mISDN_write(mISDNdevice, &rsp, mISDN_HEADER_LEN+rsp.len, TIMEOUT_1SEC);
1076 //PDEBUG(DEBUG_ISDN, "written %d bytes.\n", length);
1084 void PmISDN::set_echotest(int echo)
1086 if (p_m_echo != echo)
1089 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1091 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1092 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);
1099 void PmISDN::set_tone(char *dir, char *tone)
1105 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1112 /* check if we NOT really have to use a dsp-tone */
1113 if (!options.dsptones)
1117 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1119 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1120 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1123 Port::set_tone(dir, tone);
1129 /* now we USE dsp-tone, convert name */
1130 else if (!strcmp(tone, "dialtone"))
1132 switch(options.dsptones) {
1133 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1134 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1135 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1137 } else if (!strcmp(tone, "dialpbx"))
1139 switch(options.dsptones) {
1140 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1141 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1142 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1144 } else if (!strcmp(tone, "ringing"))
1146 switch(options.dsptones) {
1147 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1148 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1149 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1151 } else if (!strcmp(tone, "ringpbx"))
1153 switch(options.dsptones) {
1154 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1155 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1156 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1158 } else if (!strcmp(tone, "busy"))
1161 switch(options.dsptones) {
1162 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1163 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1164 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1166 } else if (!strcmp(tone, "release"))
1169 switch(options.dsptones) {
1170 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1171 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1172 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1174 } else if (!strcmp(tone, "cause_10"))
1176 else if (!strcmp(tone, "cause_11"))
1178 else if (!strcmp(tone, "cause_22"))
1180 switch(options.dsptones) {
1181 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1182 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1183 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1185 } else if (!strncmp(tone, "cause_", 6))
1186 id = TONE_SPECIAL_INFO;
1190 /* if we have a tone that is not supported by dsp */
1191 if (id==TONE_OFF && tone[0])
1199 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1201 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1202 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);
1204 /* turn user-space tones off in cases of no tone OR dsp tone */
1205 Port::set_tone("",NULL);
1209 /* MESSAGE_mISDNSIGNAL */
1210 //extern struct message *dddebug;
1211 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1213 switch(param->mISDNsignal.message)
1215 case mISDNSIGNAL_VOLUME:
1216 if (p_m_txvol != param->mISDNsignal.txvol)
1218 p_m_txvol = param->mISDNsignal.txvol;
1219 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1221 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1222 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);
1224 if (p_m_rxvol != param->mISDNsignal.rxvol)
1226 p_m_rxvol = param->mISDNsignal.rxvol;
1227 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1229 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1230 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);
1234 case mISDNSIGNAL_CONF:
1235 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1236 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1237 if (p_m_conf != param->mISDNsignal.conf)
1239 p_m_conf = param->mISDNsignal.conf;
1240 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1242 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1243 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);
1245 /* we must set, even if currently tone forbids conf */
1246 p_m_conf = param->mISDNsignal.conf;
1247 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1250 case mISDNSIGNAL_CALLDATA:
1251 if (p_m_calldata != param->mISDNsignal.calldata)
1253 p_m_calldata = param->mISDNsignal.calldata;
1254 PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata);
1258 case mISDNSIGNAL_DELAY:
1259 if (p_m_delay != param->mISDNsignal.delay)
1261 p_m_delay = param->mISDNsignal.delay;
1262 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1264 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1265 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);
1270 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1275 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1277 struct message *message;
1279 switch(param->crypt.type)
1281 case CC_ACTBF_REQ: /* activate blowfish */
1283 p_m_crypt_key_len = param->crypt.len;
1284 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1286 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1287 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1288 message->param.crypt.type = CC_ERROR_IND;
1289 message_put(message);
1292 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1294 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1296 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1297 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);
1300 case CC_DACT_REQ: /* deactivate session encryption */
1305 case CR_LISTEN_REQ: /* start listening to messages */
1306 p_m_crypt_listen = 1;
1307 p_m_crypt_listen_state = 0;
1310 case CR_UNLISTEN_REQ: /* stop listening to messages */
1311 p_m_crypt_listen = 0;
1314 case CR_MESSAGE_REQ: /* send message */
1315 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1316 if (!p_m_crypt_msg_len)
1318 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1321 p_m_crypt_msg_current = 0; /* reset */
1322 p_m_crypt_msg_loops = 3; /* enable */
1324 /* disable txmix, or we get corrupt data due to audio process */
1327 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1328 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1334 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1340 * endpoint sends messages to the port
1342 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1344 if (Port::message_epoint(epoint_id, message_id, param))
1349 case MESSAGE_DATA: /* tx-data from upper layer */
1350 txfromup(param->data.data, param->data.len);
1353 case MESSAGE_mISDNSIGNAL: /* user command */
1354 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1355 message_mISDNsignal(epoint_id, message_id, param);
1358 case MESSAGE_CRYPT: /* crypt control command */
1359 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1360 message_crypt(epoint_id, message_id, param);
1369 * main loop for processing messages from mISDN device
1371 int mISDN_handler(void)
1376 struct mISDNport *mISDNport;
1377 class PmISDN *isdnport;
1380 mISDNuser_head_t *hh;
1383 /* the que avoids loopbacks when replying to stack after receiving
1385 mISDNport = mISDNport_first;
1388 /* process turning on/off rx */
1390 while(i < mISDNport->b_num)
1392 isdnport=mISDNport->b_port[i];
1395 /* call bridges in user space OR crypto OR recording */
1396 if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1398 /* rx IS required */
1399 if (isdnport->p_m_rxoff)
1402 isdnport->p_m_rxoff = 0;
1403 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1404 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1405 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1410 /* rx NOT required */
1411 if (!isdnport->p_m_rxoff)
1414 isdnport->p_m_rxoff = 1;
1415 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1416 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1417 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1422 if (isdnport->p_record)
1424 /* txdata IS required */
1425 if (!isdnport->p_m_txdata)
1428 isdnport->p_m_txdata = 1;
1429 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1430 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1431 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1436 /* txdata NOT required */
1437 if (isdnport->p_m_txdata)
1440 isdnport->p_m_txdata = 0;
1441 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1442 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1443 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1451 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1453 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1454 mISDNport->l1timeout = 0;
1457 if (mISDNport->l2establish)
1459 if (now-mISDNport->l2establish > 5)
1461 if (mISDNport->ntmode)
1463 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1464 time(&mISDNport->l2establish);
1466 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1467 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1470 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1471 time(&mISDNport->l2establish);
1474 act.prim = DL_ESTABLISH | REQUEST;
1475 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1478 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1480 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1485 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1487 if (mISDNport->ntmode)
1489 hh = (mISDNuser_head_t *)dmsg->data;
1490 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);
1491 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1495 frm = (iframe_t *)dmsg->data;
1496 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1497 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1498 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);
1499 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1504 mISDNport = mISDNport->next;
1507 /* no device, no read */
1508 if (mISDNdevice < 0)
1511 /* get message from kernel */
1512 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1514 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1518 if (errno == EAGAIN)
1520 PERROR("FATAL ERROR: failed to do mISDN_read()\n");
1526 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1530 frm = (iframe_t *)msg->data;
1535 case MGR_DELLAYER | CONFIRM:
1536 case MGR_INITTIMER | CONFIRM:
1537 case MGR_ADDTIMER | CONFIRM:
1538 case MGR_DELTIMER | CONFIRM:
1539 case MGR_REMOVETIMER | CONFIRM:
1540 // if (options.deb & DEBUG_ISDN)
1541 // PDEBUG(DEBUG_ISDN, "timer-confirm\n");
1547 mISDNport = mISDNport_first;
1550 if ((frm->prim==(MGR_TIMER | INDICATION)) && mISDNport->ntmode)
1552 itimer_t *it = mISDNport->nst.tlist;
1557 if (it->id == (int)frm->addr)
1563 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1564 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1566 PDEBUG(DEBUG_ISDN, "timer-indication %s port %d it=%p\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, it);
1567 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1568 ret = it->function(it->data);
1571 /* we will continue here because we have a timer for a different mISDNport */
1573 //printf("comparing frm->addr %x with upper_id %x\n", frm->addr, mISDNport->upper_id);
1574 if ((frm->addr&STACK_ID_MASK) == (unsigned int)(mISDNport->upper_id&STACK_ID_MASK))
1579 case MGR_SHORTSTATUS | INDICATION:
1580 case MGR_SHORTSTATUS | CONFIRM:
1581 switch(frm->dinfo) {
1582 case SSTATUS_L1_ACTIVATED:
1583 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1586 case SSTATUS_L1_DEACTIVATED:
1587 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1590 case SSTATUS_L2_ESTABLISHED:
1591 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1594 case SSTATUS_L2_RELEASED:
1595 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1601 case PH_ACTIVATE | CONFIRM:
1602 case PH_ACTIVATE | INDICATION:
1603 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1605 if (mISDNport->ntmode)
1607 mISDNport->l1link = 1;
1608 setup_queue(mISDNport, 1);
1612 mISDNport->l1link = 1;
1613 setup_queue(mISDNport, 1);
1616 case PH_DEACTIVATE | CONFIRM:
1617 case PH_DEACTIVATE | INDICATION:
1618 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1620 if (mISDNport->ntmode)
1622 mISDNport->l1link = 0;
1623 setup_queue(mISDNport, 0);
1627 mISDNport->l1link = 0;
1628 setup_queue(mISDNport, 0);
1631 case PH_CONTROL | CONFIRM:
1632 case PH_CONTROL | INDICATION:
1633 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1636 case DL_ESTABLISH | INDICATION:
1637 case DL_ESTABLISH | CONFIRM:
1638 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1640 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1642 if (mISDNport->l2establish)
1644 mISDNport->l2establish = 0;
1645 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1647 mISDNport->l2link = 1;
1650 case DL_RELEASE | INDICATION:
1651 case DL_RELEASE | CONFIRM:
1652 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1654 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1656 mISDNport->l2link = 0;
1659 time(&mISDNport->l2establish);
1660 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
1666 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);
1667 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
1669 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
1672 if (mISDNport->ntmode)
1674 /* l1-data enters the nt-mode library */
1675 nst = &mISDNport->nst;
1676 if (nst->l1_l2(nst, msg))
1681 /* l3-data is sent to pbx */
1682 if (stack2manager_te(mISDNport, msg))
1689 //PDEBUG(DEBUG_ISDN, "flg:%d upper_id=%x addr=%x\n", (frm->addr&FLG_CHILD_STACK), (mISDNport->b_addr[0])&(~IF_CHILDMASK), (frm->addr)&(~IF_CHILDMASK));
1690 /* check if child, and if parent stack match */
1691 if ((frm->addr&FLG_CHILD_STACK) && (((unsigned int)(mISDNport->b_addr[0])&(~CHILD_ID_MASK)&STACK_ID_MASK) == ((frm->addr)&(~CHILD_ID_MASK)&STACK_ID_MASK)))
1696 /* we don't care about confirms, we use rx data to sync tx */
1697 case PH_DATA | CONFIRM:
1698 case DL_DATA | CONFIRM:
1701 /* we receive audio data, we respond to it AND we send tones */
1702 case PH_DATA | INDICATION:
1703 case DL_DATA | INDICATION:
1704 case PH_CONTROL | INDICATION:
1706 while(i < mISDNport->b_num)
1708 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1712 if (i == mISDNport->b_num)
1714 PERROR("unhandled b-message (address 0x%x).\n", frm->addr);
1717 if (mISDNport->b_port[i])
1719 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
1720 mISDNport->b_port[i]->bchannel_receive(frm);
1722 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
1725 case PH_ACTIVATE | INDICATION:
1726 case DL_ESTABLISH | INDICATION:
1727 case PH_ACTIVATE | CONFIRM:
1728 case DL_ESTABLISH | CONFIRM:
1729 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
1731 while(i < mISDNport->b_num)
1733 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1737 if (i == mISDNport->b_num)
1739 PERROR("unhandled b-establish (address 0x%x).\n", frm->addr);
1742 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1745 case PH_DEACTIVATE | INDICATION:
1746 case DL_RELEASE | INDICATION:
1747 case PH_DEACTIVATE | CONFIRM:
1748 case DL_RELEASE | CONFIRM:
1749 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
1751 while(i < mISDNport->b_num)
1753 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1757 if (i == mISDNport->b_num)
1759 PERROR("unhandled b-release (address 0x%x).\n", frm->addr);
1762 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1768 mISDNport = mISDNport->next;
1772 if (frm->prim == (MGR_TIMER | INDICATION))
1773 PERROR("unhandled timer indication message: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1775 PERROR("unhandled message: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1776 // PERROR("test: is_child: %x of stack %x == %x (baddr %x frm %x)\n", (frm->addr&FLG_CHILD_STACK), ((unsigned int)(mISDNport_first->b_addr[0])&(~CHILD_ID_MASK)&STACK_ID_MASK), ((frm->addr)&(~CHILD_ID_MASK)&STACK_ID_MASK), mISDNport_first->b_addr[0], frm->addr);
1785 * global function to add a new card (port)
1787 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
1790 unsigned char buff[1025];
1791 iframe_t *frm = (iframe_t *)buff;
1792 stack_info_t *stinf;
1793 struct mISDNport *mISDNport, **mISDNportp;
1795 // interface_info_t ii;
1802 /* open mISDNdevice if not already open */
1803 if (mISDNdevice < 0)
1808 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));
1812 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
1814 /* create entity for layer 3 TE-mode */
1815 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1816 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
1817 if (ret < (int)mISDN_HEADER_LEN)
1820 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
1823 entity = frm->dinfo & 0xffff;
1826 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
1829 /* query port's requirements */
1830 cnt = mISDN_get_stack_count(mISDNdevice);
1833 PERROR("Found no card. Please be sure to load card drivers.\n");
1836 if (port>cnt || port<1)
1838 PERROR("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
1841 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
1844 PERROR("Cannot get stack info for port %d (ret=%d)\n", port, ret);
1847 stinf = (stack_info_t *)&frm->data.p;
1848 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
1850 case ISDN_PID_L0_TE_S0:
1851 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
1853 case ISDN_PID_L0_NT_S0:
1854 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
1857 case ISDN_PID_L0_TE_E1:
1858 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
1861 case ISDN_PID_L0_NT_E1:
1862 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
1867 PERROR("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
1873 if (stinf->pid.protocol[1] == 0)
1875 PERROR("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
1878 if (stinf->pid.protocol[2])
1880 PERROR("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
1886 if (stinf->pid.protocol[1] == 0)
1888 PERROR("Given port %d: Missing layer 1 protocol.\n", port);
1891 if (stinf->pid.protocol[2] == 0)
1893 PERROR("Given port %d: Missing layer 2 protocol.\n", port);
1896 if (stinf->pid.protocol[3] == 0)
1898 PERROR("Given port %d: Missing layer 3 protocol.\n", port);
1902 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
1904 case ISDN_PID_L3_DSS1USER:
1908 PERROR("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
1912 if (stinf->pid.protocol[4])
1914 PERROR("Given port %d: Layer 4 protocol not allowed.\n", port);
1919 /* add mISDNport structure */
1920 mISDNportp = &mISDNport_first;
1922 mISDNportp = &((*mISDNportp)->next);
1923 mISDNport = (struct mISDNport *)calloc(1, sizeof(struct mISDNport));
1926 PERROR("Cannot alloc mISDNport structure\n");
1930 memset(mISDNport, 0, sizeof(mISDNport));
1931 *mISDNportp = mISDNport;
1933 /* allocate ressources of port */
1934 msg_queue_init(&mISDNport->downqueue);
1935 // SCPY(mISDNport->name, "noname");
1936 mISDNport->portnum = port;
1937 mISDNport->ntmode = nt;
1938 mISDNport->pri = pri;
1939 mISDNport->d_stid = stinf->id;
1940 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
1941 mISDNport->b_num = stinf->childcnt;
1942 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
1943 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
1945 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
1946 mISDNport->ptp = ptp = 1;
1949 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
1950 mISDNport->ptp = ptp = 0;
1954 while(i < stinf->childcnt)
1956 mISDNport->b_stid[i] = stinf->child[i];
1957 mISDNport->b_state[i] = B_STATE_IDLE;
1958 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
1961 memset(&li, 0, sizeof(li));
1962 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
1965 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1966 li.pid.layermask = ISDN_LAYER((nt?2:4));
1967 li.st = mISDNport->d_stid;
1968 ret = mISDN_new_layer(mISDNdevice, &li);
1971 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
1973 mISDNport_close(mISDNport);
1976 mISDNport->upper_id = li.id;
1977 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
1980 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
1983 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
1984 if (mISDNport->lower_id < 0)
1986 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
1989 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
1990 if (mISDNport->upper_id < 0)
1992 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
1995 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
1997 /* if ntmode, establish L1 to send the tei removal during start */
1998 if (mISDNport->ntmode)
2002 act.prim = PH_ACTIVATE | REQUEST;
2003 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2004 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2007 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2008 usleep(10000); /* to be sure, that l1 is up */
2011 /* create nst (nt-mode only) */
2014 mgr = &mISDNport->mgr;
2015 nst = &mISDNport->nst;
2020 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2021 nst->device = mISDNdevice;
2023 nst->d_stid = mISDNport->d_stid;
2025 nst->feature = FEATURE_NET_HOLD;
2027 nst->feature |= FEATURE_NET_PTP;
2029 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2032 while(i < mISDNport->b_num)
2034 nst->b_stid[i] = mISDNport->b_stid[i];
2038 nst->l1_id = mISDNport->lower_id;
2039 nst->l2_id = mISDNport->upper_id;
2042 msg_queue_init(&nst->down_queue);
2048 /* if te-mode, query state link */
2049 if (!mISDNport->ntmode)
2053 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2054 act.prim = MGR_SHORTSTATUS | REQUEST;
2055 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2056 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2058 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2060 /* if ptp AND te-mode, pull up the link */
2061 if (mISDNport->ptp && !mISDNport->ntmode)
2065 act.prim = DL_ESTABLISH | REQUEST;
2066 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2069 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2071 /* if ptp AND nt-mode, pull up the link */
2072 if (mISDNport->ptp && mISDNport->ntmode)
2076 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2077 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2080 /* initially, we assume that the link is down, exept for nt-ptmp */
2081 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2083 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2085 start_trace(mISDNport->portnum,
2093 add_trace("channels", NULL, "%d", mISDNport->b_num);
2100 * function to free ALL cards (ports)
2102 void mISDNport_close_all(void)
2104 /* free all ports */
2105 while(mISDNport_first)
2106 mISDNport_close(mISDNport_first);
2110 * free only one port
2112 void mISDNport_close(struct mISDNport *mISDNport)
2114 struct mISDNport **mISDNportp;
2116 class PmISDN *isdnport;
2118 unsigned char buf[32];
2121 /* remove all port instance that are linked to this mISDNport */
2125 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2127 isdnport = (class PmISDN *)port;
2128 if (isdnport->p_m_mISDNport)
2130 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2137 /* only if we are already part of interface */
2138 if (mISDNport->ifport)
2140 start_trace(mISDNport->portnum,
2141 mISDNport->ifport->interface,
2151 /* free bchannels */
2153 while(i < mISDNport->b_num)
2155 if (mISDNport->b_addr[i])
2157 _bchannel_destroy(mISDNport, i);
2158 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2163 /* free ressources of port */
2164 msg_queue_purge(&mISDNport->downqueue);
2167 if (mISDNport->ntmode)
2169 nst = &mISDNport->nst;
2170 if (nst->manager) /* to see if initialized */
2172 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");
2173 cleanup_Isdnl3(nst);
2174 cleanup_Isdnl2(nst);
2177 msg_queue_purge(&nst->down_queue);
2178 if (nst->phd_down_msg)
2179 free(nst->phd_down_msg);
2183 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2184 if (mISDNport->d_stid)
2186 if (mISDNport->upper_id)
2187 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2190 /* remove from list */
2191 mISDNportp = &mISDNport_first;
2194 if (*mISDNportp == mISDNport)
2196 *mISDNportp = (*mISDNportp)->next;
2200 mISDNportp = &((*mISDNportp)->next);
2205 PERROR("software error, mISDNport not in list\n");
2209 memset(mISDNport, 0, sizeof(struct mISDNport));
2213 /* close mISDNdevice, if no port */
2214 if (mISDNdevice>=0 && mISDNport_first==NULL)
2217 mISDN_write_frame(mISDNdevice, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2219 mISDN_close(mISDNdevice);
2221 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
2227 * global function to show all available isdn ports
2229 void mISDN_port_info(void)
2233 int useable, nt, pri;
2234 unsigned char buff[1025];
2235 iframe_t *frm = (iframe_t *)buff;
2236 stack_info_t *stinf;
2240 if ((device = mISDN_open()) < 0)
2242 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));
2246 /* get number of stacks */
2248 ii = mISDN_get_stack_count(device);
2252 printf("Found no card. Please be sure to load card drivers.\n");
2255 /* loop the number of cards and get their info */
2258 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2261 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2264 stinf = (stack_info_t *)&frm->data.p;
2269 /* output the port info */
2270 printf("Port %2d: ", i);
2271 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2273 case ISDN_PID_L0_TE_S0:
2274 printf("TE-mode BRI S/T interface line (for phone lines)");
2276 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2277 printf(" HFC multiport card");
2280 case ISDN_PID_L0_NT_S0:
2282 printf("NT-mode BRI S/T interface port (for phones)");
2284 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2285 printf(" HFC multiport card");
2288 case ISDN_PID_L0_TE_E1:
2290 printf("TE-mode PRI E1 interface line (for phone lines)");
2292 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2293 printf(" HFC-E1 card");
2296 case ISDN_PID_L0_NT_E1:
2299 printf("NT-mode PRI E1 interface port (for phones)");
2301 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2302 printf(" HFC-E1 card");
2307 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2313 if (stinf->pid.protocol[1] == 0)
2316 printf(" -> Missing layer 1 NT-mode protocol.\n");
2319 while(p <= MAX_LAYER_NR) {
2320 if (stinf->pid.protocol[p])
2323 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
2330 printf(" -> Interface is Point-To-Point (PRI).\n");
2332 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2336 if (stinf->pid.protocol[1] == 0)
2339 printf(" -> Missing layer 1 protocol.\n");
2341 if (stinf->pid.protocol[2] == 0)
2344 printf(" -> Missing layer 2 protocol.\n");
2346 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2348 printf(" -> Interface is Poin-To-Point.\n");
2350 if (stinf->pid.protocol[3] == 0)
2353 printf(" -> Missing layer 3 protocol.\n");
2356 printf(" -> Protocol: ");
2357 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2359 case ISDN_PID_L3_DSS1USER:
2360 printf("DSS1 (Euro ISDN)");
2365 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2370 while(p <= MAX_LAYER_NR) {
2371 if (stinf->pid.protocol[p])
2374 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
2379 printf(" - %d B-channels\n", stinf->childcnt);
2382 printf(" * Port NOT useable for PBX\n");
2384 printf("--------\n");
2391 if ((err = mISDN_close(device)))
2393 fprintf(stderr, "mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2400 * enque data from upper buffer
2402 void PmISDN::txfromup(unsigned char *data, int length)
2409 /* get free samples in buffer */
2410 avail = ((p_m_fromup_buffer_readp - p_m_fromup_buffer_writep - 1) & FROMUP_BUFFER_MASK);
2413 PDEBUG(DEBUG_PORT, "Port(%d): fromup_buffer overflows, this shall not happen under normal conditions\n", p_serial);
2417 /* write data to buffer and return */
2420 p_m_fromup_buffer[p_m_fromup_buffer_writep] = *data++;
2421 p_m_fromup_buffer_writep = (p_m_fromup_buffer_writep + 1) & FROMUP_BUFFER_MASK;
2424 return; // must return, because length is 0