1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 and sip **
10 \*****************************************************************************/
20 #include <sys/ioctl.h>
21 #include <sys/types.h>
29 #ifndef ISDN_PID_L2_B_USER
30 #define ISDN_PID_L2_B_USER 0x420000ff
32 #ifndef ISDN_PID_L3_B_USER
33 #define ISDN_PID_L3_B_USER 0x430000ff
36 #ifndef ISDN_PID_L4_B_USER
37 #define ISDN_PID_L4_B_USER 0x440000ff
40 /* used for udevice */
43 /* noise randomizer */
44 unsigned char mISDN_rand[256];
45 int mISDN_rand_count = 0;
47 /* the device handler and port list */
50 /* list of mISDN ports */
51 struct mISDNport *mISDNport_first;
56 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive) : Port(type, portname, settings)
58 p_m_mISDNport = mISDNport;
59 p_m_portnum = mISDNport->portnum;
66 p_m_txvol = p_m_rxvol = 0;
74 p_m_dtmf = !mISDNport->ifport->nodtmf;
85 p_m_crypt_msg_loops = 0;
86 p_m_crypt_msg_loops = 0;
87 p_m_crypt_msg_len = 0;
88 p_m_crypt_msg[0] = '\0';
89 p_m_crypt_msg_current = 0;
90 p_m_crypt_key[0] = '\0';
91 p_m_crypt_key_len = 0;
93 p_m_crypt_listen_state = 0;
94 p_m_crypt_listen_len = 0;
95 p_m_crypt_listen_msg[0] = '\0';
96 p_m_crypt_listen_crc = 0;
98 /* if any channel requested by constructor */
99 if (channel == CHANNEL_ANY)
101 /* reserve channel */
103 mISDNport->b_reserved++;
106 /* reserve channel */
107 if (channel > 0) // only if constructor was called with a channel resevation
108 seize_bchannel(channel, exclusive);
110 /* we increase the number of objects: */
112 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
121 struct message *message;
123 /* remove bchannel relation */
129 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
130 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
131 message->param.disconnectinfo.cause = 16;
132 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
133 message_put(message);
134 /* remove from list */
135 free_epointlist(p_epointlist);
138 /* we decrease the number of objects: */
139 p_m_mISDNport->use--;
140 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
147 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction)
149 /* init trace with given values */
150 start_trace(mISDNport?mISDNport->portnum:0,
151 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
152 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
153 port?port->p_dialinginfo.id:NULL,
156 port?port->p_serial:0,
164 static struct isdn_message {
168 {"TIMEOUT", CC_TIMEOUT},
170 {"SETUP_ACK", CC_SETUP_ACKNOWLEDGE},
171 {"PROCEEDING", CC_PROCEEDING},
172 {"ALERTING", CC_ALERTING},
173 {"CONNECT", CC_CONNECT},
174 {"CONNECT RES", CC_CONNECT},
175 {"CONNECT_ACK", CC_CONNECT_ACKNOWLEDGE},
176 {"DISCONNECT", CC_DISCONNECT},
177 {"RELEASE", CC_RELEASE},
178 {"RELEASE_COMP", CC_RELEASE_COMPLETE},
179 {"INFORMATION", CC_INFORMATION},
180 {"PROGRESS", CC_PROGRESS},
181 {"NOTIFY", CC_NOTIFY},
182 {"SUSPEND", CC_SUSPEND},
183 {"SUSPEND_ACK", CC_SUSPEND_ACKNOWLEDGE},
184 {"SUSPEND_REJ", CC_SUSPEND_REJECT},
185 {"RESUME", CC_RESUME},
186 {"RESUME_ACK", CC_RESUME_ACKNOWLEDGE},
187 {"RESUME_REJ", CC_RESUME_REJECT},
189 {"HOLD_ACK", CC_HOLD_ACKNOWLEDGE},
190 {"HOLD_REJ", CC_HOLD_REJECT},
191 {"RETRIEVE", CC_RETRIEVE},
192 {"RETRIEVE_ACK", CC_RETRIEVE_ACKNOWLEDGE},
193 {"RETRIEVE_REJ", CC_RETRIEVE_REJECT},
194 {"FACILITY", CC_FACILITY},
195 {"STATUS", CC_STATUS},
196 {"RESTART", CC_RESTART},
197 {"RELEASE_CR", CC_RELEASE_CR},
198 {"NEW_CR", CC_NEW_CR},
199 {"DL_ESTABLISH", DL_ESTABLISH},
200 {"DL_RELEASE", DL_RELEASE},
201 {"PH_ACTIVATE", PH_ACTIVATE},
202 {"PH_DEACTIVATE", PH_DEACTIVATE},
206 static char *isdn_prim[4] = {
212 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction)
215 char msgtext[64] = "<<UNKNOWN MESSAGE>>";
217 /* select message and primitive text */
219 while(isdn_message[i].name)
221 if (isdn_message[i].value == (prim&0xffffff00))
223 SCPY(msgtext, isdn_message[i].name);
228 SCAT(msgtext, isdn_prim[prim&0x00000003]);
231 if (direction && (prim&0xffffff00)!=CC_NEW_CR && (prim&0xffffff00)!=CC_RELEASE_CR)
235 if (mISDNport->ntmode)
237 if (direction == DIRECTION_OUT)
238 SCAT(msgtext, " N->U");
240 SCAT(msgtext, " N<-U");
243 if (direction == DIRECTION_OUT)
244 SCAT(msgtext, " U->N");
246 SCAT(msgtext, " U<-N");
251 /* init trace with given values */
252 start_trace(mISDNport?mISDNport->portnum:0,
253 mISDNport?mISDNport->ifport->interface:NULL,
254 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype):NULL,
255 port?port->p_dialinginfo.id:NULL,
258 port?port->p_serial:0,
264 * send control information to the channel (dsp-module)
266 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long b_addr, int c1, int c2, char *trace_name, int trace_value)
268 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
269 iframe_t *ctrl = (iframe_t *)buffer;
270 unsigned long *d = (unsigned long *)&ctrl->data.p;
272 ctrl->prim = PH_CONTROL | REQUEST;
273 ctrl->addr = b_addr | FLG_MSG_DOWN;
275 ctrl->len = sizeof(int)*2;
278 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
279 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
280 if (c1 == CMX_CONF_JOIN)
281 add_trace(trace_name, NULL, "0x%08x", trace_value);
283 add_trace(trace_name, NULL, "%d", trace_value);
287 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)
289 unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
290 iframe_t *ctrl = (iframe_t *)buffer;
291 unsigned long *d = (unsigned long *)&ctrl->data.p;
293 ctrl->prim = PH_CONTROL | REQUEST;
294 ctrl->addr = b_addr | FLG_MSG_DOWN;
296 ctrl->len = sizeof(int)+c2_len;
298 memcpy(d, c2, c2_len);
299 mISDN_write(mISDNdevice, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
300 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
301 add_trace(trace_name, NULL, "%d", trace_value);
307 * subfunction for bchannel_event
310 static int _bchannel_create(struct mISDNport *mISDNport, int i)
312 unsigned char buff[1024];
317 if (!mISDNport->b_stid[i])
319 PERROR("Error: no stack for index %d\n", i);
322 if (mISDNport->b_addr[i])
324 PERROR("Error: stack already created for index %d\n", i);
328 /* create new layer */
329 PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel %d (index %d).\n" , i+1+(i>=15), i);
330 memset(&li, 0, sizeof(li));
331 memset(&pid, 0, sizeof(pid));
334 li.st = mISDNport->b_stid[i];
335 UCPY(li.name, "B L4");
336 li.pid.layermask = ISDN_LAYER((4));
337 li.pid.protocol[4] = ISDN_PID_L4_B_USER;
338 ret = mISDN_new_layer(mISDNdevice, &li);
342 PERROR("mISDN_new_layer() failed to add bchannel %d (index %d)\n", i+1+(i>=15), i);
345 mISDNport->b_addr[i] = li.id;
348 goto failed_new_layer;
350 PDEBUG(DEBUG_BCHANNEL, "new layer (b_addr=0x%x)\n", mISDNport->b_addr[i]);
352 /* create new stack */
353 pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
354 pid.protocol[2] = ISDN_PID_L2_B_TRANS;
355 pid.protocol[3] = ISDN_PID_L3_B_DSP;
356 pid.protocol[4] = ISDN_PID_L4_B_USER;
357 pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
358 ret = mISDN_set_stack(mISDNdevice, mISDNport->b_stid[i], &pid);
362 PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel (index %d) stid=0x%x\n", ret, i, mISDNport->b_stid[i]);
363 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i], MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
366 ret = mISDN_get_setstack_ind(mISDNdevice, mISDNport->b_addr[i]);
371 mISDNport->b_addr[i] = mISDN_get_layerid(mISDNdevice, mISDNport->b_stid[i], 4);
372 if (!mISDNport->b_addr[i])
374 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
375 add_trace("channel", NULL, "%d", i+1+(i>=15));
376 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
377 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
383 mISDNport->b_addr[i] = 0;
389 * subfunction for bchannel_event
392 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
396 /* activate bchannel */
397 chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
398 add_trace("channel", NULL, "%d", i+1+(i>=15));
400 act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
401 act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
404 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
409 * subfunction for bchannel_event
412 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
417 port = mISDNport->b_port[i];
418 addr = mISDNport->b_addr[i];
421 PERROR("bchannel index i=%d not associated with a port object\n", i);
425 /* set dsp features */
426 if (port->p_m_txdata)
427 ph_control(mISDNport, port, addr, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
429 ph_control(mISDNport, port, addr, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
431 ph_control(mISDNport, port, addr, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
433 ph_control(mISDNport, port, addr, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
435 ph_control(mISDNport, port, addr, CMX_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
437 ph_control(mISDNport, port, addr, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
439 ph_control(mISDNport, port, addr, TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
441 ph_control(mISDNport, port, addr, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
442 // if (port->p_m_txmix)
443 // ph_control(mISDNport, port, addr, CMX_MIX_ON, 0, "DSP-MIX", 1);
445 ph_control(mISDNport, port, addr, DTMF_TONE_START, 0, "DSP-DTMF", 1);
447 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);
451 * subfunction for bchannel_event
454 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
456 unsigned char buff[1024];
458 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
459 add_trace("channel", NULL, "%d", i+1+(i>=15));
460 add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
461 add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
463 /* remove our stack only if set */
464 if (mISDNport->b_addr[i])
466 PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
467 mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
468 mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
469 mISDNport->b_addr[i] = 0;
478 A bchannel goes through the following states in this order:
481 No one is using the bchannel.
482 It is available and not linked to Port class, nor reserved.
485 The bchannel stack is created and an activation request is sent.
486 It MAY be linked to Port class, but already unlinked due to Port class removal.
489 The bchannel is active and cofigured to the Port class needs.
490 Also it is linked to a Port class, otherwhise it would be deactivated.
492 - B_STATE_DEACTIVATING
493 The bchannel is in deactivating state, due to deactivation request.
494 It may be linked to a Port class, that likes to reactivate it.
498 After deactivating bchannel, and if not used, the bchannel becomes idle again.
501 A bchannel can have the following events:
504 A bchannel is required by a Port class.
507 The bchannel beomes active.
510 The bchannel is not required by Port class anymore
512 - B_EVENT_DEACTIVATED
513 The bchannel becomes inactive.
515 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
520 * process bchannel events
521 * - mISDNport is a pointer to the port's structure
522 * - i is the index of the bchannel
523 * - event is the B_EVENT_* value
524 * - port is the PmISDN class pointer
526 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
528 int state = mISDNport->b_state[i];
532 case B_EVENT_ACTIVATE:
533 /* port must be linked in order to allow activation */
534 if (!mISDNport->b_port[i])
535 FATAL("bchannel must be linked to a Port class\n");
539 /* create stack and send activation request */
540 if (_bchannel_create(mISDNport, i))
542 _bchannel_activate(mISDNport, i, 1);
543 state = B_STATE_ACTIVATING;
547 case B_STATE_ACTIVATING:
548 /* do nothing, because it is already activating */
551 case B_STATE_DEACTIVATING:
552 /* do nothing, because we must wait until we can reactivate */
556 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
560 case B_EVENT_ACTIVATED:
563 case B_STATE_ACTIVATING:
564 if (mISDNport->b_port[i])
566 /* bchannel is active and used by Port class, so we configure bchannel */
567 _bchannel_configure(mISDNport, i);
568 state = B_STATE_ACTIVE;
571 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
572 _bchannel_activate(mISDNport, i, 0);
573 state = B_STATE_DEACTIVATING;
578 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
582 case B_EVENT_DEACTIVATE:
583 if (!mISDNport->b_port[i])
584 FATAL("bchannel must be linked to a Port class\n");
588 /* bchannel is idle due to an error, so we do nothing */
591 case B_STATE_ACTIVATING:
592 /* do nothing because we must wait until bchanenl is active before deactivating */
596 /* bchannel is active, so we deactivate */
597 _bchannel_activate(mISDNport, i, 0);
598 state = B_STATE_DEACTIVATING;
601 case B_STATE_DEACTIVATING:
602 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
606 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
610 case B_EVENT_DEACTIVATED:
614 /* ignore due to deactivation confirm after unloading */
617 case B_STATE_DEACTIVATING:
618 _bchannel_destroy(mISDNport, i);
619 state = B_STATE_IDLE;
620 if (mISDNport->b_port[i])
622 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
623 if (_bchannel_create(mISDNport, i))
625 _bchannel_activate(mISDNport, i, 1);
626 state = B_STATE_ACTIVATING;
632 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
637 PERROR("Illegal event %d, please correct.\n", event);
640 mISDNport->b_state[i] = state;
647 * check for available channel and reserve+set it.
648 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
650 * returns -(cause value) or x = channel x or 0 = no channel
651 * NOTE: no activation is done here
653 int PmISDN::seize_bchannel(int channel, int exclusive)
657 /* the channel is what we have */
658 if (p_m_b_channel == channel)
661 /* if channel already in use, release it */
666 if (channel==CHANNEL_NO || channel==0)
669 /* is channel in range ? */
671 || (channel>p_m_mISDNport->b_num && channel<16)
672 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
673 return(-6); /* channel unacceptable */
675 /* request exclusive channel */
676 if (exclusive && channel>0)
678 i = channel-1-(channel>16);
679 if (p_m_mISDNport->b_port[i])
680 return(-44); /* requested channel not available */
684 /* ask for channel */
687 i = channel-1-(channel>16);
688 if (p_m_mISDNport->b_port[i] == NULL)
692 /* search for channel */
694 while(i < p_m_mISDNport->b_num)
696 if (!p_m_mISDNport->b_port[i])
698 channel = i+1+(i>=15);
703 return(-34); /* no free channel */
706 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
709 p_m_mISDNport->b_port[i] = this;
711 p_m_b_channel = channel;
712 p_m_b_exclusive = exclusive;
714 /* reserve channel */
718 p_m_mISDNport->b_reserved++;
725 * drop reserved channel and unset it.
726 * deactivation is also done
728 void PmISDN::drop_bchannel(void)
733 /* unreserve channel */
735 p_m_mISDNport->b_reserved--;
742 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
744 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
745 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DEACTIVATE);
746 p_m_mISDNport->b_port[p_m_b_index] = NULL;
756 audio transmission procedure:
757 -----------------------------
760 three sources of audio transmission:
761 - crypto-data high priority
762 - tones high priority (also high)
763 - remote-data low priority
766 a variable that temporarily shows the number of samples elapsed since last transmission process.
767 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
770 a variable that is increased whenever data is transmitted.
771 it is decreased while time elapses. it stores the number of samples that
772 are currently loaded to dsp module.
773 since clock in dsp module is the same clock for user space process, these
777 there are two levels:
778 ISDN_LOAD will give the load that have to be kept in dsp.
779 ISDN_MAXLOAD will give the maximum load before dropping.
781 * procedure for low priority data
782 see txfromup() for procedure
783 in short: remote data is ignored during high priority tones
785 * procedure for high priority data
786 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
787 if no more data is available, load becomes empty again.
790 0 ISDN_LOAD ISDN_MAXLOAD
791 +--------------------+----------------------+
793 +--------------------+----------------------+
795 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
796 0 ISDN_LOAD ISDN_MAXLOAD
797 +--------------------+----------------------+
798 |TTTTTTTTTTTTTTTTTTTT| |
799 +--------------------+----------------------+
801 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
802 0 ISDN_LOAD ISDN_MAXLOAD
803 +--------------------+----------------------+
804 |TTTTTTTTTTTTTTTTTTTTRRRRR |
805 +--------------------+----------------------+
808 int PmISDN::handler(void)
810 struct message *message;
814 if ((ret = Port::handler()))
820 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
821 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
824 /* set clock of first process ever in this instance */
825 p_m_last_tv_sec = now_tv.tv_sec;
826 p_m_last_tv_msec = now_tv.tv_usec/1000;
828 /* process only if we have a minimum of samples, to make packets not too small */
829 if (elapsed >= ISDN_TRANSMIT)
831 /* set clock of last process! */
832 p_m_last_tv_sec = now_tv.tv_sec;
833 p_m_last_tv_msec = now_tv.tv_usec/1000;
836 if (elapsed < p_m_load)
841 /* to send data, tone must be active OR crypt messages must be on */
842 if ((p_tone_name[0] || p_m_crypt_msg_loops) && p_m_load < ISDN_LOAD)
844 int tosend = ISDN_LOAD - p_m_load, length;
845 unsigned char buf[mISDN_HEADER_LEN+tosend];
846 iframe_t *frm = (iframe_t *)buf;
847 unsigned char *p = buf+mISDN_HEADER_LEN;
849 /* copy crypto loops */
850 while (p_m_crypt_msg_loops && tosend)
852 /* how much do we have to send */
853 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
859 /* copy message (part) to buffer */
860 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
863 p_m_crypt_msg_current += length;
864 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
867 p_m_crypt_msg_current = 0;
868 p_m_crypt_msg_loops--;
876 if (p_tone_name[0] && tosend)
878 tosend -= read_audio(p, tosend);
882 frm->prim = DL_DATA | REQUEST;
883 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
885 frm->len = ISDN_LOAD - p_m_load - tosend;
887 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
888 p_m_load += frm->len;
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;
925 if (frm->prim == (PH_CONTROL | INDICATION))
929 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
932 cont = *((unsigned long *)&frm->data.p);
933 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
935 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
936 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
938 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
939 message->param.dtmf = cont & DTMF_TONE_MASK;
940 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
941 message_put(message);
947 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
948 add_trace("DSP-CRYPT", NULL, "error");
950 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
951 message->param.crypt.type = CC_ERROR_IND;
952 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
953 message_put(message);
957 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
958 add_trace("DSP-CRYPT", NULL, "ok");
960 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
961 message->param.crypt.type = CC_ACTBF_CONF;
962 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
963 message_put(message);
969 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
970 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
974 record((unsigned char *)(cont+1), frm->len - 4, 1); // from up
978 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
979 add_trace("unknown", NULL, "0x%x", cont);
984 if (frm->prim != (PH_DATA | INDICATION) && frm->prim != (DL_DATA | INDICATION))
986 PERROR("Bchannel received unknown primitve: 0x%x\n", frm->prim);
990 /* calls will not process any audio data unless
991 * the call is connected OR interface features audio during call setup.
993 //printf("%d -> %d prim=%x joindata=%d tones=%d\n", p_serial, ACTIVE_EPOINT(p_epointlist), frm->prim, p_m_joindata, p_m_mISDNport->earlyb);
994 #ifndef DEBUG_COREBRIDGE
995 if (p_state!=PORT_STATE_CONNECT
996 && !p_m_mISDNport->earlyb)
1000 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1003 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1009 record((unsigned char *)&frm->data.p, frm->len, 0); // from down
1011 /* randomize and listen to crypt message if enabled */
1012 if (p_m_crypt_listen)
1014 /* the noisy randomizer */
1015 p = (unsigned char *)&frm->data.p;
1018 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1020 cryptman_listen_bch((unsigned char *)&frm->data.p, frm->len);
1023 p = (unsigned char *)&frm->data.p;
1025 /* send data to epoint */
1026 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1028 length_temp = frm->len;
1032 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1033 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1034 memcpy(message->param.data.data, data_temp, message->param.data.len);
1035 message_put(message);
1036 if (length_temp <= sizeof(message->param.data.data))
1038 data_temp += sizeof(message->param.data.data);
1039 length_temp -= sizeof(message->param.data.data);
1048 void PmISDN::set_echotest(int echo)
1050 if (p_m_echo != echo)
1053 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1055 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1056 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);
1063 void PmISDN::set_tone(char *dir, char *tone)
1069 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1076 /* check if we NOT really have to use a dsp-tone */
1077 if (!options.dsptones)
1081 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1083 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1084 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], TONE_PATT_OFF, 0, "DSP-TONE", 0);
1087 Port::set_tone(dir, tone);
1093 /* now we USE dsp-tone, convert name */
1094 else if (!strcmp(tone, "dialtone"))
1096 switch(options.dsptones) {
1097 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1098 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1099 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1101 } else if (!strcmp(tone, "dialpbx"))
1103 switch(options.dsptones) {
1104 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1105 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1106 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1108 } else if (!strcmp(tone, "ringing"))
1110 switch(options.dsptones) {
1111 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1112 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1113 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1115 } else if (!strcmp(tone, "ringpbx"))
1117 switch(options.dsptones) {
1118 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1119 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1120 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1122 } else if (!strcmp(tone, "busy"))
1125 switch(options.dsptones) {
1126 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1127 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1128 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1130 } else if (!strcmp(tone, "release"))
1133 switch(options.dsptones) {
1134 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1135 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1136 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1138 } else if (!strcmp(tone, "cause_10"))
1140 else if (!strcmp(tone, "cause_11"))
1142 else if (!strcmp(tone, "cause_22"))
1144 switch(options.dsptones) {
1145 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1146 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1147 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1149 } else if (!strncmp(tone, "cause_", 6))
1150 id = TONE_SPECIAL_INFO;
1154 /* if we have a tone that is not supported by dsp */
1155 if (id==TONE_OFF && tone[0])
1163 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1165 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1166 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);
1168 /* turn user-space tones off in cases of no tone OR dsp tone */
1169 Port::set_tone("",NULL);
1173 /* MESSAGE_mISDNSIGNAL */
1174 //extern struct message *dddebug;
1175 void PmISDN::message_mISDNsignal(unsigned long epoint_id, int message_id, union parameter *param)
1177 switch(param->mISDNsignal.message)
1179 case mISDNSIGNAL_VOLUME:
1180 if (p_m_txvol != param->mISDNsignal.txvol)
1182 p_m_txvol = param->mISDNsignal.txvol;
1183 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
1185 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1186 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);
1188 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
1189 if (p_m_rxvol != param->mISDNsignal.rxvol)
1191 p_m_rxvol = param->mISDNsignal.rxvol;
1192 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
1194 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1195 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);
1197 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
1200 case mISDNSIGNAL_CONF:
1201 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1202 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1203 if (p_m_conf != param->mISDNsignal.conf)
1205 p_m_conf = param->mISDNsignal.conf;
1206 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1208 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1209 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);
1211 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1212 /* we must set, even if currently tone forbids conf */
1213 p_m_conf = param->mISDNsignal.conf;
1214 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1217 case mISDNSIGNAL_JOINDATA:
1218 if (p_m_joindata != param->mISDNsignal.joindata)
1220 p_m_joindata = param->mISDNsignal.joindata;
1221 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1223 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1226 case mISDNSIGNAL_DELAY:
1227 if (p_m_delay != param->mISDNsignal.delay)
1229 p_m_delay = param->mISDNsignal.delay;
1230 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1232 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1233 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);
1235 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1239 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1244 void PmISDN::message_crypt(unsigned long epoint_id, int message_id, union parameter *param)
1246 struct message *message;
1248 switch(param->crypt.type)
1250 case CC_ACTBF_REQ: /* activate blowfish */
1252 p_m_crypt_key_len = param->crypt.len;
1253 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1255 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1256 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1257 message->param.crypt.type = CC_ERROR_IND;
1258 message_put(message);
1261 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1263 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1265 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1266 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);
1269 case CC_DACT_REQ: /* deactivate session encryption */
1274 case CR_LISTEN_REQ: /* start listening to messages */
1275 p_m_crypt_listen = 1;
1276 p_m_crypt_listen_state = 0;
1279 case CR_UNLISTEN_REQ: /* stop listening to messages */
1280 p_m_crypt_listen = 0;
1283 case CR_MESSAGE_REQ: /* send message */
1284 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1285 if (!p_m_crypt_msg_len)
1287 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1290 p_m_crypt_msg_current = 0; /* reset */
1291 p_m_crypt_msg_loops = 3; /* enable */
1293 /* disable txmix, or we get corrupt data due to audio process */
1296 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1297 ph_control(p_m_mISDNport, this, p_mISDNport->b_addr[p_m_b_index], CMX_MIX_OFF, 0, "DSP-TXMIX", 0);
1303 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1309 * endpoint sends messages to the port
1311 int PmISDN::message_epoint(unsigned long epoint_id, int message_id, union parameter *param)
1313 if (Port::message_epoint(epoint_id, message_id, param))
1318 case MESSAGE_DATA: /* tx-data from upper layer */
1319 txfromup(param->data.data, param->data.len);
1322 case MESSAGE_mISDNSIGNAL: /* user command */
1323 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1324 message_mISDNsignal(epoint_id, message_id, param);
1327 case MESSAGE_CRYPT: /* crypt control command */
1328 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1329 message_crypt(epoint_id, message_id, param);
1338 * main loop for processing messages from mISDN device
1340 int mISDN_handler(void)
1345 struct mISDNport *mISDNport;
1346 class PmISDN *isdnport;
1349 mISDNuser_head_t *hh;
1352 /* the que avoids loopbacks when replying to stack after receiving
1354 mISDNport = mISDNport_first;
1357 /* process turning on/off rx */
1359 while(i < mISDNport->b_num)
1361 isdnport=mISDNport->b_port[i];
1364 /* call bridges in user space OR crypto OR recording */
1365 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1367 /* rx IS required */
1368 if (isdnport->p_m_rxoff)
1371 isdnport->p_m_rxoff = 0;
1372 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n");
1373 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1374 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1379 /* rx NOT required */
1380 if (!isdnport->p_m_rxoff)
1383 isdnport->p_m_rxoff = 1;
1384 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n");
1385 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1386 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1391 if (isdnport->p_record)
1393 /* txdata IS required */
1394 if (!isdnport->p_m_txdata)
1397 isdnport->p_m_txdata = 1;
1398 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n");
1399 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1400 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_ON, 0, "DSP-TXDATA", 1);
1405 /* txdata NOT required */
1406 if (isdnport->p_m_txdata)
1409 isdnport->p_m_txdata = 0;
1410 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n");
1411 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1412 ph_control(mISDNport, isdnport, mISDNport->b_addr[isdnport->p_m_b_index], CMX_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1420 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1422 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1423 mISDNport->l1timeout = 0;
1426 if (mISDNport->l2establish)
1428 if (now-mISDNport->l2establish > 5)
1430 if (mISDNport->ntmode)
1432 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link NT portnum=%d.\n", mISDNport->portnum);
1433 time(&mISDNport->l2establish);
1435 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
1436 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1439 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link TE portnum=%d.\n", mISDNport->portnum);
1440 time(&mISDNport->l2establish);
1443 act.prim = DL_ESTABLISH | REQUEST;
1444 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 3 | FLG_MSG_DOWN;
1447 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1449 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | REQUEST, DIRECTION_OUT);
1454 if ((dmsg = msg_dequeue(&mISDNport->downqueue)))
1456 if (mISDNport->ntmode)
1458 hh = (mISDNuser_head_t *)dmsg->data;
1459 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);
1460 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
1464 frm = (iframe_t *)dmsg->data;
1465 frm->addr = mISDNport->upper_id | FLG_MSG_DOWN;
1466 frm->len = (dmsg->len) - mISDN_HEADER_LEN;
1467 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);
1468 mISDN_write(mISDNdevice, dmsg->data, dmsg->len, TIMEOUT_1SEC);
1473 mISDNport = mISDNport->next;
1476 /* no device, no read */
1477 if (mISDNdevice < 0)
1480 /* get message from kernel */
1481 if (!(msg = alloc_msg(MAX_MSG_SIZE)))
1483 ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
1487 if (errno == EAGAIN)
1489 FATAL("Failed to do mISDN_read()\n");
1494 // printf("%s: ERROR: mISDN_read() returns nothing\n");
1498 frm = (iframe_t *)msg->data;
1503 case MGR_DELLAYER | CONFIRM:
1504 case MGR_INITTIMER | CONFIRM:
1505 case MGR_ADDTIMER | CONFIRM:
1506 case MGR_DELTIMER | CONFIRM:
1507 case MGR_REMOVETIMER | CONFIRM:
1512 /* handle timer events from mISDN for NT-stack
1513 * note: they do not associate with a stack */
1514 if (frm->prim == (MGR_TIMER | INDICATION))
1518 /* find mISDNport */
1519 mISDNport = mISDNport_first;
1523 if (mISDNport->ntmode)
1525 it = mISDNport->nst.tlist;
1529 if (it->id == (int)frm->addr)
1536 mISDNport = mISDNport->next;
1540 mISDN_write_frame(mISDNdevice, msg->data, mISDNport->upper_id | FLG_MSG_DOWN,
1541 MGR_TIMER | RESPONSE, 0, 0, NULL, TIMEOUT_1SEC);
1543 PDEBUG(DEBUG_ISDN, "timer-indication port %d it=%p\n", mISDNport->portnum, it);
1544 test_and_clear_bit(FLG_TIMER_RUNING, (long unsigned int *)&it->Flags);
1545 ret = it->function(it->data);
1548 PDEBUG(DEBUG_ISDN, "timer-indication not handled\n");
1553 /* find the mISDNport that belongs to the stack */
1554 mISDNport = mISDNport_first;
1557 if ((frm->addr&MASTER_ID_MASK) == (unsigned int)(mISDNport->upper_id&MASTER_ID_MASK))
1559 mISDNport = mISDNport->next;
1563 PERROR("message belongs to no mISDNport: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1568 if (!(frm->addr&FLG_CHILD_STACK))
1573 case MGR_SHORTSTATUS | INDICATION:
1574 case MGR_SHORTSTATUS | CONFIRM:
1575 switch(frm->dinfo) {
1576 case SSTATUS_L1_ACTIVATED:
1577 l1l2l3_trace_header(mISDNport, NULL, PH_ACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1580 case SSTATUS_L1_DEACTIVATED:
1581 l1l2l3_trace_header(mISDNport, NULL, PH_DEACTIVATE | (frm->prim & 0x3), DIRECTION_IN);
1584 case SSTATUS_L2_ESTABLISHED:
1585 l1l2l3_trace_header(mISDNport, NULL, DL_ESTABLISH | (frm->prim & 0x3), DIRECTION_IN);
1588 case SSTATUS_L2_RELEASED:
1589 l1l2l3_trace_header(mISDNport, NULL, DL_RELEASE | (frm->prim & 0x3), DIRECTION_IN);
1595 case PH_ACTIVATE | CONFIRM:
1596 case PH_ACTIVATE | INDICATION:
1597 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1599 if (mISDNport->ntmode)
1601 mISDNport->l1link = 1;
1602 setup_queue(mISDNport, 1);
1606 mISDNport->l1link = 1;
1607 setup_queue(mISDNport, 1);
1610 case PH_DEACTIVATE | CONFIRM:
1611 case PH_DEACTIVATE | INDICATION:
1612 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1614 if (mISDNport->ntmode)
1616 mISDNport->l1link = 0;
1617 setup_queue(mISDNport, 0);
1621 mISDNport->l1link = 0;
1622 setup_queue(mISDNport, 0);
1625 case PH_CONTROL | CONFIRM:
1626 case PH_CONTROL | INDICATION:
1627 PDEBUG(DEBUG_ISDN, "Received PH_CONTROL for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1630 case DL_ESTABLISH | INDICATION:
1631 case DL_ESTABLISH | CONFIRM:
1632 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1634 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1636 if (mISDNport->l2establish)
1638 mISDNport->l2establish = 0;
1639 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1641 mISDNport->l2link = 1;
1644 case DL_RELEASE | INDICATION:
1645 case DL_RELEASE | CONFIRM:
1646 l1l2l3_trace_header(mISDNport, NULL, frm->prim, DIRECTION_IN);
1648 if (!mISDNport->ntmode) break; /* !!!!!!!!!!!!!!!! */
1650 mISDNport->l2link = 0;
1653 time(&mISDNport->l2establish);
1654 PDEBUG(DEBUG_ISDN, "because we are ptp, we set a l2establish timer.\n");
1660 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);
1661 if (frm->dinfo==(signed long)0xffffffff && frm->prim==(PH_DATA|CONFIRM))
1663 PERROR("SERIOUS BUG, dinfo == 0xffffffff, prim == PH_DATA | CONFIRM !!!!\n");
1666 if (mISDNport->ntmode)
1668 /* l1-data enters the nt-mode library */
1669 nst = &mISDNport->nst;
1670 if (nst->l1_l2(nst, msg))
1675 /* l3-data is sent to pbx */
1676 if (stack2manager_te(mISDNport, msg))
1687 /* we don't care about confirms, we use rx data to sync tx */
1688 case PH_DATA | CONFIRM:
1689 case DL_DATA | CONFIRM:
1692 /* we receive audio data, we respond to it AND we send tones */
1693 case PH_DATA | INDICATION:
1694 case DL_DATA | INDICATION:
1695 case PH_CONTROL | INDICATION:
1697 while(i < mISDNport->b_num)
1699 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1703 if (i == mISDNport->b_num)
1705 PERROR("unhandled b-message (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1708 if (mISDNport->b_port[i])
1710 //PERROR("port sech: %s data\n", mISDNport->b_port[i]->p_name);
1711 mISDNport->b_port[i]->bchannel_receive(frm);
1713 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (address 0x%x), ignoring.\n", frm->addr);
1716 case PH_ACTIVATE | INDICATION:
1717 case DL_ESTABLISH | INDICATION:
1718 case PH_ACTIVATE | CONFIRM:
1719 case DL_ESTABLISH | CONFIRM:
1720 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
1722 while(i < mISDNport->b_num)
1724 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1728 if (i == mISDNport->b_num)
1730 PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1733 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1736 case PH_DEACTIVATE | INDICATION:
1737 case DL_RELEASE | INDICATION:
1738 case PH_DEACTIVATE | CONFIRM:
1739 case DL_RELEASE | CONFIRM:
1740 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
1742 while(i < mISDNport->b_num)
1744 if ((unsigned int)(mISDNport->b_addr[i]&STACK_ID_MASK) == (frm->addr&STACK_ID_MASK))
1748 if (i == mISDNport->b_num)
1750 PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
1753 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1757 PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
1768 * global function to add a new card (port)
1770 struct mISDNport *mISDNport_open(int port, int ptp, int ptmp, struct interface *interface)
1773 unsigned char buff[1025];
1774 iframe_t *frm = (iframe_t *)buff;
1775 stack_info_t *stinf;
1776 struct mISDNport *mISDNport, **mISDNportp;
1778 // interface_info_t ii;
1785 /* open mISDNdevice if not already open */
1786 if (mISDNdevice < 0)
1791 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));
1795 PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
1797 /* create entity for layer 3 TE-mode */
1798 mISDN_write_frame(mISDNdevice, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
1799 ret = mISDN_read_frame(mISDNdevice, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
1800 if (ret < (int)mISDN_HEADER_LEN)
1803 FATAL("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
1805 entity = frm->dinfo & 0xffff;
1808 PDEBUG(DEBUG_ISDN, "our entity for l3-processes is %d.\n", entity);
1811 /* query port's requirements */
1812 cnt = mISDN_get_stack_count(mISDNdevice);
1815 PERROR("Found no card. Please be sure to load card drivers.\n");
1818 if (port>cnt || port<1)
1820 PERROR("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 1, cnt);
1823 ret = mISDN_get_stack_info(mISDNdevice, port, buff, sizeof(buff));
1826 PERROR("Cannot get stack info for port %d (ret=%d)\n", port, ret);
1829 stinf = (stack_info_t *)&frm->data.p;
1830 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
1832 case ISDN_PID_L0_TE_S0:
1833 PDEBUG(DEBUG_ISDN, "TE-mode BRI S/T interface line\n");
1835 case ISDN_PID_L0_NT_S0:
1836 PDEBUG(DEBUG_ISDN, "NT-mode BRI S/T interface port\n");
1839 case ISDN_PID_L0_TE_E1:
1840 PDEBUG(DEBUG_ISDN, "TE-mode PRI E1 interface line\n");
1843 case ISDN_PID_L0_NT_E1:
1844 PDEBUG(DEBUG_ISDN, "LT-mode PRI E1 interface port\n");
1849 PERROR("unknown port(%d) type 0x%08x\n", port, stinf->pid.protocol[0]);
1855 if (stinf->pid.protocol[1] == 0)
1857 PERROR("Given port %d: Missing layer 1 NT-mode protocol.\n", port);
1860 if (stinf->pid.protocol[2])
1862 PERROR("Given port %d: Layer 2 protocol 0x%08x is detected, but not allowed for NT lib.\n", port, stinf->pid.protocol[2]);
1868 if (stinf->pid.protocol[1] == 0)
1870 PERROR("Given port %d: Missing layer 1 protocol.\n", port);
1873 if (stinf->pid.protocol[2] == 0)
1875 PERROR("Given port %d: Missing layer 2 protocol.\n", port);
1878 if (stinf->pid.protocol[3] == 0)
1880 PERROR("Given port %d: Missing layer 3 protocol.\n", port);
1884 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
1886 case ISDN_PID_L3_DSS1USER:
1890 PERROR("Given port %d: own protocol 0x%08x", port,stinf->pid.protocol[3]);
1894 if (stinf->pid.protocol[4])
1896 PERROR("Given port %d: Layer 4 protocol not allowed.\n", port);
1901 /* add mISDNport structure */
1902 mISDNportp = &mISDNport_first;
1904 mISDNportp = &((*mISDNportp)->next);
1905 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
1907 *mISDNportp = mISDNport;
1909 /* allocate ressources of port */
1910 msg_queue_init(&mISDNport->downqueue);
1911 // SCPY(mISDNport->name, "noname");
1912 mISDNport->portnum = port;
1913 mISDNport->ntmode = nt;
1914 mISDNport->pri = pri;
1915 mISDNport->d_stid = stinf->id;
1916 PDEBUG(DEBUG_ISDN, "d_stid = 0x%x.\n", mISDNport->d_stid);
1917 mISDNport->b_num = stinf->childcnt;
1918 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
1919 if ((stinf->pid.protocol[2]&ISDN_PID_L2_DF_PTP) || (nt&&ptp) || pri)
1921 PDEBUG(DEBUG_ISDN, "Port is point-to-point.\n");
1922 mISDNport->ptp = ptp = 1;
1925 PDEBUG(DEBUG_ISDN, "Port is forced to point-to-multipoint.\n");
1926 mISDNport->ptp = ptp = 0;
1930 while(i < stinf->childcnt)
1932 mISDNport->b_stid[i] = stinf->child[i];
1933 mISDNport->b_state[i] = B_STATE_IDLE;
1934 PDEBUG(DEBUG_ISDN, "b_stid[%d] = 0x%x.\n", i, mISDNport->b_stid[i]);
1937 memset(&li, 0, sizeof(li));
1938 UCPY(&li.name[0], (nt)?"net l2":"pbx l4");
1941 li.pid.protocol[nt?2:4] = (nt)?ISDN_PID_L2_LAPD_NET:ISDN_PID_L4_CAPI20;
1942 li.pid.layermask = ISDN_LAYER((nt?2:4));
1943 li.st = mISDNport->d_stid;
1944 ret = mISDN_new_layer(mISDNdevice, &li);
1947 PERROR("Cannot add layer %d of port %d (ret %d)\n", nt?2:4, port, ret);
1949 mISDNport_close(mISDNport);
1952 mISDNport->upper_id = li.id;
1953 ret = mISDN_register_layer(mISDNdevice, mISDNport->d_stid, mISDNport->upper_id);
1956 PERROR("Cannot register layer %d of port %d\n", nt?2:4, port);
1959 mISDNport->lower_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?1:3); // id of lower layer (nt=1, te=3)
1960 if (mISDNport->lower_id < 0)
1962 PERROR("Cannot get layer(%d) id of port %d\n", nt?1:3, port);
1965 mISDNport->upper_id = mISDN_get_layerid(mISDNdevice, mISDNport->d_stid, nt?2:4); // id of uppermost layer (nt=2, te=4)
1966 if (mISDNport->upper_id < 0)
1968 PERROR("Cannot get layer(%d) id of port %d\n", nt?2:4, port);
1971 PDEBUG(DEBUG_ISDN, "Layer %d of port %d added.\n", nt?2:4, port);
1973 /* if ntmode, establish L1 to send the tei removal during start */
1974 if (mISDNport->ntmode)
1978 act.prim = PH_ACTIVATE | REQUEST;
1979 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
1980 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
1983 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
1984 usleep(10000); /* to be sure, that l1 is up */
1987 /* create nst (nt-mode only) */
1990 mgr = &mISDNport->mgr;
1991 nst = &mISDNport->nst;
1996 nst->l3_manager = stack2manager_nt; /* messages from nt-mode */
1997 nst->device = mISDNdevice;
1999 nst->d_stid = mISDNport->d_stid;
2001 nst->feature = FEATURE_NET_HOLD;
2003 nst->feature |= FEATURE_NET_PTP;
2005 nst->feature |= FEATURE_NET_CRLEN2 | FEATURE_NET_EXTCID;
2008 while(i < mISDNport->b_num)
2010 nst->b_stid[i] = mISDNport->b_stid[i];
2014 nst->l1_id = mISDNport->lower_id;
2015 nst->l2_id = mISDNport->upper_id;
2018 msg_queue_init(&nst->down_queue);
2024 /* if te-mode, query state link */
2025 if (!mISDNport->ntmode)
2029 PDEBUG(DEBUG_ISDN, "sending short status request for port %d.\n", port);
2030 act.prim = MGR_SHORTSTATUS | REQUEST;
2031 act.addr = mISDNport->upper_id | MSG_BROADCAST;
2032 act.dinfo = SSTATUS_BROADCAST_BIT | SSTATUS_ALL;
2034 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2036 /* if ptp AND te-mode, pull up the link */
2037 if (mISDNport->ptp && !mISDNport->ntmode)
2041 act.prim = DL_ESTABLISH | REQUEST;
2042 act.addr = (mISDNport->upper_id & ~LAYER_ID_MASK) | 4 | FLG_MSG_DOWN;
2045 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2047 /* if ptp AND nt-mode, pull up the link */
2048 if (mISDNport->ptp && mISDNport->ntmode)
2052 dmsg = create_l2msg(DL_ESTABLISH | REQUEST, 0, 0);
2053 if (mISDNport->nst.manager_l3(&mISDNport->nst, dmsg))
2056 /* initially, we assume that the link is down, exept for nt-ptmp */
2057 mISDNport->l2link = (mISDNport->ntmode && !mISDNport->ptp)?1:0;
2059 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2061 start_trace(mISDNport->portnum,
2069 add_trace("channels", NULL, "%d", mISDNport->b_num);
2076 * function to free ALL cards (ports)
2078 void mISDNport_close_all(void)
2080 /* free all ports */
2081 while(mISDNport_first)
2082 mISDNport_close(mISDNport_first);
2086 * free only one port
2088 void mISDNport_close(struct mISDNport *mISDNport)
2090 struct mISDNport **mISDNportp;
2092 class PmISDN *isdnport;
2094 unsigned char buf[32];
2097 /* remove all port instance that are linked to this mISDNport */
2101 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2103 isdnport = (class PmISDN *)port;
2104 if (isdnport->p_m_mISDNport)
2106 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2113 /* only if we are already part of interface */
2114 if (mISDNport->ifport)
2116 start_trace(mISDNport->portnum,
2117 mISDNport->ifport->interface,
2127 /* free bchannels */
2129 while(i < mISDNport->b_num)
2131 if (mISDNport->b_addr[i])
2133 _bchannel_destroy(mISDNport, i);
2134 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2139 /* free ressources of port */
2140 msg_queue_purge(&mISDNport->downqueue);
2143 if (mISDNport->ntmode)
2145 nst = &mISDNport->nst;
2146 if (nst->manager) /* to see if initialized */
2148 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");
2149 cleanup_Isdnl3(nst);
2150 cleanup_Isdnl2(nst);
2153 msg_queue_purge(&nst->down_queue);
2154 if (nst->phd_down_msg)
2155 FREE(nst->phd_down_msg, 0);
2159 PDEBUG(DEBUG_BCHANNEL, "freeing d-stack.\n");
2160 if (mISDNport->d_stid)
2162 if (mISDNport->upper_id)
2163 mISDN_write_frame(mISDNdevice, buf, mISDNport->upper_id | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
2166 /* remove from list */
2167 mISDNportp = &mISDNport_first;
2170 if (*mISDNportp == mISDNport)
2172 *mISDNportp = (*mISDNportp)->next;
2176 mISDNportp = &((*mISDNportp)->next);
2180 FATAL("mISDNport not in list\n");
2182 FREE(mISDNport, sizeof(struct mISDNport));
2185 /* close mISDNdevice, if no port */
2186 if (mISDNdevice>=0 && mISDNport_first==NULL)
2189 mISDN_write_frame(mISDNdevice, buf, 0, MGR_DELENTITY | REQUEST, entity, 0, NULL, TIMEOUT_1SEC);
2191 mISDN_close(mISDNdevice);
2193 PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
2199 * global function to show all available isdn ports
2201 void mISDN_port_info(void)
2205 int useable, nt, pri;
2206 unsigned char buff[1025];
2207 iframe_t *frm = (iframe_t *)buff;
2208 stack_info_t *stinf;
2212 if ((device = mISDN_open()) < 0)
2214 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));
2218 /* get number of stacks */
2220 ii = mISDN_get_stack_count(device);
2224 printf("Found no card. Please be sure to load card drivers.\n");
2227 /* loop the number of cards and get their info */
2230 err = mISDN_get_stack_info(device, i, buff, sizeof(buff));
2233 fprintf(stderr, "mISDN_get_stack_info() failed: port=%d err=%d\n", i, err);
2236 stinf = (stack_info_t *)&frm->data.p;
2241 /* output the port info */
2242 printf("Port %2d: ", i);
2243 switch(stinf->pid.protocol[0] & ~ISDN_PID_FEATURE_MASK)
2245 case ISDN_PID_L0_TE_S0:
2246 printf("TE-mode BRI S/T interface line (for phone lines)");
2248 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_S0_HFC & ISDN_PID_FEATURE_MASK)
2249 printf(" HFC multiport card");
2252 case ISDN_PID_L0_NT_S0:
2254 printf("NT-mode BRI S/T interface port (for phones)");
2256 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_S0_HFC & ISDN_PID_FEATURE_MASK)
2257 printf(" HFC multiport card");
2260 case ISDN_PID_L0_TE_E1:
2262 printf("TE-mode PRI E1 interface line (for phone lines)");
2264 if (stinf->pid.protocol[0] & ISDN_PID_L0_TE_E1_HFC & ISDN_PID_FEATURE_MASK)
2265 printf(" HFC-E1 card");
2268 case ISDN_PID_L0_NT_E1:
2271 printf("NT-mode PRI E1 interface port (for phones)");
2273 if (stinf->pid.protocol[0] & ISDN_PID_L0_NT_E1_HFC & ISDN_PID_FEATURE_MASK)
2274 printf(" HFC-E1 card");
2279 printf("unknown type 0x%08x",stinf->pid.protocol[0]);
2285 if (stinf->pid.protocol[1] == 0)
2288 printf(" -> Missing layer 1 NT-mode protocol.\n");
2291 while(p <= MAX_LAYER_NR) {
2292 if (stinf->pid.protocol[p])
2295 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2302 printf(" -> Interface is Point-To-Point (PRI).\n");
2304 printf(" -> Interface can be Poin-To-Point/Multipoint.\n");
2308 if (stinf->pid.protocol[1] == 0)
2311 printf(" -> Missing layer 1 protocol.\n");
2313 if (stinf->pid.protocol[2] == 0)
2316 printf(" -> Missing layer 2 protocol.\n");
2318 if (stinf->pid.protocol[2] & ISDN_PID_L2_DF_PTP)
2320 printf(" -> Interface is Poin-To-Point.\n");
2322 if (stinf->pid.protocol[3] == 0)
2325 printf(" -> Missing layer 3 protocol.\n");
2328 printf(" -> Protocol: ");
2329 switch(stinf->pid.protocol[3] & ~ISDN_PID_FEATURE_MASK)
2331 case ISDN_PID_L3_DSS1USER:
2332 printf("DSS1 (Euro ISDN)");
2337 printf("unknown protocol 0x%08x",stinf->pid.protocol[3]);
2342 while(p <= MAX_LAYER_NR) {
2343 if (stinf->pid.protocol[p])
2346 printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
2351 printf(" - %d B-channels\n", stinf->childcnt);
2354 printf(" * Port NOT useable for LCR\n");
2356 printf("--------\n");
2363 if ((err = mISDN_close(device)))
2364 FATAL("mISDN_close() failed: err=%d '%s'\n", err, strerror(err));
2369 * enque data from upper buffer
2371 void PmISDN::txfromup(unsigned char *data, int length)
2373 unsigned char buf[mISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2374 iframe_t *frm = (iframe_t *)buf;
2376 /* configure frame */
2377 frm->prim = DL_DATA | REQUEST;
2378 frm->addr = p_m_mISDNport->b_addr[p_m_b_index] | FLG_MSG_DOWN;
2381 /* check if high priority tones exist
2382 * ignore data in this case
2384 if (p_tone_name[0] || p_m_crypt_msg_loops)
2387 /* preload procedure
2388 * if transmit buffer in DSP module is empty,
2389 * preload it to DSP_LOAD to prevent jitter gaps.
2391 if (p_m_load==0 && ISDN_LOAD>0)
2394 memcpy(buf+mISDN_HEADER_LEN, data, ISDN_LOAD);
2395 frm->len = ISDN_LOAD;
2396 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2397 p_m_load += frm->len;
2400 /* drop if load would exceed ISDN_MAXLOAD
2401 * this keeps the delay not too high
2403 if (p_m_load+length > ISDN_MAXLOAD)
2406 /* load data to buffer
2408 memcpy(buf+mISDN_HEADER_LEN, data, length);
2410 mISDN_write(mISDNdevice, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
2411 p_m_load += frm->len;