1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
14 #include <mISDN/q931.h>
17 #ifdef __compiler_offsetof
18 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
20 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
24 #define container_of(ptr, type, member) ({ \
25 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
26 (type *)( (char *)__mptr - offsetof(type,member) );})
29 // timeouts if activating/deactivating response from mISDN got lost
30 #define B_TIMER_ACTIVATING 1 // seconds
31 #define B_TIMER_DEACTIVATING 1 // seconds
33 /* list of mISDN ports */
34 struct mISDNport *mISDNport_first;
36 /* noise randomizer */
37 unsigned char mISDN_rand[256];
38 int mISDN_rand_count = 0;
41 unsigned int mt_assign_pid = ~0;
45 static int upqueue_pipe[2];
46 static struct lcr_fd upqueue_fd;
47 int upqueue_avail = 0;
49 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
50 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
52 static int my_mISDNlib_debug(const char *file, int line, const char *func, int level, const char *fmt, va_list va)
57 ret = vfprintf(debug_fp, fmt, va);
61 static struct mi_ext_fn_s myfn;
63 int mISDN_initialize(void)
68 /* try to open raw socket to check kernel */
69 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
70 if (mISDNsocket < 0) {
71 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
76 // set debug printout function
77 myfn.prt_debug = my_mISDNlib_debug;
79 ver = init_layer3(4, &myfn); // buffer of 4
81 /* open debug, if enabled and not only stack debugging */
83 SPRINT(filename, "%s/debug.log", LOG_DIR);
84 debug_fp = fopen(filename, "a");
87 if (options.deb & DEBUG_STACK)
88 mISDN_set_debug_level(0xfffffeff);
90 mISDN_set_debug_level(0);
92 if (pipe(upqueue_pipe) < 0)
93 FATAL("Failed to open pipe\n");
94 memset(&upqueue_fd, 0, sizeof(upqueue_fd));
95 upqueue_fd.fd = upqueue_pipe[0];
96 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
101 void mISDN_deinitialize(void)
109 if (mISDNsocket > -1)
112 if (upqueue_fd.inuse) {
113 unregister_fd(&upqueue_fd);
114 close(upqueue_pipe[0]);
115 close(upqueue_pipe[1]);
120 static int load_timer(struct lcr_timer *timer, void *instance, int index);
125 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, struct interface *interface, int channel, int exclusive, int mode) : Port(type, portname, settings, interface)
127 p_m_mISDNport = mISDNport;
128 p_m_portnum = mISDNport->portnum;
135 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
136 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
142 p_m_preload = ISDN_LOAD;
143 p_m_disable_dejitter = 0;
147 p_m_inband_send_on = 0;
148 p_m_inband_receive_on = 0;
149 p_m_dtmf = !mISDNport->ifport->nodtmf;
150 p_m_dtmf_threshold = mISDNport->ifport->dtmf_threshold;
151 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
152 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
153 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
156 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
157 add_timer(&p_m_loadtimer, load_timer, this, 0);
163 p_m_crypt_listen = 0;
164 p_m_crypt_msg_loops = 0;
165 p_m_crypt_msg_loops = 0;
166 p_m_crypt_msg_len = 0;
167 p_m_crypt_msg[0] = '\0';
168 p_m_crypt_msg_current = 0;
169 p_m_crypt_key_len = 0;
170 p_m_crypt_listen = 0;
171 p_m_crypt_listen_state = 0;
172 p_m_crypt_listen_len = 0;
173 p_m_crypt_listen_msg[0] = '\0';
174 p_m_crypt_listen_crc = 0;
175 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
176 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
177 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
181 /* if any channel requested by constructor */
182 if (channel == CHANNEL_ANY) {
183 /* reserve channel */
185 mISDNport->b_reserved++;
188 /* reserve channel */
189 if (channel > 0) // only if constructor was called with a channel resevation
190 seize_bchannel(channel, exclusive);
192 /* we increase the number of objects: */
194 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
195 //inband_receive_on();
204 struct lcr_msg *message;
206 del_timer(&p_m_timeout);
207 del_timer(&p_m_loadtimer);
209 /* remove bchannel relation */
213 while (p_epointlist) {
214 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
215 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
216 message->param.disconnectinfo.cause = 16;
217 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
218 message_put(message);
219 /* remove from list */
220 free_epointlist(p_epointlist);
223 /* we decrease the number of objects: */
224 p_m_mISDNport->use--;
225 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
232 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
234 /* init trace with given values */
235 start_trace(mISDNport?mISDNport->portnum:-1,
236 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
237 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
238 port?port->p_dialinginfo.id:NULL,
241 port?port->p_serial:0,
249 static struct isdn_message {
253 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
254 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
255 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
256 {"DL_RELEASE", L2_RELEASE_REQ},
257 {"UNKNOWN", L3_UNKNOWN_REQ},
258 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
259 {"MT_SETUP", L3_SETUP_REQ},
260 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
261 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
262 {"MT_ALERTING", L3_ALERTING_REQ},
263 {"MT_CONNECT", L3_CONNECT_REQ},
264 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
265 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
266 {"MT_RELEASE", L3_RELEASE_REQ},
267 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
268 {"MT_INFORMATION", L3_INFORMATION_REQ},
269 {"MT_PROGRESS", L3_PROGRESS_REQ},
270 {"MT_NOTIFY", L3_NOTIFY_REQ},
271 {"MT_SUSPEND", L3_SUSPEND_REQ},
272 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
273 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
274 {"MT_RESUME", L3_RESUME_REQ},
275 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
276 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
277 {"MT_HOLD", L3_HOLD_REQ},
278 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
279 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
280 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
281 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
282 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
283 {"MT_FACILITY", L3_FACILITY_REQ},
284 {"MT_STATUS", L3_STATUS_REQ},
285 {"MT_RESTART", L3_RESTART_REQ},
286 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
287 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
290 static const char *isdn_prim[4] = {
296 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
301 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
302 /* select message and primitive text */
304 while(isdn_message[i].name) {
305 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
306 if (isdn_message[i].value == (msg&0xffffff00)) {
307 SCPY(msgtext, isdn_message[i].name);
312 SCAT(msgtext, isdn_prim[msg&0x00000003]);
315 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
317 if (mISDNport->ntmode) {
318 if (direction == DIRECTION_OUT)
319 SCAT(msgtext, " N->U");
321 SCAT(msgtext, " N<-U");
323 if (direction == DIRECTION_OUT)
324 SCAT(msgtext, " U->N");
326 SCAT(msgtext, " U<-N");
331 /* init trace with given values */
332 start_trace(mISDNport?mISDNport->portnum:-1,
333 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
334 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
335 port?port->p_dialinginfo.id:NULL,
338 port?port->p_serial:0,
344 * send control information to the channel (dsp-module)
346 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
348 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
349 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
350 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
357 if (c1 == DTMF_TONE_START && c2 == 0) {
361 ctrl->prim = PH_CONTROL_REQ;
365 ret = sendto(sock, buffer, MISDN_HEADER_LEN+len, 0, NULL, 0);
367 PERROR("Failed to send to socket %d\n", sock);
368 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
369 if (c1 == DSP_CONF_JOIN)
370 add_trace(trace_name, NULL, "0x%08x", trace_value);
372 add_trace(trace_name, NULL, "%d", trace_value);
376 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, const char *trace_name, int trace_value)
378 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
379 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
380 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
386 ctrl->prim = PH_CONTROL_REQ;
389 memcpy(d, c2, c2_len);
390 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
392 PERROR("Failed to send to socket %d\n", sock);
393 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
394 add_trace(trace_name, NULL, "%d", trace_value);
398 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
401 * subfunction for bchannel_event
404 static int _bchannel_create(struct mISDNport *mISDNport, int i)
407 struct sockaddr_mISDN addr;
409 if (mISDNport->b_sock[i].inuse) {
410 PERROR("Error: Socket already created for index %d\n", i);
415 //#warning testing without DSP
416 // mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
417 mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
418 if (mISDNport->b_sock[i].fd < 0) {
419 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
423 /* register callback for read */
424 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
426 /* bind socket to bchannel */
427 addr.family = AF_ISDN;
428 addr.dev = mISDNport->portnum;
429 addr.channel = i+1+(i>=15);
430 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
432 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer (errno=%d). Did you load mISDN_dsp.ko?\n", i, errno);
433 close(mISDNport->b_sock[i].fd);
434 unregister_fd(&mISDNport->b_sock[i]);
438 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
439 add_trace("channel", NULL, "%d", i+1+(i>=15));
440 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
448 * subfunction for bchannel_event
449 * activate / deactivate request
451 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
453 struct mISDNhead act;
456 if (!mISDNport->b_sock[i].inuse)
458 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
460 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
462 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
465 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
466 add_trace("channel", NULL, "%d", i+1+(i>=15));
468 add_trace("event", NULL, "timeout recovery");
474 * subfunction for bchannel_event
477 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
482 if (!mISDNport->b_sock[i].inuse)
484 handle = mISDNport->b_sock[i].fd;
485 port = mISDNport->b_port[i];
486 mode = mISDNport->b_mode[i];
488 PERROR("bchannel index i=%d not associated with a port object\n", i);
492 /* set dsp features */
493 if (port->p_m_txdata)
494 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
495 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
496 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
497 if (port->p_m_tx_dejitter && mode == B_MODE_TRANSPARENT)
498 ph_control(mISDNport, port, handle, DSP_TX_DEJITTER, port->p_m_tx_dejitter, "DSP-TX_DEJITTER", port->p_m_tx_dejitter);
499 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
500 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
501 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
502 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
503 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
504 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
505 if (port->p_m_conf && !port->p_m_mute)
506 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
508 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
509 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
510 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
512 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
513 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
514 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
515 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
516 ph_control(mISDNport, port, handle, DTMF_TONE_START, port->p_m_dtmf_threshold, "DSP-DTMF", 1);
517 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
518 ph_control_block(mISDNport, port, handle, DSP_BF_ENABLE_KEY, port->p_m_crypt_key, port->p_m_crypt_key_len, "DSP-CRYPT", port->p_m_crypt_key_len);
522 void PmISDN::set_conf(int oldconf, int newconf)
524 if (oldconf != newconf) {
525 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
526 if (p_m_b_index > -1)
527 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
528 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, (newconf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, newconf, "DSP-CONF", newconf);
530 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
535 * subfunction for bchannel_event
538 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
540 if (!mISDNport->b_sock[i].inuse)
542 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
543 add_trace("channel", NULL, "%d", i+1+(i>=15));
544 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
546 close(mISDNport->b_sock[i].fd);
547 unregister_fd(&mISDNport->b_sock[i]);
555 A bchannel goes through the following states in this order:
558 No one is using the bchannel.
559 It is available and not linked to Port class, nor reserved.
562 The bchannel stack is created and an activation request is sent.
563 It MAY be linked to Port class, but already unlinked due to Port class removal.
566 The bchannel is active and cofigured to the Port class needs.
567 Also it is linked to a Port class, otherwhise it would be deactivated.
569 - B_STATE_DEACTIVATING
570 The bchannel is in deactivating state, due to deactivation request.
571 It may be linked to a Port class, that likes to reactivate it.
575 After deactivating bchannel, and if not used, the bchannel becomes idle again.
577 A bchannel can have the following events:
580 A bchannel is required by a Port class.
583 The bchannel beomes active.
586 The bchannel is not required by Port class anymore
588 - B_EVENT_DEACTIVATED
589 The bchannel becomes inactive.
591 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
596 * process bchannel events
597 * - mISDNport is a pointer to the port's structure
598 * - i is the index of the bchannel
599 * - event is the B_EVENT_* value
600 * - port is the PmISDN class pointer
602 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
604 class PmISDN *b_port = mISDNport->b_port[i];
605 int state = mISDNport->b_state[i];
606 int timer = -1; // no change
609 char *p_m_pipeline = NULL;
610 unsigned char *p_m_crypt_key = NULL;
611 int p_m_crypt_key_len = 0;
612 int p_m_crypt_key_type = 0;
615 p_m_tx_gain = b_port->p_m_tx_gain;
616 p_m_rx_gain = b_port->p_m_rx_gain;
617 p_m_pipeline = b_port->p_m_pipeline;
618 p_m_crypt_key = b_port->p_m_crypt_key;
619 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
620 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
625 /* port must be linked in order to allow activation */
627 FATAL("bchannel must be linked to a Port class\n");
630 /* create stack and send activation request */
631 if (_bchannel_create(mISDNport, i)) {
632 _bchannel_activate(mISDNport, i, 1, 0);
633 state = B_STATE_ACTIVATING;
634 timer = B_TIMER_ACTIVATING;
638 case B_STATE_ACTIVATING:
639 /* do nothing, because it is already activating */
643 /* problems that might ocurr:
644 * B_EVENT_USE is received when channel already in use.
646 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
651 case B_EVENT_ACTIVATED:
654 case B_STATE_ACTIVATING:
656 /* bchannel is active and used by Port class, so we configure bchannel */
657 _bchannel_configure(mISDNport, i);
658 state = B_STATE_ACTIVE;
659 b_port->p_m_load = 0;
660 b_port->update_load();
662 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
663 _bchannel_activate(mISDNport, i, 0, 0);
664 state = B_STATE_DEACTIVATING;
665 timer = B_TIMER_DEACTIVATING;
670 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
676 FATAL("bchannel must be linked to a Port class\n");
679 /* bchannel is idle due to an error, so we do nothing */
682 case B_STATE_ACTIVATING:
683 /* do nothing because we must wait until bchanenl is active before deactivating */
687 /* bchannel is active, so we deactivate */
688 _bchannel_activate(mISDNport, i, 0, 0);
689 state = B_STATE_DEACTIVATING;
690 timer = B_TIMER_DEACTIVATING;
693 case B_STATE_DEACTIVATING:
694 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
698 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
702 case B_EVENT_DEACTIVATED:
706 /* ignore due to deactivation confirm after unloading */
709 case B_STATE_DEACTIVATING:
710 _bchannel_destroy(mISDNport, i);
711 state = B_STATE_IDLE;
713 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
714 if (_bchannel_create(mISDNport, i)) {
715 _bchannel_activate(mISDNport, i, 1, 0);
716 state = B_STATE_ACTIVATING;
717 timer = B_TIMER_ACTIVATING;
723 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
727 case B_EVENT_TIMEOUT:
731 /* ignore due to deactivation confirm after unloading */
734 case B_STATE_ACTIVATING:
735 _bchannel_activate(mISDNport, i, 1, 1);
736 timer = B_TIMER_ACTIVATING;
739 case B_STATE_DEACTIVATING:
740 _bchannel_activate(mISDNport, i, 0, 1);
741 timer = B_TIMER_DEACTIVATING;
745 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
750 PERROR("Illegal event %d, please correct.\n", event);
753 mISDNport->b_state[i] = state;
755 unsched_timer(&mISDNport->b_timer[i]);
757 schedule_timer(&mISDNport->b_timer[i], timer, 0);
764 * check for available channel and reserve+set it.
765 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
767 * returns -(cause value) or x = channel x or 0 = no channel
768 * NOTE: no activation is done here
770 int PmISDN::seize_bchannel(int channel, int exclusive)
774 /* the channel is what we have */
775 if (p_m_b_channel == channel)
778 /* if channel already in use, release it */
783 if (channel==CHANNEL_NO || channel==0)
786 /* is channel in range ? */
788 || (channel>p_m_mISDNport->b_num && channel<16)
789 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
790 return(-6); /* channel unacceptable */
792 /* request exclusive channel */
793 if (exclusive && channel>0) {
794 i = channel-1-(channel>16);
795 if (p_m_mISDNport->b_port[i])
796 return(-44); /* requested channel not available */
800 /* ask for channel */
802 i = channel-1-(channel>16);
803 if (p_m_mISDNport->b_port[i] == NULL)
807 /* search for channel */
809 while(i < p_m_mISDNport->b_num) {
810 if (!p_m_mISDNport->b_port[i]) {
811 channel = i+1+(i>=15);
816 return(-34); /* no free channel */
819 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
821 /* link Port, set parameters */
822 p_m_mISDNport->b_port[i] = this;
824 p_m_b_channel = channel;
825 p_m_b_exclusive = exclusive;
826 p_m_mISDNport->b_mode[i] = p_m_b_mode;
828 /* reserve channel */
829 if (!p_m_b_reserve) {
831 p_m_mISDNport->b_reserved++;
838 * drop reserved channel and unset it.
839 * deactivation is also done
841 void PmISDN::drop_bchannel(void)
843 /* unreserve channel */
845 p_m_mISDNport->b_reserved--;
854 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
856 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
857 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
858 p_m_mISDNport->b_port[p_m_b_index] = NULL;
859 p_m_mISDNport->b_mode[p_m_b_index] = 0;
869 audio transmission procedure:
870 -----------------------------
873 three sources of audio transmission:
874 - crypto-data high priority
875 - tones high priority (also high)
876 - remote-data low priority
879 a variable that temporarily shows the number of samples elapsed since last transmission process.
880 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
883 a variable that is increased whenever data is transmitted.
884 it is decreased while time elapses. it stores the number of samples that
885 are currently loaded to dsp module.
886 since clock in dsp module is the same clock for user space process, these
890 there are two levels:
891 p_m_preload will give the load that have to be kept in dsp.
892 ISDN_MAXLOAD (2*p_m_preload) will give the maximum load before dropping.
894 * procedure for low priority data
895 see txfromup() for procedure
896 in short: remote data is ignored during high priority tones
898 * procedure for high priority data
899 whenever load is below p_m_preload, load is filled up to p_m_preload
900 if no more data is available, load becomes empty again.
903 0 p_m_preload ISDN_MAXLOAD
904 +--------------------+----------------------+
906 +--------------------+----------------------+
908 on empty load or on load below p_m_preload, the load is inceased to p_m_preload:
909 0 p_m_preload ISDN_MAXLOAD
910 +--------------------+----------------------+
911 |TTTTTTTTTTTTTTTTTTTT| |
912 +--------------------+----------------------+
914 on empty load, remote-audio causes the load with the remote audio to be increased to p_m_preload.
915 0 p_m_preload ISDN_MAXLOAD
916 +--------------------+----------------------+
917 |TTTTTTTTTTTTTTTTTTTTRRRRR |
918 +--------------------+----------------------+
921 void PmISDN::update_load(void)
923 /* don't trigger load event if event already active */
924 if (p_m_loadtimer.active)
927 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
930 static int load_timer(struct lcr_timer *timer, void *instance, int index)
932 class PmISDN *isdnport = (class PmISDN *)instance;
939 void PmISDN::load_tx(void)
943 struct timeval current_time;
946 gettimeofday(¤t_time, NULL);
947 if (p_m_last_tv_sec) {
948 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
949 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
951 /* set clock of last process! */
952 p_m_last_tv_sec = current_time.tv_sec;
953 p_m_last_tv_msec = current_time.tv_usec/1000;
955 /* process only if we have samples and we are active */
956 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
961 if (elapsed < p_m_load)
966 /* to send data, tone must be on */
967 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
968 && (p_m_load < p_m_preload) /* not too much load? */
969 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
970 int tosend = p_m_preload - p_m_load, length;
971 unsigned char buf[MISDN_HEADER_LEN+tosend];
972 struct mISDNhead *frm = (struct mISDNhead *)buf;
973 unsigned char *p = buf+MISDN_HEADER_LEN;
975 /* copy inband signalling (e.g. used by ss5) */
976 if (p_m_inband_send_on && tosend) {
977 tosend -= inband_send(p, tosend);
980 /* copy crypto loops */
981 while (p_m_crypt_msg_loops && tosend) {
982 /* how much do we have to send */
983 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
989 /* copy message (part) to buffer */
990 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
993 p_m_crypt_msg_current += length;
994 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
996 p_m_crypt_msg_current = 0;
997 p_m_crypt_msg_loops--;
998 if (!p_m_crypt_msg_loops)
1000 // puts("eine loop weniger");
1008 if (p_tone_name[0] && tosend) {
1009 tosend -= read_audio(p, tosend);
1013 if (p_m_preload - p_m_load - tosend > 0) {
1014 frm->prim = PH_DATA_REQ;
1016 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+p_m_preload-p_m_load-tosend, 0, NULL, 0);
1018 PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_preload-p_m_load-tosend);
1019 p_m_load += p_m_preload - p_m_load - tosend;
1024 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
1027 /* handle timeouts */
1028 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1030 class PmISDN *isdnport = (class PmISDN *)instance;
1031 struct lcr_msg *message;
1033 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", isdnport->p_name, isdnport->p_m_timeout.timeout.tv_sec, isdnport->p_state);
1034 /* send timeout to endpoint */
1035 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1036 message->param.state = isdnport->p_state;
1037 message_put(message);
1044 * whenever we get audio data from bchannel, we process it here
1046 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1048 unsigned int cont = *((unsigned int *)data);
1049 struct lcr_msg *message;
1053 if (hh->prim == PH_CONTROL_IND) {
1055 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1058 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1059 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1060 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1062 add_trace("info", NULL, "DTMF is disabled");
1066 if (p_type == PORT_TYPE_POTS_FXS_IN && p_state == PORT_STATE_IN_OVERLAP) {
1067 class Pfxs *pfxs = (class Pfxs *)this;
1068 if (!pfxs->p_m_fxs_allow_dtmf) {
1069 PDEBUG(DEBUG_PORT, "PmISDN(%s) DTMF for FXS currently disabled\n", p_name);
1072 SCCAT(p_dialinginfo.id, cont & DTMF_TONE_MASK);
1073 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
1074 message->param.information.id[0] = cont & DTMF_TONE_MASK;
1075 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION INFORMATION digit '%s'\n", p_name, message->param.information.id);
1076 message_put(message);
1078 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1079 message->param.dtmf = cont & DTMF_TONE_MASK;
1080 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1081 message_put(message);
1087 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1088 add_trace("DSP-CRYPT", NULL, "error");
1090 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1091 message->param.crypt.type = CC_ERROR_IND;
1092 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1093 message_put(message);
1097 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1098 add_trace("DSP-CRYPT", NULL, "ok");
1100 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1101 message->param.crypt.type = CC_ACTBF_CONF;
1102 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1103 message_put(message);
1107 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1108 add_trace("unknown", NULL, "0x%x", cont);
1113 if (hh->prim == PH_CONTROL_IND) {
1116 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1117 add_trace("unknown", NULL, "0x%x", hh->id);
1122 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1124 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1125 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1128 /* see below (same condition) */
1129 if (p_state!=PORT_STATE_CONNECT
1130 && !p_m_mISDNport->tones)
1132 // printf(".");fflush(stdout);return;
1134 record(data, len, 1); // from up
1136 tap(data, len, 1); // from up
1139 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1140 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1144 /* inband is processed */
1145 if (p_m_inband_receive_on)
1146 inband_receive(data, len);
1148 /* send to remote, if bridged */
1149 bridge_tx(data, len);
1151 /* calls will not process any audio data unless
1152 * the call is connected OR tones feature is enabled.
1154 #ifndef DEBUG_COREBRIDGE
1155 if (p_state!=PORT_STATE_CONNECT
1156 && !p_m_mISDNport->tones)
1161 /* the bearer capability must be audio in order to send and receive
1162 * audio prior or after connect.
1164 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1168 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1170 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1176 record(data, len, 0); // from down
1178 tap(data, len, 0); // from down
1180 /* randomize and listen to crypt message if enabled */
1181 if (p_m_crypt_listen) {
1182 /* the noisy randomizer */
1186 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1188 cryptman_listen_bch(data, len);
1196 void PmISDN::set_echotest(int echo)
1198 if (p_m_echo != echo) {
1200 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1202 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1203 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1210 void PmISDN::set_tone(const char *dir, const char *tone)
1215 /* if no directory is given (by extension), we use interface.conf or options.conf */
1216 if (!dir || !dir[0]) {
1217 if (p_m_mISDNport->ifport->tones_dir[0])
1218 dir = p_m_mISDNport->ifport->tones_dir;
1219 else if (options.tones_dir[0])
1220 dir = options.tones_dir;
1225 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1231 /* check for dsp tones */
1232 if (!strcmp(dir, "american"))
1234 if (!strcmp(dir, "german"))
1236 if (!strcmp(dir, "oldgerman"))
1237 dsp = DSP_OLDGERMAN;
1239 /* check if we NOT really have to use a dsp-tone */
1240 if (dsp == DSP_NONE) {
1243 if (p_m_b_index > -1)
1244 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1245 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1246 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1249 Port::set_tone(dir, tone);
1253 /* now we USE dsp-tone, convert name */
1254 if (!strcmp(tone, "dialtone")) {
1256 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1257 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1258 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1260 } else if (!strcmp(tone, "dialpbx")) {
1262 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1263 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1264 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1266 } else if (!strcmp(tone, "ringing")) {
1268 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1269 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1270 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1272 } else if (!strcmp(tone, "ringpbx")) {
1274 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1275 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1276 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1278 } else if (!strcmp(tone, "busy")) {
1281 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1282 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1283 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1285 } else if (!strcmp(tone, "release")) {
1288 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1289 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1290 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1292 } else if (!strcmp(tone, "cause_10"))
1294 else if (!strcmp(tone, "cause_11"))
1296 else if (!strcmp(tone, "cause_22")) {
1298 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1299 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1300 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1302 } else if (!strncmp(tone, "cause_", 6))
1303 id = TONE_SPECIAL_INFO;
1307 /* if we have a tone that is not supported by dsp */
1308 if (id==TONE_OFF && tone[0])
1312 if (p_m_tone != id) {
1315 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1316 if (p_m_b_index > -1)
1317 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1318 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1320 /* turn user-space tones off in cases of no tone OR dsp tone */
1321 Port::set_tone("",NULL);
1325 /* MESSAGE_mISDNSIGNAL */
1326 //extern struct lcr_msg *dddebug;
1327 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1329 int oldconf, newconf;
1330 switch(param->mISDNsignal.message) {
1331 case mISDNSIGNAL_VOLUME:
1332 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1333 p_m_tx_gain = param->mISDNsignal.tx_gain;
1334 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1335 if (p_m_b_index > -1)
1336 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1337 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1339 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1340 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1341 p_m_rx_gain = param->mISDNsignal.rx_gain;
1342 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1343 if (p_m_b_index > -1)
1344 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1345 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1347 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1350 case mISDNSIGNAL_CONF:
1351 oldconf = p_m_mute?0:p_m_conf;
1352 p_m_conf = param->mISDNsignal.conf;
1353 newconf = p_m_mute?0:p_m_conf;
1354 set_conf(oldconf, newconf);
1357 case mISDNSIGNAL_DELAY:
1358 if (p_m_delay != param->mISDNsignal.delay) {
1359 p_m_delay = param->mISDNsignal.delay;
1360 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1361 if (p_m_b_index > -1)
1362 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1363 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1365 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1369 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1374 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1376 struct lcr_msg *message;
1378 switch(param->crypt.type) {
1379 case CC_ACTBF_REQ: /* activate blowfish */
1381 p_m_crypt_key_len = param->crypt.len;
1382 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1383 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1384 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1385 message->param.crypt.type = CC_ERROR_IND;
1386 message_put(message);
1389 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1391 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1392 if (p_m_b_index > -1)
1393 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1394 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1397 case CC_DACT_REQ: /* deactivate session encryption */
1402 case CR_LISTEN_REQ: /* start listening to messages */
1403 p_m_crypt_listen = 1;
1405 p_m_crypt_listen_state = 0;
1408 case CR_UNLISTEN_REQ: /* stop listening to messages */
1409 p_m_crypt_listen = 0;
1413 case CR_MESSAGE_REQ: /* send message */
1414 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1415 if (!p_m_crypt_msg_len) {
1416 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1419 p_m_crypt_msg_current = 0; /* reset */
1420 p_m_crypt_msg_loops = 6; /* enable */
1423 /* disable txmix, or we get corrupt data due to audio process */
1424 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1425 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1426 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1432 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1438 * endpoint sends messages to the port
1440 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1442 if (Port::message_epoint(epoint_id, message_id, param)) {
1443 if (message_id == MESSAGE_BRIDGE)
1448 switch(message_id) {
1449 case MESSAGE_mISDNSIGNAL: /* user command */
1450 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1451 message_mISDNsignal(epoint_id, message_id, param);
1454 case MESSAGE_CRYPT: /* crypt control command */
1455 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1456 message_crypt(epoint_id, message_id, param);
1459 case MESSAGE_DISABLE_DEJITTER:
1460 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received de-jitter disable order.\n", p_name);
1461 p_m_disable_dejitter = 1;
1462 p_m_preload = param->queue;
1470 void PmISDN::update_rxoff(void)
1472 int tx_dejitter = 0;
1474 /* call bridges in user space OR crypto OR recording */
1475 if (p_bridge || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_tap || p_m_inband_receive_on) {
1476 /* rx IS required */
1480 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1481 if (p_m_b_index > -1)
1482 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1483 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1486 /* rx NOT required */
1490 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1491 if (p_m_b_index > -1)
1492 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1493 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1496 /* recording / tapping */
1497 if (p_record || p_tap) {
1498 /* txdata IS required */
1502 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1503 if (p_m_b_index > -1)
1504 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1505 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1508 /* txdata NOT required */
1512 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1513 if (p_m_b_index > -1)
1514 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1515 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1518 /* dejitter on bridge */
1519 if (p_bridge && !p_m_disable_dejitter)
1521 if (p_m_tx_dejitter != tx_dejitter) {
1522 p_m_tx_dejitter = tx_dejitter;
1523 PDEBUG(DEBUG_BCHANNEL, "we change dejitter mode to %s.\n", (p_m_tx_dejitter) ? "on" : "off");
1524 if (p_m_b_index > -1)
1525 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1526 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TX_DEJITTER, p_m_tx_dejitter, "DSP-TX_DEJITTER", p_m_tx_dejitter);
1530 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1532 struct mISDNport *mISDNport;
1538 /* unset global semaphore */
1540 // with a very small incident, upqueue_avail may be set by mISDN thread and
1541 // another byte may be sent to the pipe, which causes a call to this function
1542 // again with nothing in the upqueue. this is no problem.
1543 ret = read(fd->fd, &byte, 1);
1545 /* process all ports */
1546 mISDNport = mISDNport_first;
1548 /* handle queued up-messages (d-channel) */
1549 while ((mb = mdequeue(&mISDNport->upqueue))) {
1552 case MPH_ACTIVATE_IND:
1553 if (mISDNport->l1link != 1) {
1554 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1556 mISDNport->l1link = 1;
1560 case MPH_DEACTIVATE_IND:
1561 if (mISDNport->l1link != 0) {
1562 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1564 mISDNport->l1link = 0;
1568 case MPH_INFORMATION_IND:
1569 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1571 case L1_SIGNAL_LOS_ON:
1574 case L1_SIGNAL_LOS_OFF:
1577 case L1_SIGNAL_AIS_ON:
1580 case L1_SIGNAL_AIS_OFF:
1583 case L1_SIGNAL_RDI_ON:
1586 case L1_SIGNAL_RDI_OFF:
1589 case L1_SIGNAL_SLIP_TX:
1590 mISDNport->slip_tx++;
1592 case L1_SIGNAL_SLIP_RX:
1593 mISDNport->slip_rx++;
1598 case MT_L2ESTABLISH:
1599 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1600 add_trace("tei", NULL, "%d", l3m->pid);
1602 mISDNport->l2link = 1;
1604 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1605 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1606 if (mISDNport->l2establish.active) {
1607 unsched_timer(&mISDNport->l2establish);
1608 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1615 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1616 if (!mISDNport->l2establish.active) {
1617 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1618 add_trace("tei", NULL, "%d", l3m->pid);
1620 /* down if not nt-ptmp */
1621 if (!mISDNport->ntmode || mISDNport->ptp)
1622 mISDNport->l2link = 0;
1624 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1625 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1626 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1627 schedule_timer(&mISDNport->l2establish, 5, 0);
1628 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1634 /* l3-data is sent to LCR */
1635 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1640 mISDNport = mISDNport->next;
1645 /* l2 establish timer fires */
1646 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1648 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1650 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1651 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1652 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1653 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1659 /* handle frames from bchannel */
1660 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1662 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1663 unsigned char buffer[2048+MISDN_HEADER_LEN];
1664 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1667 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1669 PERROR("read error frame, errno %d\n", errno);
1672 if (ret < (int)MISDN_HEADER_LEN) {
1673 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1677 /* we don't care about confirms, we use rx data to sync tx */
1681 /* we receive audio data, we respond to it AND we send tones */
1686 case PH_CONTROL_IND:
1687 if (mISDNport->b_port[i])
1688 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1690 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1693 case PH_ACTIVATE_IND:
1694 case DL_ESTABLISH_IND:
1695 case PH_ACTIVATE_CNF:
1696 case DL_ESTABLISH_CNF:
1697 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1698 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1701 case PH_DEACTIVATE_IND:
1702 case DL_RELEASE_IND:
1703 case PH_DEACTIVATE_CNF:
1704 case DL_RELEASE_CNF:
1705 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
1706 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1710 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
1716 /* process timer events for bchannel handling */
1717 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
1719 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1721 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1727 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1731 * l3m must be queued, except for MT_ASSIGN
1734 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
1737 #ifdef OLD_MT_ASSIGN
1738 /* special MT_ASSIGN handling:
1740 * if we request a PID from mlayer, we always do it while lcr is locked.
1741 * therefore we must check the MT_ASSIGN reply first before we lock.
1742 * this is because the MT_ASSIGN reply is received with the requesting
1743 * process, not by the mlayer thread!
1744 * this means, that the reply is sent during call of the request.
1745 * we must check if we get a reply and we know that we lcr is currently
1748 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
1749 /* let's do some checking if someone changes stack behaviour */
1750 if (mt_assign_pid != 0)
1751 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
1752 mt_assign_pid = pid;
1756 /* queue message, create, if required */
1758 l3m = alloc_l3_msg();
1760 FATAL("No memory for layer 3 message\n");
1762 mb = container_of(l3m, struct mbuffer, l3);
1765 mqueue_tail(&mISDNport->upqueue, mb);
1766 if (!upqueue_avail) {
1767 // multiple threads may cause multiple calls of this section, but this
1768 // results only in multiple processing of the upqueue read.
1769 // this is no problem.
1773 ret = write(upqueue_pipe[1], &byte, 1);
1778 int mISDN_getportbyname(int sock, int cnt, char *portname)
1780 struct mISDN_devinfo devinfo;
1784 while (port < cnt) {
1786 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
1789 if (!strcasecmp(devinfo.name, portname))
1799 /* handle frames from pots */
1800 static int pots_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1802 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1803 unsigned char buffer[2048+MISDN_HEADER_LEN];
1804 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1808 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1810 PERROR("read error frame, errno %d\n", errno);
1813 if (ret < (int)MISDN_HEADER_LEN) {
1814 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1818 case PH_CONTROL_IND:
1819 cont = *((unsigned int *)(buffer + MISDN_HEADER_LEN));
1820 /* l1-control is sent to LCR */
1821 if (mISDNport->ntmode)
1822 stack2manager_fxs(mISDNport, cont);
1824 PERROR("FXO not supported!\n");
1826 case PH_ACTIVATE_REQ:
1830 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
1837 * global function to add a new card (port)
1839 struct mISDNport *mISDNport_open(struct interface_port *ifport)
1842 struct mISDNport *mISDNport, **mISDNportp;
1843 int port = ifport->portnum;
1844 int ptp = ifport->ptp;
1845 int force_nt = ifport->nt;
1846 int l1hold = ifport->l1hold;
1847 int l2hold = ifport->l2hold;
1848 int ss5 = ifport->ss5;
1852 // struct mlayer3 *ml3;
1853 struct mISDN_devinfo devinfo;
1854 unsigned int protocol, prop;
1856 /* check port counts */
1857 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
1859 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
1864 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
1868 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
1870 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
1873 // note: 'port' has still the port number
1875 if (port>cnt || port<0) {
1876 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
1880 /* get port attributes */
1881 pri = bri = pots = nt = te = 0;
1883 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
1885 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
1888 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
1892 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
1896 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
1900 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
1904 #ifdef ISDN_P_FXS_POTS
1905 if (devinfo.Dprotocols & (1 << ISDN_P_FXO_POTS)) {
1909 if (devinfo.Dprotocols & (1 << ISDN_P_FXS_POTS)) {
1914 if (force_nt && !nt) {
1916 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
1918 PERROR_RUNTIME("Port %d does not support FXS-mode\n", port);
1922 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
1925 if (!bri && !pri && !pots) {
1926 PERROR_RUNTIME("Port %d does not support BRI nor PRI nor POTS!\n", port);
1930 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
1933 /* set NT by turning off TE */
1936 /* if TE an NT is supported (and not forced to NT), turn off NT */
1940 PERROR_RUNTIME("Port %d uses FXO-mode, but not supported by LCR!\n", port);
1944 /* check for double use of port */
1946 mISDNport = mISDNport_first;
1948 if (mISDNport->portnum == port)
1950 mISDNport = mISDNport->next;
1953 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
1958 /* check for continous channelmap with no bchannel on slot 16 */
1959 if (test_channelmap(0, devinfo.channelmap)) {
1960 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
1964 while(i < (int)devinfo.nrbchan + 1) {
1966 if (test_channelmap(i, devinfo.channelmap)) {
1967 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
1971 if (!test_channelmap(i, devinfo.channelmap)) {
1972 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
1979 /* add mISDNport structure */
1980 mISDNportp = &mISDNport_first;
1982 mISDNportp = &((*mISDNportp)->next);
1983 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
1984 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
1986 /* ss5 link is always active */
1987 mISDNport->l1link = 1;
1988 mISDNport->l2link = 1;
1990 mISDNport->l1link = -1;
1991 mISDNport->l2link = -1;
1994 *mISDNportp = mISDNport;
1996 /* if pri, must set PTP */
2000 /* set ss5 params */
2002 /* try to keep interface enabled */
2022 /* allocate ressources of port */
2025 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2026 prop = (1 << MISDN_FLG_L2_CLEAN);
2027 if (ptp) // ptp forced
2028 prop |= (1 << MISDN_FLG_PTP);
2029 if (nt) // supports hold/retrieve on nt-mode
2030 prop |= (1 << MISDN_FLG_NET_HOLD);
2031 if (l1hold) // supports layer 1 hold
2032 prop |= (1 << MISDN_FLG_L1_HOLD);
2033 if (l2hold) // supports layer 2 hold
2034 prop |= (1 << MISDN_FLG_L2_HOLD);
2035 /* open layer 3 and init upqueue */
2036 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2037 mqueue_init(&mISDNport->upqueue);
2038 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2039 if (!mISDNport->ml3) {
2040 mqueue_purge(&mISDNport->upqueue);
2041 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2049 "PORT (open failed)");
2051 mISDNport_close(mISDNport);
2055 #ifdef ISDN_P_FXS_POTS
2058 struct sockaddr_mISDN addr;
2059 struct mISDNhead act;
2062 /* queue must be initializes, because even pots interfaces are checked at mISDN_upqueue loop */
2063 mqueue_init(&mISDNport->upqueue);
2064 sock = socket(PF_ISDN, SOCK_DGRAM, (nt) ? ISDN_P_FXS_POTS : ISDN_P_FXO_POTS);
2066 PERROR_RUNTIME("Cannot open mISDN due to '%s'.\n", strerror(errno));
2069 /* bind socket to dchannel */
2070 addr.family = AF_ISDN;
2073 ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
2075 PERROR_RUNTIME("Error: Failed to bind pots control channel\n");
2083 "PORT (open failed)");
2087 act.prim = PH_ACTIVATE_REQ;
2089 ret = sendto(sock, &act, MISDN_HEADER_LEN, 0, NULL, 0);
2091 PERROR("Failed to send to socket %d\n", sock);
2092 mISDNport->pots_sock.fd = sock;
2093 register_fd(&mISDNport->pots_sock, LCR_FD_READ, pots_sock_callback, mISDNport, i);
2097 SCPY(mISDNport->name, devinfo.name);
2098 mISDNport->b_num = devinfo.nrbchan;
2099 mISDNport->portnum = port;
2100 mISDNport->ntmode = nt;
2101 mISDNport->pots = pots;
2102 mISDNport->tespecial = ifport->tespecial;
2103 mISDNport->pri = pri;
2104 mISDNport->ptp = ptp;
2105 mISDNport->l1hold = l1hold;
2106 mISDNport->l2hold = l2hold;
2107 mISDNport->ss5 = ss5;
2108 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2110 while(i < mISDNport->b_num) {
2111 mISDNport->b_state[i] = B_STATE_IDLE;
2112 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2116 /* if ptp, pull up the link */
2117 if (!pots && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2118 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2119 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2120 add_trace("tei", NULL, "%d", 0);
2122 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2125 /* for POTS or nt-mode ptmp the link is always up */
2126 if (pots || (mISDNport->ntmode && !mISDNport->ptp))
2127 mISDNport->l2link = 1;
2129 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2131 start_trace(mISDNport->portnum,
2140 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2142 add_trace("mode", NULL, (mISDNport->ntmode)?"FXS":"FXO");
2143 add_trace("channels", NULL, "%d", mISDNport->b_num);
2145 add_trace("ccitt#5", NULL, "enabled");
2153 * load static port instances, if required by mISDNport
2155 void mISDNport_static(struct mISDNport *mISDNport)
2160 while(i < mISDNport->b_num) {
2163 ss5_create_channel(mISDNport, i);
2171 * function to free ALL cards (ports)
2173 void mISDNport_close_all(void)
2175 /* free all ports */
2176 while(mISDNport_first)
2177 mISDNport_close(mISDNport_first);
2181 * free only one port
2183 void mISDNport_close(struct mISDNport *mISDNport)
2185 struct mISDNport **mISDNportp;
2187 class PmISDN *isdnport;
2190 /* remove all port instance that are linked to this mISDNport */
2194 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2195 isdnport = (class PmISDN *)port;
2196 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2197 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2205 /* only if we are already part of interface */
2206 if (mISDNport->ifport) {
2207 start_trace(mISDNport->portnum,
2208 mISDNport->ifport->interface,
2218 /* free bchannels */
2220 while(i < mISDNport->b_num) {
2221 if (mISDNport->b_sock[i].inuse) {
2222 _bchannel_destroy(mISDNport, i);
2223 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2225 if (mISDNport->b_timer[i].inuse) {
2226 del_timer(&mISDNport->b_timer[i]);
2230 del_timer(&mISDNport->l2establish);
2232 /* close layer 3, if open */
2233 if (mISDNport->ml3) {
2234 close_layer3(mISDNport->ml3);
2237 /* close layer 1, if open */
2238 if (mISDNport->pots_sock.fd) {
2239 unregister_fd(&mISDNport->pots_sock);
2240 close(mISDNport->pots_sock.fd);
2244 mqueue_purge(&mISDNport->upqueue);
2246 /* remove from list */
2247 mISDNportp = &mISDNport_first;
2248 while(*mISDNportp) {
2249 if (*mISDNportp == mISDNport) {
2250 *mISDNportp = (*mISDNportp)->next;
2254 mISDNportp = &((*mISDNportp)->next);
2258 FATAL("mISDNport not in list\n");
2260 FREE(mISDNport, sizeof(struct mISDNport));
2267 * enque data from remote port
2269 int PmISDN::bridge_rx(unsigned char *data, int length)
2271 unsigned char buf[MISDN_HEADER_LEN+((length>p_m_preload)?length:p_m_preload)];
2272 struct mISDNhead *hh = (struct mISDNhead *)buf;
2275 if (p_m_b_index < 0)
2277 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2280 /* check if high priority tones exist
2281 * ignore data in this case
2283 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2286 /* preload procedure
2287 * if transmit buffer in DSP module is empty,
2288 * preload it to DSP_LOAD to prevent jitter gaps.
2290 * if load runs empty, preload again.
2292 if (p_m_disable_dejitter && p_m_load == 0 && p_m_preload > 0) {
2293 //printf("preload=%d\n", p_m_preload);
2294 hh->prim = PH_DATA_REQ;
2296 memset(buf+MISDN_HEADER_LEN, silence, p_m_preload);
2297 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+p_m_preload, 0, NULL, 0);
2299 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2300 p_m_load += p_m_preload;
2301 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
2304 /* drop if load would exceed ISDN_MAXLOAD
2305 * this keeps the delay not too high
2307 //printf("load=%d len=%d 2*preload=%d\n", p_m_load, length, p_m_preload << 1);
2308 if (p_m_disable_dejitter && p_m_preload > 0 && p_m_load+length > (p_m_preload << 1))
2311 /* make and send frame */
2312 hh->prim = PH_DATA_REQ;
2314 memcpy(buf+MISDN_HEADER_LEN, data, length);
2315 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2317 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2323 int PmISDN::inband_send(unsigned char *buffer, int len)
2325 PERROR("this function must be derived to function!\n");
2329 void PmISDN::inband_send_on(void)
2331 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2332 p_m_inband_send_on = 1;
2335 void PmISDN::inband_send_off(void)
2337 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2338 p_m_inband_send_on = 0;
2341 void PmISDN::inband_receive(unsigned char *buffer, int len)
2344 // if (len >= SS5_DECODER_NPOINTS)
2345 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2346 PERROR("this function must be derived to function!\n");
2349 void PmISDN::inband_receive_on(void)
2351 /* this must work during constructor, see ss5.cpp */
2352 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2353 p_m_inband_receive_on = 1;
2357 void PmISDN::inband_receive_off(void)
2359 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2360 p_m_inband_receive_on = 0;
2364 void PmISDN::mute_on(void)
2368 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2370 set_conf(p_m_conf, 0);
2373 void PmISDN::mute_off(void)
2377 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2379 set_conf(0, p_m_conf);