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->interface:NULL,
145 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
146 port?port->p_dialinginfo.number: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.number: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");
312 if (mISDNport->b_addr[i])
314 PERROR("Error: stack already created");
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", "%d", mISDNport->b_stid[i]);
367 add_trace("stack", "address", "%d", 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", "%d", mISDNport->b_stid[i]);
470 add_trace("stack", "address", "%d", 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];
539 case B_EVENT_ACTIVATE:
540 /* port may not be used by any other bchannel */
541 if (mISDNport->b_port[i])
543 PERROR("SOFTWARE ERROR: bchannel must not be linked to a Port class\n");
549 /* create stack and send activation request */
550 if (_bchannel_create(mISDNport, i))
552 _bchannel_activate(mISDNport, i);
553 state = B_STATE_ACTIVATING;
557 case B_STATE_ACTIVATING:
558 /* do nothing, because it is already activating */
561 case B_STATE_DEACTIVATING:
562 /* do nothing, because we must wait until we can reactivate */
566 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
570 case B_EVENT_ACTIVATED:
573 case B_STATE_ACTIVATING:
574 if (mISDNport->b_port[i])
576 /* bchannel is active and used by Port class, so we configure bchannel */
577 _bchannel_configure(mISDNport, i);
578 state = B_STATE_ACTIVE;
581 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
582 _bchannel_deactivate(mISDNport, i);
583 state = B_STATE_DEACTIVATING;
588 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
592 case B_EVENT_DEACTIVATE:
593 if (!mISDNport->b_port[i])
595 PERROR("SOFTWARE ERROR: bchannel must be linked to a Port class\n");
601 /* bchannel is idle due to an error, so we do nothing */
604 case B_STATE_ACTIVATING:
605 /* do nothing because we must wait until bchanenl is active before deactivating */
609 /* bchannel is active, so we deactivate */
610 _bchannel_deactivate(mISDNport, i);
611 state = B_STATE_DEACTIVATING;
614 case B_STATE_DEACTIVATING:
615 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
619 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
623 case B_EVENT_DEACTIVATED:
624 _bchannel_destroy(mISDNport, i);
625 state = B_STATE_IDLE;
628 case B_STATE_DEACTIVATING:
629 if (mISDNport->b_port[i])
631 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
632 if (_bchannel_create(mISDNport, i))
634 _bchannel_activate(mISDNport, i);
635 state = B_STATE_ACTIVATING;
641 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
646 PERROR("Illegal event %d, please correct.\n", event);
649 mISDNport->b_state[i] = state;
656 * check for available channel and reserve+set it.
657 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
659 * returns -(cause value) or x = channel x or 0 = no channel
660 * NOTE: no activation is done here
662 int PmISDN::seize_bchannel(int channel, int exclusive)
666 /* the channel is what we have */
667 if (p_m_b_channel == channel)
670 /* if channel already in use, release it */
675 if (channel==CHANNEL_NO || channel==0)
678 /* is channel in range ? */
680 || (channel>p_m_mISDNport->b_num && channel<16)
681 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
682 return(-6); /* channel unacceptable */
684 /* request exclusive channel */
685 if (exclusive && channel>0)
687 i = channel-1-(channel>16);
688 if (p_m_mISDNport->b_port[i])
689 return(-44); /* requested channel not available */
693 /* ask for channel */
696 i = channel-1-(channel>16);
697 if (p_m_mISDNport->b_port[i] == NULL)
701 /* search for channel */
703 while(i < p_m_mISDNport->b_num)
705 if (!p_m_mISDNport->b_port[i])
707 channel = i+1+(i>=15);
712 return(-34); /* no free channel */
715 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
718 p_m_mISDNport->b_port[i] = this;
720 p_m_b_channel = channel;
721 p_m_b_exclusive = exclusive;
724 /* reserve channel */
728 p_m_mISDNport->b_reserved++;
735 * drop reserved channel and unset it.
736 * deactivation is also done
738 void PmISDN::drop_bchannel(void)
743 /* unreserve channel */
745 p_m_mISDNport->b_reserved--;
752 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
754 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
755 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DEACTIVATE);
756 p_m_mISDNport->b_port[p_m_b_index] = NULL;
766 int PmISDN::handler(void)
768 struct message *message;
773 if ((ret = Port::handler()))
776 inbuffer = (p_m_fromup_buffer_writep - p_m_fromup_buffer_readp) & FROMUP_BUFFER_MASK;
777 /* send tone data to isdn device only if we have data */
778 if (p_tone_fh>=0 || p_tone_fetched || p_m_crypt_msg_loops || inbuffer)
780 /* calculate how much to transmit */
783 elapsed = ISDN_PRELOAD; /* preload for the first time */
786 elapsed = 8000 * (now_tv.tv_sec - p_last_tv_sec)
787 + 8 * (now_tv.tv_usec/1000 - p_last_tv_msec);
788 /* gap was greater preload, so only fill up to preload level */
789 if (elapsed > ISDN_PRELOAD)
791 elapsed = ISDN_PRELOAD;
794 if (elapsed >= ISDN_TRANSMIT)
796 unsigned char buf[mISDN_HEADER_LEN+ISDN_PRELOAD], *p = buf;
797 iframe_t *frm = (iframe_t *)buf;
799 p_last_tv_sec = now_tv.tv_sec;
800 p_last_tv_msec = now_tv.tv_usec/1000;
803 length = read_audio(p, elapsed);
807 * the fromup_buffer data is written to the beginning of the buffer
808 * the part that is filles with tones (length) is skipped, so tones have priority
809 * the length value is increased by the number of data copied from fromup_buffer
813 /* inbuffer might be less than we skip due to audio */
814 if (inbuffer <= length)
817 p_m_fromup_buffer_readp = p_m_fromup_buffer_writep;
821 /* skip what we already have with tones */
822 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + length) & FROMUP_BUFFER_MASK;
826 /* if we have more in buffer, than we send this time */
827 if (inbuffer > (elapsed-length))
828 inbuffer = elapsed - length;
829 /* set length to what we actually have */
830 length = length + inbuffer;
831 /* now fill up with fromup_buffer */
834 *p++ = p_m_fromup_buffer[p_m_fromup_buffer_readp];
835 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + 1) & FROMUP_BUFFER_MASK;
840 /* overwrite buffer with crypto stuff */
841 if (p_m_crypt_msg_loops)
843 /* send pending message */
846 /* how much do we have to send */
847 tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
848 if (tosend > elapsed)
851 /* our length increases, if less */
855 /* copy message (part) to buffer */
856 memcpy(buf, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
857 p_m_crypt_msg_current += tosend;
858 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
860 p_m_crypt_msg_current = 0;
861 p_m_crypt_msg_loops--;
864 frm->prim = DL_DATA | REQUEST;
865 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
868 memcpy(&frm->data.p, buf, length);
869 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
871 if (p_debug_nothingtosend)
873 p_debug_nothingtosend = 0;
874 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
880 if (!p_debug_nothingtosend)
882 p_debug_nothingtosend = 1;
883 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
887 // NOTE: deletion is done by the child class
889 /* handle timeouts */
892 if (p_m_timer+p_m_timeout < now_d)
894 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
896 /* send timeout to endpoint */
897 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
898 message->param.state = p_state;
899 message_put(message);
904 return(0); /* nothing done */
909 * whenever we get audio data from bchannel, we process it here
911 void PmISDN::bchannel_receive(iframe_t *frm)
913 unsigned char *data_temp;
914 unsigned long length_temp;
915 struct message *message;
919 // iframe_t rsp; /* response to possible indication */
921 #warning BCHANNEL-DEBUG
923 // check if we are part of all ports */
924 class Port *port = port_first;
933 PERROR_RUNTIME("**************************************************\n");
934 PERROR_RUNTIME("*** BCHANNEL-DEBUG: !this! is not in list of ports\n");
935 PERROR_RUNTIME("**************************************************\n");
942 if (frm->prim == (PH_CONTROL | INDICATION))
946 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
949 cont = *((unsigned long *)&frm->data.p);
950 // PDEBUG(DEBUG_PORT, "PmISDN(%s) received a PH_CONTROL INDICATION 0x%x\n", p_name, cont);
951 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
953 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
954 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
956 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
957 message->param.dtmf = cont & DTMF_TONE_MASK;
958 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
959 message_put(message);
965 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
966 add_trace("DSP-CRYPT", NULL, "error");
968 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
969 message->param.crypt.type = CC_ERROR_IND;
970 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
971 message_put(message);
975 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
976 add_trace("DSP-CRYPT", NULL, "ok");
978 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
979 message->param.crypt.type = CC_ACTBF_CONF;
980 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
981 message_put(message);
987 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
988 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring rx data, because 'txdata' is turned off\n", p_name);
992 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
996 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
997 add_trace("unknown", NULL, "0x%x", cont);
1002 if (frm->prim != (PH_DATA | INDICATION))
1004 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1008 /* calls will not process any audio data unless
1009 * the call is connected OR tones feature is enabled.
1011 if (p_state!=PORT_STATE_CONNECT
1012 && !p_m_mISDNport->is_tones)
1016 /* the bearer capability must be audio in order to send and receive
1017 * audio prior or after connect.
1019 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1023 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1026 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1032 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1034 /* randomize and listen to crypt message if enabled */
1035 if (p_m_crypt_listen)
1037 /* the noisy randomizer */
1038 p = (unsigned char *)&frm->data.p;
1041 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1043 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1046 p = (unsigned char *)&frm->data.p;
1048 /* send data to epoint */
1049 if (p_m_calldata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1051 //printf("we are port %s and sending to epoint %d\n", p_m_cardname, p_epoint->serial);
1052 length_temp = frm->len;
1056 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1057 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1058 memcpy(message->param.data.data, data_temp, message->param.data.len);
1059 message_put(message);
1060 if (length_temp <= sizeof(message->param.data.data))
1062 data_temp += sizeof(message->param.data.data);
1063 length_temp -= sizeof(message->param.data.data);
1067 /* response to the data indication */
1068 rsp.prim = frm->prim & 0xfffffffc | RESPONSE;
1069 rsp.addr = frm->addr & INST_ID_MASK | FLG_MSG_DOWN;
1070 rsp.dinfo = frm->dinfo;
1072 mISDN_write(mISDNdevice, &rsp, mISDN_HEADER_LEN+rsp.len, TIMEOUT_1SEC);
1073 //PDEBUG(DEBUG_ISDN, "written %d bytes.\n", length);
1081 void PmISDN::set_echotest(int echo)
1083 if (p_m_echo != echo)
1086 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1088 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1089 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);
1096 void PmISDN::set_tone(char *dir, char *tone)
1102 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1109 /* check if we NOT really have to use a dsp-tone */
1110 if (!options.dsptones)
1114 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1116 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1117 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1120 Port::set_tone(dir, tone);
1126 /* now we USE dsp-tone, convert name */
1127 else if (!strcmp(tone, "dialtone"))
1129 switch(options.dsptones) {
1130 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1131 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1132 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1134 } else if (!strcmp(tone, "dialpbx"))
1136 switch(options.dsptones) {
1137 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1138 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1139 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1141 } else if (!strcmp(tone, "ringing"))
1143 switch(options.dsptones) {
1144 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1145 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1146 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1148 } else if (!strcmp(tone, "ringpbx"))
1150 switch(options.dsptones) {
1151 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1152 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1153 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1155 } else if (!strcmp(tone, "busy"))
1158 switch(options.dsptones) {
1159 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1160 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1161 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1163 } else if (!strcmp(tone, "release"))
1166 switch(options.dsptones) {
1167 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1168 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1169 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1171 } else if (!strcmp(tone, "cause_10"))
1173 else if (!strcmp(tone, "cause_11"))
1175 else if (!strcmp(tone, "cause_22"))
1177 switch(options.dsptones) {
1178 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1179 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1180 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1182 } else if (!strncmp(tone, "cause_", 6))
1183 id = TONE_SPECIAL_INFO;
1187 /* if we have a tone that is not supported by dsp */
1188 if (id==TONE_OFF && tone[0])
1196 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1198 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1199 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);
1201 /* turn user-space tones off in cases of no tone OR dsp tone */
1202 Port::set_tone("",NULL);
1206 /* MESSAGE_mISDNSIGNAL */
1207 //extern struct message *dddebug;
1208 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1210 switch(param->mISDNsignal.message)
1212 case mISDNSIGNAL_VOLUME:
1213 if (p_m_txvol != param->mISDNsignal.txvol)
1215 p_m_txvol = param->mISDNsignal.txvol;
1216 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1218 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1219 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);
1221 if (p_m_rxvol != param->mISDNsignal.rxvol)
1223 p_m_rxvol = param->mISDNsignal.rxvol;
1224 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1226 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1227 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);
1231 case mISDNSIGNAL_CONF:
1232 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1233 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1234 if (p_m_conf != param->mISDNsignal.conf)
1236 p_m_conf = param->mISDNsignal.conf;
1237 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1239 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1240 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);
1242 /* we must set, even if currently tone forbids conf */
1243 p_m_conf = param->mISDNsignal.conf;
1244 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1247 case mISDNSIGNAL_CALLDATA:
1248 if (p_m_calldata != param->mISDNsignal.calldata)
1250 p_m_calldata = param->mISDNsignal.calldata;
1251 PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata);
1255 case mISDNSIGNAL_DELAY:
1256 if (p_m_delay != param->mISDNsignal.delay)
1258 p_m_delay = param->mISDNsignal.delay;
1259 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1261 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1262 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);
1267 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1272 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1274 struct message *message;
1276 switch(param->crypt.type)
1278 case CC_ACTBF_REQ: /* activate blowfish */
1280 p_m_crypt_key_len = param->crypt.len;
1281 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1283 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1284 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1285 message->param.crypt.type = CC_ERROR_IND;
1286 message_put(message);
1289 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1291 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1293 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1294 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);
1297 case CC_DACT_REQ: /* deactivate session encryption */
1302 case CR_LISTEN_REQ: /* start listening to messages */
1303 p_m_crypt_listen = 1;
1304 p_m_crypt_listen_state = 0;
1307 case CR_UNLISTEN_REQ: /* stop listening to messages */
1308 p_m_crypt_listen = 0;
1311 case CR_MESSAGE_REQ: /* send message */
1312 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1313 if (!p_m_crypt_msg_len)
1315 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1318 p_m_crypt_msg_current = 0; /* reset */
1319 p_m_crypt_msg_loops = 3; /* enable */
1321 /* disable txmix, or we get corrupt data due to audio process */
1324 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1325 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1331 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1337 * endpoint sends messages to the port
1339 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1341 if (Port::message_epoint(epoint_id, message_id, param))
1346 case MESSAGE_DATA: /* tx-data from upper layer */
1347 txfromup(param->data.data, param->data.len);
1350 case MESSAGE_mISDNSIGNAL: /* user command */
1351 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1352 message_mISDNsignal(epoint_id, message_id, param);
1355 case MESSAGE_CRYPT: /* crypt control command */
1356 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1357 message_crypt(epoint_id, message_id, param);
1366 * main loop for processing messages from mISDN device
1368 int mISDN_handler(void)
1373 struct mISDNport *mISDNport;
1374 class PmISDN *isdnport;
1377 mISDNuser_head_t *hh;
1380 /* the que avoids loopbacks when replying to stack after receiving
1382 mISDNport = mISDNport_first;
1385 /* process turning on/off rx */
1387 while(i < mISDNport->b_num)
1389 isdnport=mISDNport->b_port[i];
1392 /* call bridges in user space OR crypto OR recording */
1393 if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1395 /* rx IS required */
1396 if (isdnport->p_m_rxoff)
1399 isdnport->p_m_rxoff = 0;
1400 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1401 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1402 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1407 /* rx NOT required */
1408 if (!isdnport->p_m_rxoff)
1411 isdnport->p_m_rxoff = 1;
1412 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1413 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1414 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1419 if (isdnport->p_record)
1421 /* txdata IS required */
1422 if (!isdnport->p_m_txdata)
1425 isdnport->p_m_txdata = 1;
1426 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1427 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1428 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1433 /* txdata NOT required */
1434 if (isdnport->p_m_txdata)
1437 isdnport->p_m_txdata = 0;
1438 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1439 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1440 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1448 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1450 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1451 mISDNport->l1timeout = 0;
1454 if (mISDNport->l2establish)
1456 if (now-mISDNport->l2establish > 5)
1458 if (mISDNport->ntmode)
1460 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1461 time(&mISDNport->l2establish);
1463 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1464 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1467 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1468 time(&mISDNport->l2establish);
1471 act.prim = DL_ESTABLISH | REQUEST;
1472 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1475 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1477 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1482 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1484 if (mISDNport->ntmode)
1486 hh = (mISDNuser_head_t *)dmsg->data;
1487 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);
1488 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1492 frm = (iframe_t *)dmsg->data;
1493 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1494 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1495 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);
1496 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1501 mISDNport = mISDNport->next;
1504 /* get message from kernel */
1505 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1507 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1511 if (errno == EAGAIN)
1513 PERROR("FATAL ERROR: failed to do mISDN_read()\n");
1519 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1523 frm = (iframe_t *)msg->data;
1528 case MGR_INITTIMER | CONFIRM:
1529 case MGR_ADDTIMER | CONFIRM:
1530 case MGR_DELTIMER | CONFIRM:
1531 case MGR_REMOVETIMER | CONFIRM:
1532 // if (options.deb & DEBUG_ISDN)
1533 // PDEBUG(DEBUG_ISDN, "timer-confirm\n");
1539 mISDNport = mISDNport_first;
1542 if ((frm->prim==(MGR_TIMER | INDICATION)) && mISDNport->ntmode)
1544 itimer_t *it = mISDNport->nst.tlist;
1549 if (it->id == (int)frm->addr)
1555 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1556 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1558 PDEBUG(DEBUG_ISDN, "timer-indication %s port %d it=%p\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, it);
1559 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1560 ret = it->function(it->data);
1563 /* we will continue here because we have a timer for a different mISDNport */
1565 //printf("comparing frm->addr %x with upper_id %x\n", frm->addr, mISDNport->upper_id);
1566 if ((frm->addr&STACK_ID_MASK) == (unsigned int)(mISDNport->upper_id&STACK_ID_MASK))
1571 case MGR_SHORTSTATUS | INDICATION:
1572 case MGR_SHORTSTATUS | CONFIRM:
1573 switch(frm->dinfo) {
1574 case SSTATUS_L1_ACTIVATED:
1575 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1578 case SSTATUS_L1_DEACTIVATED:
1579 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1582 case SSTATUS_L2_ESTABLISHED:
1583 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1586 case SSTATUS_L2_RELEASED:
1587 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1593 case PH_ACTIVATE | CONFIRM:
1594 case PH_ACTIVATE | INDICATION:
1595 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1597 if (mISDNport->ntmode)
1599 mISDNport->l1link = 1;
1600 setup_queue(mISDNport, 1);
1604 mISDNport->l1link = 1;
1605 setup_queue(mISDNport, 1);
1608 case PH_DEACTIVATE | CONFIRM:
1609 case PH_DEACTIVATE | INDICATION:
1610 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1612 if (mISDNport->ntmode)
1614 mISDNport->l1link = 0;
1615 setup_queue(mISDNport, 0);
1619 mISDNport->l1link = 0;
1620 setup_queue(mISDNport, 0);
1623 case PH_CONTROL | CONFIRM:
1624 case PH_CONTROL | INDICATION:
1625 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1628 case DL_ESTABLISH | INDICATION:
1629 case DL_ESTABLISH | CONFIRM:
1630 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1632 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1634 if (mISDNport->l2establish)
1636 mISDNport->l2establish = 0;
1637 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1639 mISDNport->l2link = 1;
1642 case DL_RELEASE | INDICATION:
1643 case DL_RELEASE | CONFIRM:
1644 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1646 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1648 mISDNport->l2link = 0;
1651 time(&mISDNport->l2establish);
1652 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
1658 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);
1659 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
1661 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
1664 if (mISDNport->ntmode)
1666 /* l1-data enters the nt-mode library */
1667 nst = &mISDNport->nst;
1668 if (nst->l1_l2(nst, msg))
1673 /* l3-data is sent to pbx */
1674 if (stack2manager_te(mISDNport, msg))
1681 //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));
1682 /* check if child, and if parent stack match */
1683 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)))
1688 /* we don't care about confirms, we use rx data to sync tx */
1689 case PH_DATA | CONFIRM:
1690 case DL_DATA | CONFIRM:
1693 /* we receive audio data, we respond to it AND we send tones */
1694 case PH_DATA | INDICATION:
1695 case DL_DATA | INDICATION:
1696 case PH_CONTROL | INDICATION:
1698 while(i < mISDNport->b_num)
1700 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1704 if (i == mISDNport->b_num)
1706 PERROR("unhandled b-message (address 0x%x).\n", frm->addr);
1709 if (mISDNport->b_port[i])
1711 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
1712 mISDNport->b_port[i]->bchannel_receive(frm);
1714 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
1717 case PH_ACTIVATE | INDICATION:
1718 case DL_ESTABLISH | INDICATION:
1719 case PH_ACTIVATE | CONFIRM:
1720 case DL_ESTABLISH | CONFIRM:
1721 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
1723 while(i < mISDNport->b_num)
1725 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1729 if (i == mISDNport->b_num)
1731 PERROR("unhandled b-establish (address 0x%x).\n", frm->addr);
1734 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1737 case PH_DEACTIVATE | INDICATION:
1738 case DL_RELEASE | INDICATION:
1739 case PH_DEACTIVATE | CONFIRM:
1740 case DL_RELEASE | CONFIRM:
1741 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
1743 while(i < mISDNport->b_num)
1745 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1749 if (i == mISDNport->b_num)
1751 PERROR("unhandled b-release (address 0x%x).\n", frm->addr);
1754 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1760 mISDNport = mISDNport->next;
1764 if (frm->prim == (MGR_TIMER | INDICATION))
1765 PERROR("unhandled timer indication message: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1767 PERROR("unhandled message: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1768 // 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);
1777 * global function to add a new card (port)
1779 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp)
1782 unsigned char buff[1025];
1783 iframe_t *frm = (iframe_t *)buff;
1784 stack_info_t *stinf;
1785 struct mISDNport *mISDNport, **mISDNportp;
1787 // interface_info_t ii;
1794 /* open mISDNdevice if not already open */
1795 if (mISDNdevice < 0)
1800 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));
1804 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
1806 /* create entity for layer 3 TE-mode */
1807 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1808 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
1809 if (ret < (int)mISDN_HEADER_LEN)
1812 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
1815 entity = frm->dinfo & 0xffff;
1818 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
1821 /* query port's requirements */
1822 cnt = mISDN_get_stack_count(mISDNdevice);
1825 PERROR("Found no card. Please be sure to load card drivers.\n");
1828 if (port>cnt || port<1)
1830 PERROR("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
1833 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
1836 PERROR("Cannot get stack info for port %d (ret=%d)\n", port, ret);
1839 stinf = (stack_info_t *)&frm->data.p;
1840 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
1842 case ISDN_PID_L0_TE_S0:
1843 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
1845 case ISDN_PID_L0_NT_S0:
1846 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
1849 case ISDN_PID_L0_TE_E1:
1850 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
1853 case ISDN_PID_L0_NT_E1:
1854 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
1859 PERROR("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
1865 if (stinf->pid.protocol[1] == 0)
1867 PERROR("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
1870 if (stinf->pid.protocol[2])
1872 PERROR("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
1878 if (stinf->pid.protocol[1] == 0)
1880 PERROR("Given port %d: Missing layer 1 protocol.\n", port);
1883 if (stinf->pid.protocol[2] == 0)
1885 PERROR("Given port %d: Missing layer 2 protocol.\n", port);
1888 if (stinf->pid.protocol[3] == 0)
1890 PERROR("Given port %d: Missing layer 3 protocol.\n", port);
1894 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
1896 case ISDN_PID_L3_DSS1USER:
1900 PERROR("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
1904 if (stinf->pid.protocol[4])
1906 PERROR("Given port %d: Layer 4 protocol not allowed.\n", port);
1911 /* add mISDNport structure */
1912 mISDNportp = &mISDNport_first;
1914 mISDNportp = &mISDNport->next;
1915 mISDNport = (struct mISDNport *)calloc(1, sizeof(struct mISDNport));
1918 PERROR("Cannot alloc mISDNport structure\n");
1922 memset(mISDNport, 0, sizeof(mISDNport));
1923 *mISDNportp = mISDNport;
1925 /* allocate ressources of port */
1926 msg_queue_init(&mISDNport->downqueue);
1927 // SCPY(mISDNport->name, "noname");
1928 mISDNport->portnum = port;
1929 mISDNport->ntmode = nt;
1930 mISDNport->pri = pri;
1931 mISDNport->d_stid = stinf->id;
1932 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
1933 mISDNport->b_num = stinf->childcnt;
1934 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
1935 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
1937 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
1938 mISDNport->ptp = ptp = 1;
1941 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
1942 mISDNport->ptp = ptp = 0;
1946 while(i < stinf->childcnt)
1948 mISDNport->b_stid[i] = stinf->child[i];
1949 mISDNport->b_state[i] = B_STATE_IDLE;
1950 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
1953 memset(&li, 0, sizeof(li));
1954 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
1957 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1958 li.pid.layermask = ISDN_LAYER((nt?2:4));
1959 li.st = mISDNport->d_stid;
1960 ret = mISDN_new_layer(mISDNdevice, &li);
1963 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
1965 mISDNport_close(mISDNport);
1968 mISDNport->upper_id = li.id;
1969 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
1972 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
1975 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
1976 if (mISDNport->lower_id < 0)
1978 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
1981 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
1982 if (mISDNport->upper_id < 0)
1984 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
1987 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
1989 /* if ntmode, establish L1 to send the tei removal during start */
1990 if (mISDNport->ntmode)
1994 act.prim = PH_ACTIVATE | REQUEST;
1995 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
1996 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
1999 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2000 usleep(10000); /* to be sure, that l1 is up */
2003 /* create nst (nt-mode only) */
2006 mgr = &mISDNport->mgr;
2007 nst = &mISDNport->nst;
2012 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2013 nst->device = mISDNdevice;
2015 nst->d_stid = mISDNport->d_stid;
2017 nst->feature = FEATURE_NET_HOLD;
2019 nst->feature |= FEATURE_NET_PTP;
2021 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2024 while(i < mISDNport->b_num)
2026 nst->b_stid[i] = mISDNport->b_stid[i];
2030 nst->l1_id = mISDNport->lower_id;
2031 nst->l2_id = mISDNport->upper_id;
2034 msg_queue_init(&nst->down_queue);
2040 /* if te-mode, query state link */
2041 if (!mISDNport->ntmode)
2045 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2046 act.prim = MGR_SHORTSTATUS | REQUEST;
2047 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2048 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2050 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2052 /* if ptp AND te-mode, pull up the link */
2053 if (mISDNport->ptp && !mISDNport->ntmode)
2057 act.prim = DL_ESTABLISH | REQUEST;
2058 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2061 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2063 /* if ptp AND nt-mode, pull up the link */
2064 if (mISDNport->ptp && mISDNport->ntmode)
2068 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2069 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2072 /* initially, we assume that the link is down, exept for nt-ptmp */
2073 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2075 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2077 start_trace(mISDNport->portnum,
2078 mISDNport->ifport->interface,
2085 add_trace("channels", NULL, "%d", mISDNport->b_num);
2092 * function to free ALL cards (ports)
2094 void mISDNport_close_all(void)
2096 /* free all ports */
2097 while(mISDNport_first)
2098 mISDNport_close(mISDNport_first);
2102 * free only one port
2104 void mISDNport_close(struct mISDNport *mISDNport)
2106 struct mISDNport **mISDNportp;
2108 class PmISDN *isdnport;
2110 unsigned char buf[32];
2113 /* remove all port instance that are linked to this mISDNport */
2117 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2119 isdnport = (class PmISDN *)port;
2120 if (isdnport->p_m_mISDNport)
2122 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2129 start_trace(mISDNport->portnum,
2130 mISDNport->ifport->interface,
2139 /* free bchannels */
2141 while(i < mISDNport->b_num)
2143 if (mISDNport->b_stid[i])
2145 _bchannel_destroy(mISDNport, i);
2146 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2151 /* free ressources of port */
2152 msg_queue_purge(&mISDNport->downqueue);
2155 if (mISDNport->ntmode)
2157 nst = &mISDNport->nst;
2158 if (nst->manager) /* to see if initialized */
2160 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");
2161 cleanup_Isdnl3(nst);
2162 cleanup_Isdnl2(nst);
2165 msg_queue_purge(&nst->down_queue);
2166 if (nst->phd_down_msg)
2167 free(nst->phd_down_msg);
2171 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2172 if (mISDNport->d_stid)
2174 // mISDN_clear_stack(mISDNdevice, mISDNport->d_stid);
2175 if (mISDNport->lower_id)
2176 mISDN_write_frame(mISDNdevice, buf, mISDNport->lower_id, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2179 /* remove from list */
2180 mISDNportp = &mISDNport_first;
2183 if (*mISDNportp == mISDNport)
2185 *mISDNportp = (*mISDNportp)->next;
2188 mISDNportp = &((*mISDNportp)->next);
2193 PERROR("software error, mISDNport not in list\n");
2197 memset(mISDNport, 0, sizeof(struct mISDNport));
2201 /* close mISDNdevice, if no port */
2202 if (mISDNdevice>=0 && mISDNport_first==NULL)
2205 mISDN_write_frame(mISDNdevice, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2207 mISDN_close(mISDNdevice);
2209 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
2215 * global function to show all available isdn ports
2217 void mISDN_port_info(void)
2221 int useable, nt, pri;
2222 unsigned char buff[1025];
2223 iframe_t *frm = (iframe_t *)buff;
2224 stack_info_t *stinf;
2228 if ((device = mISDN_open()) < 0)
2230 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));
2234 /* get number of stacks */
2236 ii = mISDN_get_stack_count(device);
2240 printf("Found no card. Please be sure to load card drivers.\n");
2243 /* loop the number of cards and get their info */
2246 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2249 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2252 stinf = (stack_info_t *)&frm->data.p;
2257 /* output the port info */
2258 printf("Port %2d: ", i);
2259 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2261 case ISDN_PID_L0_TE_S0:
2262 printf("TE-mode BRI S/T interface line (for phone lines)");
2264 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2265 printf(" HFC multiport card");
2268 case ISDN_PID_L0_NT_S0:
2270 printf("NT-mode BRI S/T interface port (for phones)");
2272 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2273 printf(" HFC multiport card");
2276 case ISDN_PID_L0_TE_E1:
2278 printf("TE-mode PRI E1 interface line (for phone lines)");
2280 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2281 printf(" HFC-E1 card");
2284 case ISDN_PID_L0_NT_E1:
2287 printf("NT-mode PRI E1 interface port (for phones)");
2289 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2290 printf(" HFC-E1 card");
2295 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2301 if (stinf->pid.protocol[1] == 0)
2304 printf(" -> Missing layer 1 NT-mode protocol.\n");
2307 while(p <= MAX_LAYER_NR) {
2308 if (stinf->pid.protocol[p])
2311 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
2318 printf(" -> Interface is Point-To-Point (PRI).\n");
2320 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2324 if (stinf->pid.protocol[1] == 0)
2327 printf(" -> Missing layer 1 protocol.\n");
2329 if (stinf->pid.protocol[2] == 0)
2332 printf(" -> Missing layer 2 protocol.\n");
2334 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2336 printf(" -> Interface is Poin-To-Point.\n");
2338 if (stinf->pid.protocol[3] == 0)
2341 printf(" -> Missing layer 3 protocol.\n");
2344 printf(" -> Protocol: ");
2345 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2347 case ISDN_PID_L3_DSS1USER:
2348 printf("DSS1 (Euro ISDN)");
2353 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2358 while(p <= MAX_LAYER_NR) {
2359 if (stinf->pid.protocol[p])
2362 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
2367 printf(" - %d B-channels\n", stinf->childcnt);
2370 printf(" * Port NOT useable for PBX\n");
2372 printf("--------\n");
2379 if ((err = mISDN_close(device)))
2381 fprintf(stderr, "mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2388 * enque data from upper buffer
2390 void PmISDN::txfromup(unsigned char *data, int length)
2397 /* get free samples in buffer */
2398 avail = ((p_m_fromup_buffer_readp - p_m_fromup_buffer_writep - 1) & FROMUP_BUFFER_MASK);
2401 PDEBUG(DEBUG_PORT, "Port(%d): fromup_buffer overflows, this shall not happen under normal conditions\n", p_serial);
2405 /* write data to buffer and return */
2408 p_m_fromup_buffer[p_m_fromup_buffer_writep] = *data++;
2409 p_m_fromup_buffer_writep = (p_m_fromup_buffer_writep + 1) & FROMUP_BUFFER_MASK;
2412 return; // must return, because length is 0