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 printf("p%d elapsed=%d\n", p_serial, elapsed);
798 if (elapsed >= ISDN_TRANSMIT)
800 unsigned char buf[mISDN_HEADER_LEN+ISDN_PRELOAD];
801 iframe_t *frm = (iframe_t *)buf;
802 unsigned char *p = buf+mISDN_HEADER_LEN;
804 p_last_tv_sec = now_tv.tv_sec;
805 p_last_tv_msec = now_tv.tv_usec/1000;
807 /* read tones or fill with silence */
808 length = read_audio(p, elapsed);
812 * the fromup_buffer data is written to the beginning of the buffer
813 * the part that is filles with tones (length) is skipped, so tones have priority
814 * the length value is increased by the number of data copied from fromup_buffer
816 printf("p%d inbuffer=%d\n", p_serial, inbuffer);
819 /* inbuffer might be less than we skip due to audio */
820 if (inbuffer <= length)
823 p_m_fromup_buffer_readp = p_m_fromup_buffer_writep;
827 /* skip what we already have with tones */
828 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + length) & FROMUP_BUFFER_MASK;
832 /* if we have more in buffer, than we send this time */
833 if (inbuffer > (elapsed-length))
834 inbuffer = elapsed - length;
835 /* set length to what we actually have */
836 length = length + inbuffer;
837 printf("p%d inbuffer=%d\n", p_serial, inbuffer);
838 /* now fill up with fromup_buffer */
841 *p++ = p_m_fromup_buffer[p_m_fromup_buffer_readp];
842 p_m_fromup_buffer_readp = (p_m_fromup_buffer_readp + 1) & FROMUP_BUFFER_MASK;
846 printf("p%d length=%d\n", p_serial, length);
848 /* overwrite buffer with crypto stuff */
849 if (p_m_crypt_msg_loops)
851 /* send pending message */
854 /* how much do we have to send */
855 tosend = p_m_crypt_msg_len - p_m_crypt_msg_current;
856 if (tosend > elapsed)
859 /* our length increases, if less */
863 /* copy message (part) to buffer */
864 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, tosend);
865 p_m_crypt_msg_current += tosend;
866 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
868 p_m_crypt_msg_current = 0;
869 p_m_crypt_msg_loops--;
872 frm->prim = DL_DATA | REQUEST;
873 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
876 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
878 if (p_debug_nothingtosend)
880 p_debug_nothingtosend = 0;
881 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) start sending, because we have tones and/or remote audio.\n", p_name);
887 if (!p_debug_nothingtosend)
889 p_debug_nothingtosend = 1;
890 PDEBUG((DEBUG_PORT | DEBUG_BCHANNEL), "PmISDN(%s) stop sending, because we have only silence.\n", p_name);
894 // NOTE: deletion is done by the child class
896 /* handle timeouts */
899 if (p_m_timer+p_m_timeout < now_d)
901 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
903 /* send timeout to endpoint */
904 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
905 message->param.state = p_state;
906 message_put(message);
911 return(0); /* nothing done */
916 * whenever we get audio data from bchannel, we process it here
918 void PmISDN::bchannel_receive(iframe_t *frm)
920 unsigned char *data_temp;
921 unsigned long length_temp;
922 struct message *message;
927 if (frm->prim == (PH_CONTROL | INDICATION))
931 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
934 cont = *((unsigned long *)&frm->data.p);
935 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
937 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
938 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
940 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
941 message->param.dtmf = cont & DTMF_TONE_MASK;
942 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
943 message_put(message);
949 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
950 add_trace("DSP-CRYPT", NULL, "error");
952 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
953 message->param.crypt.type = CC_ERROR_IND;
954 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
955 message_put(message);
959 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
960 add_trace("DSP-CRYPT", NULL, "ok");
962 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
963 message->param.crypt.type = CC_ACTBF_CONF;
964 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
965 message_put(message);
971 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
972 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring rx data, because 'txdata' is turned off\n", p_name);
976 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
980 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
981 add_trace("unknown", NULL, "0x%x", cont);
986 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
988 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
992 /* calls will not process any audio data unless
993 * the call is connected OR interface features audio during call setup.
995 //printf("%d -> %d prim=%x calldata=%d tones=%d\n", p_serial, ACTIVE_EPOINT(p_epointlist), frm->prim, p_m_calldata, p_m_mISDNport->earlyb);
996 #warning "disabled for debug"
998 if (p_state!=PORT_STATE_CONNECT
999 && !p_m_mISDNport->earlyb)
1003 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1006 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1012 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1014 /* randomize and listen to crypt message if enabled */
1015 if (p_m_crypt_listen)
1017 /* the noisy randomizer */
1018 p = (unsigned char *)&frm->data.p;
1021 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1023 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1026 p = (unsigned char *)&frm->data.p;
1028 /* send data to epoint */
1029 if (p_m_calldata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1031 length_temp = frm->len;
1035 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1036 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1037 memcpy(message->param.data.data, data_temp, message->param.data.len);
1038 message_put(message);
1039 if (length_temp <= sizeof(message->param.data.data))
1041 data_temp += sizeof(message->param.data.data);
1042 length_temp -= sizeof(message->param.data.data);
1051 void PmISDN::set_echotest(int echo)
1053 if (p_m_echo != echo)
1056 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1058 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1059 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);
1066 void PmISDN::set_tone(char *dir, char *tone)
1072 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1079 /* check if we NOT really have to use a dsp-tone */
1080 if (!options.dsptones)
1084 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1086 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1087 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1090 Port::set_tone(dir, tone);
1096 /* now we USE dsp-tone, convert name */
1097 else if (!strcmp(tone, "dialtone"))
1099 switch(options.dsptones) {
1100 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1101 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1102 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1104 } else if (!strcmp(tone, "dialpbx"))
1106 switch(options.dsptones) {
1107 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1108 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1109 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1111 } else if (!strcmp(tone, "ringing"))
1113 switch(options.dsptones) {
1114 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1115 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1116 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1118 } else if (!strcmp(tone, "ringpbx"))
1120 switch(options.dsptones) {
1121 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1122 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1123 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1125 } else if (!strcmp(tone, "busy"))
1128 switch(options.dsptones) {
1129 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1130 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1131 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1133 } else if (!strcmp(tone, "release"))
1136 switch(options.dsptones) {
1137 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1138 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1139 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1141 } else if (!strcmp(tone, "cause_10"))
1143 else if (!strcmp(tone, "cause_11"))
1145 else if (!strcmp(tone, "cause_22"))
1147 switch(options.dsptones) {
1148 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1149 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1150 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1152 } else if (!strncmp(tone, "cause_", 6))
1153 id = TONE_SPECIAL_INFO;
1157 /* if we have a tone that is not supported by dsp */
1158 if (id==TONE_OFF && tone[0])
1166 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1168 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1169 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);
1171 /* turn user-space tones off in cases of no tone OR dsp tone */
1172 Port::set_tone("",NULL);
1176 /* MESSAGE_mISDNSIGNAL */
1177 //extern struct message *dddebug;
1178 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1180 switch(param->mISDNsignal.message)
1182 case mISDNSIGNAL_VOLUME:
1183 if (p_m_txvol != param->mISDNsignal.txvol)
1185 p_m_txvol = param->mISDNsignal.txvol;
1186 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1188 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1189 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);
1191 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1192 if (p_m_rxvol != param->mISDNsignal.rxvol)
1194 p_m_rxvol = param->mISDNsignal.rxvol;
1195 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1197 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1198 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);
1200 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1203 case mISDNSIGNAL_CONF:
1204 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1205 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1206 if (p_m_conf != param->mISDNsignal.conf)
1208 p_m_conf = param->mISDNsignal.conf;
1209 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1211 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1212 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);
1214 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1215 /* we must set, even if currently tone forbids conf */
1216 p_m_conf = param->mISDNsignal.conf;
1217 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1220 case mISDNSIGNAL_CALLDATA:
1221 if (p_m_calldata != param->mISDNsignal.calldata)
1223 p_m_calldata = param->mISDNsignal.calldata;
1224 PDEBUG(DEBUG_BCHANNEL, "we change to calldata=%d.\n", p_m_calldata);
1226 PDEBUG(DEBUG_BCHANNEL, "we already have calldata=%d.\n", p_m_calldata);
1229 case mISDNSIGNAL_DELAY:
1230 if (p_m_delay != param->mISDNsignal.delay)
1232 p_m_delay = param->mISDNsignal.delay;
1233 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1235 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1236 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);
1238 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1242 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1247 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1249 struct message *message;
1251 switch(param->crypt.type)
1253 case CC_ACTBF_REQ: /* activate blowfish */
1255 p_m_crypt_key_len = param->crypt.len;
1256 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1258 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1259 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1260 message->param.crypt.type = CC_ERROR_IND;
1261 message_put(message);
1264 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1266 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1268 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1269 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);
1272 case CC_DACT_REQ: /* deactivate session encryption */
1277 case CR_LISTEN_REQ: /* start listening to messages */
1278 p_m_crypt_listen = 1;
1279 p_m_crypt_listen_state = 0;
1282 case CR_UNLISTEN_REQ: /* stop listening to messages */
1283 p_m_crypt_listen = 0;
1286 case CR_MESSAGE_REQ: /* send message */
1287 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1288 if (!p_m_crypt_msg_len)
1290 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1293 p_m_crypt_msg_current = 0; /* reset */
1294 p_m_crypt_msg_loops = 3; /* enable */
1296 /* disable txmix, or we get corrupt data due to audio process */
1299 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1300 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1306 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1312 * endpoint sends messages to the port
1314 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1316 if (Port::message_epoint(epoint_id, message_id, param))
1321 case MESSAGE_DATA: /* tx-data from upper layer */
1322 txfromup(param->data.data, param->data.len);
1325 case MESSAGE_mISDNSIGNAL: /* user command */
1326 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1327 message_mISDNsignal(epoint_id, message_id, param);
1330 case MESSAGE_CRYPT: /* crypt control command */
1331 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1332 message_crypt(epoint_id, message_id, param);
1341 * main loop for processing messages from mISDN device
1343 int mISDN_handler(void)
1348 struct mISDNport *mISDNport;
1349 class PmISDN *isdnport;
1352 mISDNuser_head_t *hh;
1355 /* the que avoids loopbacks when replying to stack after receiving
1357 mISDNport = mISDNport_first;
1360 /* process turning on/off rx */
1362 while(i < mISDNport->b_num)
1364 isdnport=mISDNport->b_port[i];
1367 /* call bridges in user space OR crypto OR recording */
1368 if (isdnport->p_m_calldata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1370 /* rx IS required */
1371 if (isdnport->p_m_rxoff)
1374 isdnport->p_m_rxoff = 0;
1375 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1376 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1377 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1382 /* rx NOT required */
1383 if (!isdnport->p_m_rxoff)
1386 isdnport->p_m_rxoff = 1;
1387 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1388 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1389 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1394 if (isdnport->p_record)
1396 /* txdata IS required */
1397 if (!isdnport->p_m_txdata)
1400 isdnport->p_m_txdata = 1;
1401 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1402 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1403 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1408 /* txdata NOT required */
1409 if (isdnport->p_m_txdata)
1412 isdnport->p_m_txdata = 0;
1413 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1414 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1415 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1423 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1425 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1426 mISDNport->l1timeout = 0;
1429 if (mISDNport->l2establish)
1431 if (now-mISDNport->l2establish > 5)
1433 if (mISDNport->ntmode)
1435 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1436 time(&mISDNport->l2establish);
1438 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1439 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1442 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1443 time(&mISDNport->l2establish);
1446 act.prim = DL_ESTABLISH | REQUEST;
1447 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1450 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1452 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1457 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1459 if (mISDNport->ntmode)
1461 hh = (mISDNuser_head_t *)dmsg->data;
1462 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);
1463 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1467 frm = (iframe_t *)dmsg->data;
1468 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1469 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1470 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);
1471 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1476 mISDNport = mISDNport->next;
1479 /* no device, no read */
1480 if (mISDNdevice < 0)
1483 /* get message from kernel */
1484 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1486 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1490 if (errno == EAGAIN)
1492 PERROR("FATAL ERROR: failed to do mISDN_read()\n");
1498 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1502 frm = (iframe_t *)msg->data;
1507 case MGR_DELLAYER | CONFIRM:
1508 case MGR_INITTIMER | CONFIRM:
1509 case MGR_ADDTIMER | CONFIRM:
1510 case MGR_DELTIMER | CONFIRM:
1511 case MGR_REMOVETIMER | CONFIRM:
1516 /* handle timer events from mISDN for NT-stack
1517 * note: they do not associate with a stack */
1518 if (frm->prim == (MGR_TIMER | INDICATION))
1522 /* find mISDNport */
1523 mISDNport = mISDNport_first;
1527 if (mISDNport->ntmode)
1529 it = mISDNport->nst.tlist;
1533 if (it->id == (int)frm->addr)
1540 mISDNport = mISDNport->next;
1544 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1545 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1547 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
1548 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1549 ret = it->function(it->data);
1552 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
1557 /* find the mISDNport that belongs to the stack */
1558 mISDNport = mISDNport_first;
1561 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
1563 mISDNport = mISDNport->next;
1567 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1572 if (!(frm->addr&FLG_CHILD_STACK))
1577 case MGR_SHORTSTATUS | INDICATION:
1578 case MGR_SHORTSTATUS | CONFIRM:
1579 switch(frm->dinfo) {
1580 case SSTATUS_L1_ACTIVATED:
1581 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1584 case SSTATUS_L1_DEACTIVATED:
1585 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1588 case SSTATUS_L2_ESTABLISHED:
1589 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1592 case SSTATUS_L2_RELEASED:
1593 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1599 case PH_ACTIVATE | CONFIRM:
1600 case PH_ACTIVATE | INDICATION:
1601 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1603 if (mISDNport->ntmode)
1605 mISDNport->l1link = 1;
1606 setup_queue(mISDNport, 1);
1610 mISDNport->l1link = 1;
1611 setup_queue(mISDNport, 1);
1614 case PH_DEACTIVATE | CONFIRM:
1615 case PH_DEACTIVATE | INDICATION:
1616 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1618 if (mISDNport->ntmode)
1620 mISDNport->l1link = 0;
1621 setup_queue(mISDNport, 0);
1625 mISDNport->l1link = 0;
1626 setup_queue(mISDNport, 0);
1629 case PH_CONTROL | CONFIRM:
1630 case PH_CONTROL | INDICATION:
1631 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1634 case DL_ESTABLISH | INDICATION:
1635 case DL_ESTABLISH | CONFIRM:
1636 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1638 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1640 if (mISDNport->l2establish)
1642 mISDNport->l2establish = 0;
1643 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1645 mISDNport->l2link = 1;
1648 case DL_RELEASE | INDICATION:
1649 case DL_RELEASE | CONFIRM:
1650 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1652 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1654 mISDNport->l2link = 0;
1657 time(&mISDNport->l2establish);
1658 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
1664 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);
1665 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
1667 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
1670 if (mISDNport->ntmode)
1672 /* l1-data enters the nt-mode library */
1673 nst = &mISDNport->nst;
1674 if (nst->l1_l2(nst, msg))
1679 /* l3-data is sent to pbx */
1680 if (stack2manager_te(mISDNport, msg))
1691 /* we don't care about confirms, we use rx data to sync tx */
1692 case PH_DATA | CONFIRM:
1693 case DL_DATA | CONFIRM:
1696 /* we receive audio data, we respond to it AND we send tones */
1697 case PH_DATA | INDICATION:
1698 case DL_DATA | INDICATION:
1699 case PH_CONTROL | INDICATION:
1701 while(i < mISDNport->b_num)
1703 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1707 if (i == mISDNport->b_num)
1709 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1712 if (mISDNport->b_port[i])
1714 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
1715 mISDNport->b_port[i]->bchannel_receive(frm);
1717 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
1720 case PH_ACTIVATE | INDICATION:
1721 case DL_ESTABLISH | INDICATION:
1722 case PH_ACTIVATE | CONFIRM:
1723 case DL_ESTABLISH | CONFIRM:
1724 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
1726 while(i < mISDNport->b_num)
1728 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1732 if (i == mISDNport->b_num)
1734 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1737 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1740 case PH_DEACTIVATE | INDICATION:
1741 case DL_RELEASE | INDICATION:
1742 case PH_DEACTIVATE | CONFIRM:
1743 case DL_RELEASE | CONFIRM:
1744 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
1746 while(i < mISDNport->b_num)
1748 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1752 if (i == mISDNport->b_num)
1754 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1757 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1761 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1772 * global function to add a new card (port)
1774 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
1777 unsigned char buff[1025];
1778 iframe_t *frm = (iframe_t *)buff;
1779 stack_info_t *stinf;
1780 struct mISDNport *mISDNport, **mISDNportp;
1782 // interface_info_t ii;
1789 /* open mISDNdevice if not already open */
1790 if (mISDNdevice < 0)
1795 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));
1799 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
1801 /* create entity for layer 3 TE-mode */
1802 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1803 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
1804 if (ret < (int)mISDN_HEADER_LEN)
1807 fprintf(stderr, "cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
1810 entity = frm->dinfo & 0xffff;
1813 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
1816 /* query port's requirements */
1817 cnt = mISDN_get_stack_count(mISDNdevice);
1820 PERROR("Found no card. Please be sure to load card drivers.\n");
1823 if (port>cnt || port<1)
1825 PERROR("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
1828 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
1831 PERROR("Cannot get stack info for port %d (ret=%d)\n", port, ret);
1834 stinf = (stack_info_t *)&frm->data.p;
1835 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
1837 case ISDN_PID_L0_TE_S0:
1838 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
1840 case ISDN_PID_L0_NT_S0:
1841 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
1844 case ISDN_PID_L0_TE_E1:
1845 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
1848 case ISDN_PID_L0_NT_E1:
1849 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
1854 PERROR("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
1860 if (stinf->pid.protocol[1] == 0)
1862 PERROR("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
1865 if (stinf->pid.protocol[2])
1867 PERROR("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
1873 if (stinf->pid.protocol[1] == 0)
1875 PERROR("Given port %d: Missing layer 1 protocol.\n", port);
1878 if (stinf->pid.protocol[2] == 0)
1880 PERROR("Given port %d: Missing layer 2 protocol.\n", port);
1883 if (stinf->pid.protocol[3] == 0)
1885 PERROR("Given port %d: Missing layer 3 protocol.\n", port);
1889 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
1891 case ISDN_PID_L3_DSS1USER:
1895 PERROR("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
1899 if (stinf->pid.protocol[4])
1901 PERROR("Given port %d: Layer 4 protocol not allowed.\n", port);
1906 /* add mISDNport structure */
1907 mISDNportp = &mISDNport_first;
1909 mISDNportp = &((*mISDNportp)->next);
1910 mISDNport = (struct mISDNport *)calloc(1, sizeof(struct mISDNport));
1913 PERROR("Cannot alloc mISDNport structure\n");
1917 memset(mISDNport, 0, sizeof(mISDNport));
1918 *mISDNportp = mISDNport;
1920 /* allocate ressources of port */
1921 msg_queue_init(&mISDNport->downqueue);
1922 // SCPY(mISDNport->name, "noname");
1923 mISDNport->portnum = port;
1924 mISDNport->ntmode = nt;
1925 mISDNport->pri = pri;
1926 mISDNport->d_stid = stinf->id;
1927 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
1928 mISDNport->b_num = stinf->childcnt;
1929 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
1930 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
1932 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
1933 mISDNport->ptp = ptp = 1;
1936 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
1937 mISDNport->ptp = ptp = 0;
1941 while(i < stinf->childcnt)
1943 mISDNport->b_stid[i] = stinf->child[i];
1944 mISDNport->b_state[i] = B_STATE_IDLE;
1945 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
1948 memset(&li, 0, sizeof(li));
1949 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
1952 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1953 li.pid.layermask = ISDN_LAYER((nt?2:4));
1954 li.st = mISDNport->d_stid;
1955 ret = mISDN_new_layer(mISDNdevice, &li);
1958 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
1960 mISDNport_close(mISDNport);
1963 mISDNport->upper_id = li.id;
1964 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
1967 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
1970 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
1971 if (mISDNport->lower_id < 0)
1973 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
1976 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
1977 if (mISDNport->upper_id < 0)
1979 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
1982 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
1984 /* if ntmode, establish L1 to send the tei removal during start */
1985 if (mISDNport->ntmode)
1989 act.prim = PH_ACTIVATE | REQUEST;
1990 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
1991 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
1994 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1995 usleep(10000); /* to be sure, that l1 is up */
1998 /* create nst (nt-mode only) */
2001 mgr = &mISDNport->mgr;
2002 nst = &mISDNport->nst;
2007 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
2008 nst->device = mISDNdevice;
2010 nst->d_stid = mISDNport->d_stid;
2012 nst->feature = FEATURE_NET_HOLD;
2014 nst->feature |= FEATURE_NET_PTP;
2016 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2019 while(i < mISDNport->b_num)
2021 nst->b_stid[i] = mISDNport->b_stid[i];
2025 nst->l1_id = mISDNport->lower_id;
2026 nst->l2_id = mISDNport->upper_id;
2029 msg_queue_init(&nst->down_queue);
2035 /* if te-mode, query state link */
2036 if (!mISDNport->ntmode)
2040 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2041 act.prim = MGR_SHORTSTATUS | REQUEST;
2042 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2043 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2045 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2047 /* if ptp AND te-mode, pull up the link */
2048 if (mISDNport->ptp && !mISDNport->ntmode)
2052 act.prim = DL_ESTABLISH | REQUEST;
2053 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2056 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2058 /* if ptp AND nt-mode, pull up the link */
2059 if (mISDNport->ptp && mISDNport->ntmode)
2063 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2064 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2067 /* initially, we assume that the link is down, exept for nt-ptmp */
2068 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2070 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2072 start_trace(mISDNport->portnum,
2080 add_trace("channels", NULL, "%d", mISDNport->b_num);
2087 * function to free ALL cards (ports)
2089 void mISDNport_close_all(void)
2091 /* free all ports */
2092 while(mISDNport_first)
2093 mISDNport_close(mISDNport_first);
2097 * free only one port
2099 void mISDNport_close(struct mISDNport *mISDNport)
2101 struct mISDNport **mISDNportp;
2103 class PmISDN *isdnport;
2105 unsigned char buf[32];
2108 /* remove all port instance that are linked to this mISDNport */
2112 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2114 isdnport = (class PmISDN *)port;
2115 if (isdnport->p_m_mISDNport)
2117 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2124 /* only if we are already part of interface */
2125 if (mISDNport->ifport)
2127 start_trace(mISDNport->portnum,
2128 mISDNport->ifport->interface,
2138 /* free bchannels */
2140 while(i < mISDNport->b_num)
2142 if (mISDNport->b_addr[i])
2144 _bchannel_destroy(mISDNport, i);
2145 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2150 /* free ressources of port */
2151 msg_queue_purge(&mISDNport->downqueue);
2154 if (mISDNport->ntmode)
2156 nst = &mISDNport->nst;
2157 if (nst->manager) /* to see if initialized */
2159 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");
2160 cleanup_Isdnl3(nst);
2161 cleanup_Isdnl2(nst);
2164 msg_queue_purge(&nst->down_queue);
2165 if (nst->phd_down_msg)
2166 free(nst->phd_down_msg);
2170 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2171 if (mISDNport->d_stid)
2173 if (mISDNport->upper_id)
2174 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2177 /* remove from list */
2178 mISDNportp = &mISDNport_first;
2181 if (*mISDNportp == mISDNport)
2183 *mISDNportp = (*mISDNportp)->next;
2187 mISDNportp = &((*mISDNportp)->next);
2192 PERROR("software error, mISDNport not in list\n");
2196 memset(mISDNport, 0, sizeof(struct mISDNport));
2200 /* close mISDNdevice, if no port */
2201 if (mISDNdevice>=0 && mISDNport_first==NULL)
2204 mISDN_write_frame(mISDNdevice, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2206 mISDN_close(mISDNdevice);
2208 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
2214 * global function to show all available isdn ports
2216 void mISDN_port_info(void)
2220 int useable, nt, pri;
2221 unsigned char buff[1025];
2222 iframe_t *frm = (iframe_t *)buff;
2223 stack_info_t *stinf;
2227 if ((device = mISDN_open()) < 0)
2229 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));
2233 /* get number of stacks */
2235 ii = mISDN_get_stack_count(device);
2239 printf("Found no card. Please be sure to load card drivers.\n");
2242 /* loop the number of cards and get their info */
2245 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2248 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2251 stinf = (stack_info_t *)&frm->data.p;
2256 /* output the port info */
2257 printf("Port %2d: ", i);
2258 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2260 case ISDN_PID_L0_TE_S0:
2261 printf("TE-mode BRI S/T interface line (for phone lines)");
2263 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2264 printf(" HFC multiport card");
2267 case ISDN_PID_L0_NT_S0:
2269 printf("NT-mode BRI S/T interface port (for phones)");
2271 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2272 printf(" HFC multiport card");
2275 case ISDN_PID_L0_TE_E1:
2277 printf("TE-mode PRI E1 interface line (for phone lines)");
2279 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2280 printf(" HFC-E1 card");
2283 case ISDN_PID_L0_NT_E1:
2286 printf("NT-mode PRI E1 interface port (for phones)");
2288 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2289 printf(" HFC-E1 card");
2294 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2300 if (stinf->pid.protocol[1] == 0)
2303 printf(" -> Missing layer 1 NT-mode protocol.\n");
2306 while(p <= MAX_LAYER_NR) {
2307 if (stinf->pid.protocol[p])
2310 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
2317 printf(" -> Interface is Point-To-Point (PRI).\n");
2319 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2323 if (stinf->pid.protocol[1] == 0)
2326 printf(" -> Missing layer 1 protocol.\n");
2328 if (stinf->pid.protocol[2] == 0)
2331 printf(" -> Missing layer 2 protocol.\n");
2333 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2335 printf(" -> Interface is Poin-To-Point.\n");
2337 if (stinf->pid.protocol[3] == 0)
2340 printf(" -> Missing layer 3 protocol.\n");
2343 printf(" -> Protocol: ");
2344 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2346 case ISDN_PID_L3_DSS1USER:
2347 printf("DSS1 (Euro ISDN)");
2352 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2357 while(p <= MAX_LAYER_NR) {
2358 if (stinf->pid.protocol[p])
2361 printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
2366 printf(" - %d B-channels\n", stinf->childcnt);
2369 printf(" * Port NOT useable for PBX\n");
2371 printf("--------\n");
2378 if ((err = mISDN_close(device)))
2380 fprintf(stderr, "mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2387 * enque data from upper buffer
2389 void PmISDN::txfromup(unsigned char *data, int length)
2396 /* get free samples in buffer */
2397 avail = ((p_m_fromup_buffer_readp - p_m_fromup_buffer_writep - 1) & FROMUP_BUFFER_MASK);
2400 PDEBUG(DEBUG_PORT, "Port(%d): fromup_buffer overflows, this shall not happen under normal conditions\n", p_serial);
2404 /* write data to buffer and return */
2407 p_m_fromup_buffer[p_m_fromup_buffer_writep] = *data++;
2408 p_m_fromup_buffer_writep = (p_m_fromup_buffer_writep + 1) & FROMUP_BUFFER_MASK;
2411 return; // must return, because length is 0