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)
448 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL deactivate", DIRECTION_OUT);
449 add_trace("channel", NULL, "%d", i+1+(i>=15));
451 dact.prim = DL_RELEASE | REQUEST;
452 dact.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
455 mISDN_write(mISDNdevice, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC);
459 * subfunction for bchannel_event
462 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
464 unsigned char buff[1024];
466 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
467 add_trace("channel", NULL, "%d", i+1+(i>=15));
468 add_trace("stack", "id", "0x%8x", mISDNport->b_stid[i]);
469 add_trace("stack", "address", "0x%8x", mISDNport->b_addr[i]);
471 /* remove our stack only if set */
472 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
473 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
474 if (mISDNport->b_addr[i])
475 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
476 mISDNport->b_addr[i] = 0;
484 A bchannel goes through the following states in this order:
487 No one is using the bchannel.
488 It is available and not linked to Port class, nor reserved.
491 The bchannel stack is created and an activation request is sent.
492 It MAY be linked to Port class, but already unlinked due to Port class removal.
495 The bchannel is active and cofigured to the Port class needs.
496 Also it is linked to a Port class, otherwhise it would be deactivated.
498 - B_STATE_DEACTIVATING
499 The bchannel is in deactivating state, due to deactivation request.
500 It may be linked to a Port class, that likes to reactivate it.
504 After deactivating bchannel, and if not used, the bchannel becomes idle again.
507 A bchannel can have the following events:
510 A bchannel is required by a Port class.
513 The bchannel beomes active.
516 The bchannel is not required by Port class anymore
518 - B_EVENT_DEACTIVATED
519 The bchannel becomes inactive.
521 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
526 * process bchannel events
527 * - mISDNport is a pointer to the port's structure
528 * - i is the index of the bchannel
529 * - event is the B_EVENT_* value
530 * - port is the PmISDN class pointer
532 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
534 int state = mISDNport->b_state[i];
538 case B_EVENT_ACTIVATE:
539 /* port must be linked in order to allow activation */
540 if (!mISDNport->b_port[i])
542 PERROR("SOFTWARE ERROR: bchannel must be linked to a Port class\n");
548 /* create stack and send activation request */
549 if (_bchannel_create(mISDNport, i))
551 _bchannel_activate(mISDNport, i);
552 state = B_STATE_ACTIVATING;
556 case B_STATE_ACTIVATING:
557 /* do nothing, because it is already activating */
560 case B_STATE_DEACTIVATING:
561 /* do nothing, because we must wait until we can reactivate */
565 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
569 case B_EVENT_ACTIVATED:
572 case B_STATE_ACTIVATING:
573 if (mISDNport->b_port[i])
575 /* bchannel is active and used by Port class, so we configure bchannel */
576 _bchannel_configure(mISDNport, i);
577 state = B_STATE_ACTIVE;
580 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
581 _bchannel_deactivate(mISDNport, i);
582 state = B_STATE_DEACTIVATING;
587 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
591 case B_EVENT_DEACTIVATE:
592 if (!mISDNport->b_port[i])
594 PERROR("SOFTWARE ERROR: bchannel must be linked to a Port class\n");
600 /* bchannel is idle due to an error, so we do nothing */
603 case B_STATE_ACTIVATING:
604 /* do nothing because we must wait until bchanenl is active before deactivating */
608 /* bchannel is active, so we deactivate */
609 _bchannel_deactivate(mISDNport, i);
610 state = B_STATE_DEACTIVATING;
613 case B_STATE_DEACTIVATING:
614 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
618 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
622 case B_EVENT_DEACTIVATED:
626 /* ignore due to deactivation confirm after unloading */
629 case B_STATE_DEACTIVATING:
630 _bchannel_destroy(mISDNport, i);
631 state = B_STATE_IDLE;
632 if (mISDNport->b_port[i])
634 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
635 if (_bchannel_create(mISDNport, i))
637 _bchannel_activate(mISDNport, i);
638 state = B_STATE_ACTIVATING;
644 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
649 PERROR("Illegal event %d, please correct.\n", event);
652 mISDNport->b_state[i] = state;
659 * check for available channel and reserve+set it.
660 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
662 * returns -(cause value) or x = channel x or 0 = no channel
663 * NOTE: no activation is done here
665 int PmISDN::seize_bchannel(int channel, int exclusive)
669 /* the channel is what we have */
670 if (p_m_b_channel == channel)
673 /* if channel already in use, release it */
678 if (channel==CHANNEL_NO || channel==0)
681 /* is channel in range ? */
683 || (channel>p_m_mISDNport->b_num && channel<16)
684 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
685 return(-6); /* channel unacceptable */
687 /* request exclusive channel */
688 if (exclusive && channel>0)
690 i = channel-1-(channel>16);
691 if (p_m_mISDNport->b_port[i])
692 return(-44); /* requested channel not available */
696 /* ask for channel */
699 i = channel-1-(channel>16);
700 if (p_m_mISDNport->b_port[i] == NULL)
704 /* search for channel */
706 while(i < p_m_mISDNport->b_num)
708 if (!p_m_mISDNport->b_port[i])
710 channel = i+1+(i>=15);
715 return(-34); /* no free channel */
718 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
721 p_m_mISDNport->b_port[i] = this;
723 p_m_b_channel = channel;
724 p_m_b_exclusive = exclusive;
727 /* reserve channel */
731 p_m_mISDNport->b_reserved++;
738 * drop reserved channel and unset it.
739 * deactivation is also done
741 void PmISDN::drop_bchannel(void)
746 /* unreserve channel */
748 p_m_mISDNport->b_reserved--;
755 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
757 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
758 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DEACTIVATE);
759 p_m_mISDNport->b_port[p_m_b_index] = NULL;
769 int PmISDN::handler(void)
771 struct message *message;
776 if ((ret = Port::handler()))
779 inbuffer = (p_m_fromup_buffer_writep - p_m_fromup_buffer_readp) & FROMUP_BUFFER_MASK;
780 /* send tone data to isdn device only if we have data */
781 if (p_tone_name[0] || p_m_crypt_msg_loops || inbuffer)
783 /* calculate how much to transmit */
786 elapsed = ISDN_PRELOAD; /* preload for the first time */
789 elapsed = 8000 * (now_tv.tv_sec - p_last_tv_sec)
790 + 8 * (now_tv.tv_usec/1000 - p_last_tv_msec);
791 /* gap was greater preload, so only fill up to preload level */
792 if (elapsed > ISDN_PRELOAD)
794 elapsed = ISDN_PRELOAD;
797 if (elapsed >= ISDN_TRANSMIT)
799 unsigned char buf[mISDN_HEADER_LEN+ISDN_PRELOAD];
800 iframe_t *frm = (iframe_t *)buf;
801 unsigned char *p = buf+mISDN_HEADER_LEN;
803 p_last_tv_sec = now_tv.tv_sec;
804 p_last_tv_msec = now_tv.tv_usec/1000;
806 /* read tones or fill with silence */
807 length = read_audio(p, elapsed);
811 * the fromup_buffer data is written to the beginning of the buffer
812 * the part that is filles with tones (length) is skipped, so tones have priority
813 * the length value is increased by the number of data copied from fromup_buffer
818 /* inbuffer might be less than we skip due to audio */
819 if (inbuffer <= length)
822 p_m_fromup_buffer_readp = p_m_fromup_buffer_writep;
826 /* skip what we already have with tones */
827 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + length) & FROMUP_BUFFER_MASK;
831 /* if we have more in buffer, than we send this time */
832 if (inbuffer > (elapsed-length))
833 inbuffer = elapsed - length;
834 /* set length to what we actually have */
835 length = length + inbuffer;
836 /* now fill up with fromup_buffer */
839 *p++ = p_m_fromup_buffer[p_m_fromup_buffer_readp];
840 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + 1) & FROMUP_BUFFER_MASK;
845 /* overwrite buffer with crypto stuff */
846 if (p_m_crypt_msg_loops)
849 /* send pending message */
852 /* how much do we have to send */
853 tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
854 if (tosend > elapsed)
857 /* our length increases, if less */
861 /* copy message (part) to buffer */
862 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
863 p_m_crypt_msg_current += tosend;
864 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
866 p_m_crypt_msg_current = 0;
867 p_m_crypt_msg_loops--;
870 frm->prim = DL_DATA | REQUEST;
871 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
874 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
876 if (p_debug_nothingtosend)
878 p_debug_nothingtosend = 0;
879 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
885 if (!p_debug_nothingtosend)
887 p_debug_nothingtosend = 1;
888 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
892 // NOTE: deletion is done by the child class
894 /* handle timeouts */
897 if (p_m_timer+p_m_timeout < now_d)
899 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
901 /* send timeout to endpoint */
902 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
903 message->param.state = p_state;
904 message_put(message);
909 return(0); /* nothing done */
914 * whenever we get audio data from bchannel, we process it here
916 void PmISDN::bchannel_receive(iframe_t *frm)
918 unsigned char *data_temp;
919 unsigned long length_temp;
920 struct message *message;
924 // iframe_t rsp; /* response to possible indication */
926 #warning BCHANNEL-DEBUG
928 // check if we are part of all ports */
929 class Port *port = port_first;
938 PERROR_RUNTIME("**************************************************\n");
939 PERROR_RUNTIME("*** BCHANNEL-DEBUG: !this! is not in list of ports\n");
940 PERROR_RUNTIME("**************************************************\n");
947 if (frm->prim == (PH_CONTROL | INDICATION))
951 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
954 cont = *((unsigned long *)&frm->data.p);
955 // PDEBUG(DEBUG_PORT, "PmISDN(%s) received a PH_CONTROL INDICATION 0x%x\n", p_name, cont);
956 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
958 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
959 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
961 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
962 message->param.dtmf = cont & DTMF_TONE_MASK;
963 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
964 message_put(message);
970 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
971 add_trace("DSP-CRYPT", NULL, "error");
973 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
974 message->param.crypt.type = CC_ERROR_IND;
975 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
976 message_put(message);
980 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
981 add_trace("DSP-CRYPT", NULL, "ok");
983 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
984 message->param.crypt.type = CC_ACTBF_CONF;
985 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
986 message_put(message);
992 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
993 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring rx data, because 'txdata' is turned off\n", p_name);
997 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
1001 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1002 add_trace("unknown", NULL, "0x%x", cont);
1007 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
1009 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
1013 /* calls will not process any audio data unless
1014 * the call is connected OR tones feature is enabled.
1016 if (p_state!=PORT_STATE_CONNECT
1017 && !p_m_mISDNport->tones)
1021 /* the bearer capability must be audio in order to send and receive
1022 * audio prior or after connect.
1024 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1028 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1031 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1037 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1039 /* randomize and listen to crypt message if enabled */
1040 if (p_m_crypt_listen)
1042 /* the noisy randomizer */
1043 p = (unsigned char *)&frm->data.p;
1046 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1048 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1051 p = (unsigned char *)&frm->data.p;
1053 /* send data to epoint */
1054 if (p_m_calldata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1056 //printf("we are port %s and sending to epoint %d\n", p_m_cardname, p_epoint->serial);
1057 length_temp = frm->len;
1061 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1062 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1063 memcpy(message->param.data.data, data_temp, message->param.data.len);
1064 message_put(message);
1065 if (length_temp <= sizeof(message->param.data.data))
1067 data_temp += sizeof(message->param.data.data);
1068 length_temp -= sizeof(message->param.data.data);
1072 /* response to the data indication */
1073 rsp.prim = frm->prim & 0xfffffffc | RESPONSE;
1074 rsp.addr = frm->addr & INST_ID_MASK | FLG_MSG_DOWN;
1075 rsp.dinfo = frm->dinfo;
1077 mISDN_write(mISDNdevice, &rsp, mISDN_HEADER_LEN+rsp.len, TIMEOUT_1SEC);
1078 //PDEBUG(DEBUG_ISDN, "written %d bytes.\n", length);
1086 void PmISDN::set_echotest(int echo)
1088 if (p_m_echo != echo)
1091 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1093 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1094 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);
1101 void PmISDN::set_tone(char *dir, char *tone)
1107 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1114 /* check if we NOT really have to use a dsp-tone */
1115 if (!options.dsptones)
1119 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1121 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1122 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1125 Port::set_tone(dir, tone);
1131 /* now we USE dsp-tone, convert name */
1132 else if (!strcmp(tone, "dialtone"))
1134 switch(options.dsptones) {
1135 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1136 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1137 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1139 } else if (!strcmp(tone, "dialpbx"))
1141 switch(options.dsptones) {
1142 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1143 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1144 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1146 } else if (!strcmp(tone, "ringing"))
1148 switch(options.dsptones) {
1149 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1150 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1151 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1153 } else if (!strcmp(tone, "ringpbx"))
1155 switch(options.dsptones) {
1156 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1157 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1158 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1160 } else if (!strcmp(tone, "busy"))
1163 switch(options.dsptones) {
1164 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1165 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1166 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1168 } else if (!strcmp(tone, "release"))
1171 switch(options.dsptones) {
1172 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1173 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1174 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1176 } else if (!strcmp(tone, "cause_10"))
1178 else if (!strcmp(tone, "cause_11"))
1180 else if (!strcmp(tone, "cause_22"))
1182 switch(options.dsptones) {
1183 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1184 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1185 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1187 } else if (!strncmp(tone, "cause_", 6))
1188 id = TONE_SPECIAL_INFO;
1192 /* if we have a tone that is not supported by dsp */
1193 if (id==TONE_OFF && tone[0])
1201 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1203 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1204 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);
1206 /* turn user-space tones off in cases of no tone OR dsp tone */
1207 Port::set_tone("",NULL);
1211 /* MESSAGE_mISDNSIGNAL */
1212 //extern struct message *dddebug;
1213 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1215 switch(param->mISDNsignal.message)
1217 case mISDNSIGNAL_VOLUME:
1218 if (p_m_txvol != param->mISDNsignal.txvol)
1220 p_m_txvol = param->mISDNsignal.txvol;
1221 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1223 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1224 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);
1226 if (p_m_rxvol != param->mISDNsignal.rxvol)
1228 p_m_rxvol = param->mISDNsignal.rxvol;
1229 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1231 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1232 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);
1236 case mISDNSIGNAL_CONF:
1237 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1238 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1239 if (p_m_conf != param->mISDNsignal.conf)
1241 p_m_conf = param->mISDNsignal.conf;
1242 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1244 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1245 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);
1247 /* we must set, even if currently tone forbids conf */
1248 p_m_conf = param->mISDNsignal.conf;
1249 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1252 case mISDNSIGNAL_CALLDATA:
1253 if (p_m_calldata != param->mISDNsignal.calldata)
1255 p_m_calldata = param->mISDNsignal.calldata;
1256 PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata);
1260 case mISDNSIGNAL_DELAY:
1261 if (p_m_delay != param->mISDNsignal.delay)
1263 p_m_delay = param->mISDNsignal.delay;
1264 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1266 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1267 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);
1272 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1277 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1279 struct message *message;
1281 switch(param->crypt.type)
1283 case CC_ACTBF_REQ: /* activate blowfish */
1285 p_m_crypt_key_len = param->crypt.len;
1286 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1288 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1289 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1290 message->param.crypt.type = CC_ERROR_IND;
1291 message_put(message);
1294 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1296 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1298 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1299 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);
1302 case CC_DACT_REQ: /* deactivate session encryption */
1307 case CR_LISTEN_REQ: /* start listening to messages */
1308 p_m_crypt_listen = 1;
1309 p_m_crypt_listen_state = 0;
1312 case CR_UNLISTEN_REQ: /* stop listening to messages */
1313 p_m_crypt_listen = 0;
1316 case CR_MESSAGE_REQ: /* send message */
1317 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1318 if (!p_m_crypt_msg_len)
1320 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1323 p_m_crypt_msg_current = 0; /* reset */
1324 p_m_crypt_msg_loops = 3; /* enable */
1326 /* disable txmix, or we get corrupt data due to audio process */
1329 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1330 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1336 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1342 * endpoint sends messages to the port
1344 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1346 if (Port::message_epoint(epoint_id, message_id, param))
1351 case MESSAGE_DATA: /* tx-data from upper layer */
1352 txfromup(param->data.data, param->data.len);
1355 case MESSAGE_mISDNSIGNAL: /* user command */
1356 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1357 message_mISDNsignal(epoint_id, message_id, param);
1360 case MESSAGE_CRYPT: /* crypt control command */
1361 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1362 message_crypt(epoint_id, message_id, param);
1371 * main loop for processing messages from mISDN device
1373 int mISDN_handler(void)
1378 struct mISDNport *mISDNport;
1379 class PmISDN *isdnport;
1382 mISDNuser_head_t *hh;
1385 /* the que avoids loopbacks when replying to stack after receiving
1387 mISDNport = mISDNport_first;
1390 /* process turning on/off rx */
1392 while(i < mISDNport->b_num)
1394 isdnport=mISDNport->b_port[i];
1397 /* call bridges in user space OR crypto OR recording */
1398 if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1400 /* rx IS required */
1401 if (isdnport->p_m_rxoff)
1404 isdnport->p_m_rxoff = 0;
1405 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1406 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1407 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1412 /* rx NOT required */
1413 if (!isdnport->p_m_rxoff)
1416 isdnport->p_m_rxoff = 1;
1417 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1418 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1419 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1424 if (isdnport->p_record)
1426 /* txdata IS required */
1427 if (!isdnport->p_m_txdata)
1430 isdnport->p_m_txdata = 1;
1431 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1432 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1433 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1438 /* txdata NOT required */
1439 if (isdnport->p_m_txdata)
1442 isdnport->p_m_txdata = 0;
1443 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1444 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1445 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1453 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1455 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1456 mISDNport->l1timeout = 0;
1459 if (mISDNport->l2establish)
1461 if (now-mISDNport->l2establish > 5)
1463 if (mISDNport->ntmode)
1465 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1466 time(&mISDNport->l2establish);
1468 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1469 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1472 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1473 time(&mISDNport->l2establish);
1476 act.prim = DL_ESTABLISH | REQUEST;
1477 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1480 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1482 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1487 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1489 if (mISDNport->ntmode)
1491 hh = (mISDNuser_head_t *)dmsg->data;
1492 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);
1493 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1497 frm = (iframe_t *)dmsg->data;
1498 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1499 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1500 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);
1501 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1506 mISDNport = mISDNport->next;
1509 /* no device, no read */
1510 if (mISDNdevice < 0)
1513 /* get message from kernel */
1514 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1516 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1520 if (errno == EAGAIN)
1522 PERROR("FATAL ERROR: failed to do mISDN_read()\n");
1528 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1532 frm = (iframe_t *)msg->data;
1537 case MGR_DELLAYER | CONFIRM:
1538 case MGR_INITTIMER | CONFIRM:
1539 case MGR_ADDTIMER | CONFIRM:
1540 case MGR_DELTIMER | CONFIRM:
1541 case MGR_REMOVETIMER | CONFIRM:
1546 /* handle timer events from mISDN for NT-stack
1547 * note: they do not associate with a stack */
1548 if (frm->prim == (MGR_TIMER | INDICATION))
1552 /* find mISDNport */
1553 mISDNport = mISDNport_first;
1557 if (mISDNport->ntmode)
1559 it = mISDNport->nst.tlist;
1563 if (it->id == (int)frm->addr)
1570 mISDNport = mISDNport->next;
1574 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1575 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1577 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
1578 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1579 ret = it->function(it->data);
1582 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
1587 /* find the mISDNport that belongs to the stack */
1588 mISDNport = mISDNport_first;
1591 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
1593 mISDNport = mISDNport->next;
1597 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1602 if (!(frm->addr&FLG_CHILD_STACK))
1607 case MGR_SHORTSTATUS | INDICATION:
1608 case MGR_SHORTSTATUS | CONFIRM:
1609 switch(frm->dinfo) {
1610 case SSTATUS_L1_ACTIVATED:
1611 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1614 case SSTATUS_L1_DEACTIVATED:
1615 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1618 case SSTATUS_L2_ESTABLISHED:
1619 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1622 case SSTATUS_L2_RELEASED:
1623 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1629 case PH_ACTIVATE | CONFIRM:
1630 case PH_ACTIVATE | INDICATION:
1631 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1633 if (mISDNport->ntmode)
1635 mISDNport->l1link = 1;
1636 setup_queue(mISDNport, 1);
1640 mISDNport->l1link = 1;
1641 setup_queue(mISDNport, 1);
1644 case PH_DEACTIVATE | CONFIRM:
1645 case PH_DEACTIVATE | INDICATION:
1646 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1648 if (mISDNport->ntmode)
1650 mISDNport->l1link = 0;
1651 setup_queue(mISDNport, 0);
1655 mISDNport->l1link = 0;
1656 setup_queue(mISDNport, 0);
1659 case PH_CONTROL | CONFIRM:
1660 case PH_CONTROL | INDICATION:
1661 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1664 case DL_ESTABLISH | INDICATION:
1665 case DL_ESTABLISH | CONFIRM:
1666 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1668 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1670 if (mISDNport->l2establish)
1672 mISDNport->l2establish = 0;
1673 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1675 mISDNport->l2link = 1;
1678 case DL_RELEASE | INDICATION:
1679 case DL_RELEASE | CONFIRM:
1680 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1682 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1684 mISDNport->l2link = 0;
1687 time(&mISDNport->l2establish);
1688 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
1694 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);
1695 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
1697 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
1700 if (mISDNport->ntmode)
1702 /* l1-data enters the nt-mode library */
1703 nst = &mISDNport->nst;
1704 if (nst->l1_l2(nst, msg))
1709 /* l3-data is sent to pbx */
1710 if (stack2manager_te(mISDNport, msg))
1721 /* we don't care about confirms, we use rx data to sync tx */
1722 case PH_DATA | CONFIRM:
1723 case DL_DATA | CONFIRM:
1726 /* we receive audio data, we respond to it AND we send tones */
1727 case PH_DATA | INDICATION:
1728 case DL_DATA | INDICATION:
1729 case PH_CONTROL | INDICATION:
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-message (address 0x%x).\n", frm->addr);
1742 if (mISDNport->b_port[i])
1744 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
1745 mISDNport->b_port[i]->bchannel_receive(frm);
1747 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
1750 case PH_ACTIVATE | INDICATION:
1751 case DL_ESTABLISH | INDICATION:
1752 case PH_ACTIVATE | CONFIRM:
1753 case DL_ESTABLISH | CONFIRM:
1754 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
1756 while(i < mISDNport->b_num)
1758 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1762 if (i == mISDNport->b_num)
1764 PERROR("unhandled b-establish (address 0x%x).\n", frm->addr);
1767 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1770 case PH_DEACTIVATE | INDICATION:
1771 case DL_RELEASE | INDICATION:
1772 case PH_DEACTIVATE | CONFIRM:
1773 case DL_RELEASE | CONFIRM:
1774 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
1776 while(i < mISDNport->b_num)
1778 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1782 if (i == mISDNport->b_num)
1784 PERROR("unhandled b-release (address 0x%x).\n", frm->addr);
1787 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1791 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1802 * global function to add a new card (port)
1804 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
1807 unsigned char buff[1025];
1808 iframe_t *frm = (iframe_t *)buff;
1809 stack_info_t *stinf;
1810 struct mISDNport *mISDNport, **mISDNportp;
1812 // interface_info_t ii;
1819 /* open mISDNdevice if not already open */
1820 if (mISDNdevice < 0)
1825 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));
1829 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
1831 /* create entity for layer 3 TE-mode */
1832 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1833 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
1834 if (ret < (int)mISDN_HEADER_LEN)
1837 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
1840 entity = frm->dinfo & 0xffff;
1843 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
1846 /* query port's requirements */
1847 cnt = mISDN_get_stack_count(mISDNdevice);
1850 PERROR("Found no card. Please be sure to load card drivers.\n");
1853 if (port>cnt || port<1)
1855 PERROR("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
1858 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
1861 PERROR("Cannot get stack info for port %d (ret=%d)\n", port, ret);
1864 stinf = (stack_info_t *)&frm->data.p;
1865 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
1867 case ISDN_PID_L0_TE_S0:
1868 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
1870 case ISDN_PID_L0_NT_S0:
1871 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
1874 case ISDN_PID_L0_TE_E1:
1875 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
1878 case ISDN_PID_L0_NT_E1:
1879 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
1884 PERROR("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
1890 if (stinf->pid.protocol[1] == 0)
1892 PERROR("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
1895 if (stinf->pid.protocol[2])
1897 PERROR("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
1903 if (stinf->pid.protocol[1] == 0)
1905 PERROR("Given port %d: Missing layer 1 protocol.\n", port);
1908 if (stinf->pid.protocol[2] == 0)
1910 PERROR("Given port %d: Missing layer 2 protocol.\n", port);
1913 if (stinf->pid.protocol[3] == 0)
1915 PERROR("Given port %d: Missing layer 3 protocol.\n", port);
1919 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
1921 case ISDN_PID_L3_DSS1USER:
1925 PERROR("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
1929 if (stinf->pid.protocol[4])
1931 PERROR("Given port %d: Layer 4 protocol not allowed.\n", port);
1936 /* add mISDNport structure */
1937 mISDNportp = &mISDNport_first;
1939 mISDNportp = &((*mISDNportp)->next);
1940 mISDNport = (struct mISDNport *)calloc(1, sizeof(struct mISDNport));
1943 PERROR("Cannot alloc mISDNport structure\n");
1947 memset(mISDNport, 0, sizeof(mISDNport));
1948 *mISDNportp = mISDNport;
1950 /* allocate ressources of port */
1951 msg_queue_init(&mISDNport->downqueue);
1952 // SCPY(mISDNport->name, "noname");
1953 mISDNport->portnum = port;
1954 mISDNport->ntmode = nt;
1955 mISDNport->pri = pri;
1956 mISDNport->d_stid = stinf->id;
1957 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
1958 mISDNport->b_num = stinf->childcnt;
1959 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
1960 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
1962 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
1963 mISDNport->ptp = ptp = 1;
1966 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
1967 mISDNport->ptp = ptp = 0;
1971 while(i < stinf->childcnt)
1973 mISDNport->b_stid[i] = stinf->child[i];
1974 mISDNport->b_state[i] = B_STATE_IDLE;
1975 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
1978 memset(&li, 0, sizeof(li));
1979 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
1982 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1983 li.pid.layermask = ISDN_LAYER((nt?2:4));
1984 li.st = mISDNport->d_stid;
1985 ret = mISDN_new_layer(mISDNdevice, &li);
1988 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
1990 mISDNport_close(mISDNport);
1993 mISDNport->upper_id = li.id;
1994 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
1997 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
2000 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
2001 if (mISDNport->lower_id < 0)
2003 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
2006 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
2007 if (mISDNport->upper_id < 0)
2009 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
2012 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
2014 /* if ntmode, establish L1 to send the tei removal during start */
2015 if (mISDNport->ntmode)
2019 act.prim = PH_ACTIVATE | REQUEST;
2020 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2021 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2024 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2025 usleep(10000); /* to be sure, that l1 is up */
2028 /* create nst (nt-mode only) */
2031 mgr = &mISDNport->mgr;
2032 nst = &mISDNport->nst;
2037 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2038 nst->device = mISDNdevice;
2040 nst->d_stid = mISDNport->d_stid;
2042 nst->feature = FEATURE_NET_HOLD;
2044 nst->feature |= FEATURE_NET_PTP;
2046 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2049 while(i < mISDNport->b_num)
2051 nst->b_stid[i] = mISDNport->b_stid[i];
2055 nst->l1_id = mISDNport->lower_id;
2056 nst->l2_id = mISDNport->upper_id;
2059 msg_queue_init(&nst->down_queue);
2065 /* if te-mode, query state link */
2066 if (!mISDNport->ntmode)
2070 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2071 act.prim = MGR_SHORTSTATUS | REQUEST;
2072 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2073 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2075 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2077 /* if ptp AND te-mode, pull up the link */
2078 if (mISDNport->ptp && !mISDNport->ntmode)
2082 act.prim = DL_ESTABLISH | REQUEST;
2083 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2086 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2088 /* if ptp AND nt-mode, pull up the link */
2089 if (mISDNport->ptp && mISDNport->ntmode)
2093 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2094 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2097 /* initially, we assume that the link is down, exept for nt-ptmp */
2098 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2100 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2102 start_trace(mISDNport->portnum,
2110 add_trace("channels", NULL, "%d", mISDNport->b_num);
2117 * function to free ALL cards (ports)
2119 void mISDNport_close_all(void)
2121 /* free all ports */
2122 while(mISDNport_first)
2123 mISDNport_close(mISDNport_first);
2127 * free only one port
2129 void mISDNport_close(struct mISDNport *mISDNport)
2131 struct mISDNport **mISDNportp;
2133 class PmISDN *isdnport;
2135 unsigned char buf[32];
2138 /* remove all port instance that are linked to this mISDNport */
2142 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2144 isdnport = (class PmISDN *)port;
2145 if (isdnport->p_m_mISDNport)
2147 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2154 /* only if we are already part of interface */
2155 if (mISDNport->ifport)
2157 start_trace(mISDNport->portnum,
2158 mISDNport->ifport->interface,
2168 /* free bchannels */
2170 while(i < mISDNport->b_num)
2172 if (mISDNport->b_addr[i])
2174 _bchannel_destroy(mISDNport, i);
2175 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2180 /* free ressources of port */
2181 msg_queue_purge(&mISDNport->downqueue);
2184 if (mISDNport->ntmode)
2186 nst = &mISDNport->nst;
2187 if (nst->manager) /* to see if initialized */
2189 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");
2190 cleanup_Isdnl3(nst);
2191 cleanup_Isdnl2(nst);
2194 msg_queue_purge(&nst->down_queue);
2195 if (nst->phd_down_msg)
2196 free(nst->phd_down_msg);
2200 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2201 if (mISDNport->d_stid)
2203 if (mISDNport->upper_id)
2204 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2207 /* remove from list */
2208 mISDNportp = &mISDNport_first;
2211 if (*mISDNportp == mISDNport)
2213 *mISDNportp = (*mISDNportp)->next;
2217 mISDNportp = &((*mISDNportp)->next);
2222 PERROR("software error, mISDNport not in list\n");
2226 memset(mISDNport, 0, sizeof(struct mISDNport));
2230 /* close mISDNdevice, if no port */
2231 if (mISDNdevice>=0 && mISDNport_first==NULL)
2234 mISDN_write_frame(mISDNdevice, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2236 mISDN_close(mISDNdevice);
2238 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
2244 * global function to show all available isdn ports
2246 void mISDN_port_info(void)
2250 int useable, nt, pri;
2251 unsigned char buff[1025];
2252 iframe_t *frm = (iframe_t *)buff;
2253 stack_info_t *stinf;
2257 if ((device = mISDN_open()) < 0)
2259 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));
2263 /* get number of stacks */
2265 ii = mISDN_get_stack_count(device);
2269 printf("Found no card. Please be sure to load card drivers.\n");
2272 /* loop the number of cards and get their info */
2275 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2278 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2281 stinf = (stack_info_t *)&frm->data.p;
2286 /* output the port info */
2287 printf("Port %2d: ", i);
2288 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2290 case ISDN_PID_L0_TE_S0:
2291 printf("TE-mode BRI S/T interface line (for phone lines)");
2293 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2294 printf(" HFC multiport card");
2297 case ISDN_PID_L0_NT_S0:
2299 printf("NT-mode BRI S/T interface port (for phones)");
2301 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2302 printf(" HFC multiport card");
2305 case ISDN_PID_L0_TE_E1:
2307 printf("TE-mode PRI E1 interface line (for phone lines)");
2309 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2310 printf(" HFC-E1 card");
2313 case ISDN_PID_L0_NT_E1:
2316 printf("NT-mode PRI E1 interface port (for phones)");
2318 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2319 printf(" HFC-E1 card");
2324 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2330 if (stinf->pid.protocol[1] == 0)
2333 printf(" -> Missing layer 1 NT-mode protocol.\n");
2336 while(p <= MAX_LAYER_NR) {
2337 if (stinf->pid.protocol[p])
2340 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
2347 printf(" -> Interface is Point-To-Point (PRI).\n");
2349 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2353 if (stinf->pid.protocol[1] == 0)
2356 printf(" -> Missing layer 1 protocol.\n");
2358 if (stinf->pid.protocol[2] == 0)
2361 printf(" -> Missing layer 2 protocol.\n");
2363 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2365 printf(" -> Interface is Poin-To-Point.\n");
2367 if (stinf->pid.protocol[3] == 0)
2370 printf(" -> Missing layer 3 protocol.\n");
2373 printf(" -> Protocol: ");
2374 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2376 case ISDN_PID_L3_DSS1USER:
2377 printf("DSS1 (Euro ISDN)");
2382 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2387 while(p <= MAX_LAYER_NR) {
2388 if (stinf->pid.protocol[p])
2391 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
2396 printf(" - %d B-channels\n", stinf->childcnt);
2399 printf(" * Port NOT useable for PBX\n");
2401 printf("--------\n");
2408 if ((err = mISDN_close(device)))
2410 fprintf(stderr, "mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2417 * enque data from upper buffer
2419 void PmISDN::txfromup(unsigned char *data, int length)
2426 /* get free samples in buffer */
2427 avail = ((p_m_fromup_buffer_readp - p_m_fromup_buffer_writep - 1) & FROMUP_BUFFER_MASK);
2430 PDEBUG(DEBUG_PORT, "Port(%d): fromup_buffer overflows, this shall not happen under normal conditions\n", p_serial);
2434 /* write data to buffer and return */
2437 p_m_fromup_buffer[p_m_fromup_buffer_writep] = *data++;
2438 p_m_fromup_buffer_writep = (p_m_fromup_buffer_writep + 1) & FROMUP_BUFFER_MASK;
2441 return; // must return, because length is 0