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)
67 /* try to open raw socket to check kernel */
68 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
69 if (mISDNsocket < 0) {
70 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
75 // set debug printout function
76 myfn.prt_debug = my_mISDNlib_debug;
78 init_layer3(4, &myfn); // buffer of 4
80 /* open debug, if enabled and not only stack debugging */
82 SPRINT(filename, "%s/debug.log", LOG_DIR);
83 debug_fp = fopen(filename, "a");
86 if (options.deb & DEBUG_STACK)
87 mISDN_set_debug_level(0xfffffeff);
89 mISDN_set_debug_level(0);
91 if (pipe(upqueue_pipe) < 0)
92 FATAL("Failed to open pipe\n");
93 memset(&upqueue_fd, 0, sizeof(upqueue_fd));
94 upqueue_fd.fd = upqueue_pipe[0];
95 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
100 void mISDN_deinitialize(void)
108 if (mISDNsocket > -1)
111 if (upqueue_fd.inuse) {
112 unregister_fd(&upqueue_fd);
113 close(upqueue_pipe[0]);
114 close(upqueue_pipe[1]);
119 static int load_timer(struct lcr_timer *timer, void *instance, int index);
124 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)
126 p_m_mISDNport = mISDNport;
127 p_m_portnum = mISDNport->portnum;
134 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
135 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
141 p_m_preload = ISDN_LOAD;
142 p_m_disable_dejitter = 0;
146 p_m_inband_send_on = 0;
147 p_m_inband_receive_on = 0;
148 p_m_dtmf = !mISDNport->ifport->nodtmf;
149 p_m_dtmf_threshold = mISDNport->ifport->dtmf_threshold;
150 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
151 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
152 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
155 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
156 add_timer(&p_m_loadtimer, load_timer, this, 0);
162 p_m_crypt_listen = 0;
163 p_m_crypt_msg_loops = 0;
164 p_m_crypt_msg_loops = 0;
165 p_m_crypt_msg_len = 0;
166 p_m_crypt_msg[0] = '\0';
167 p_m_crypt_msg_current = 0;
168 p_m_crypt_key_len = 0;
169 p_m_crypt_listen = 0;
170 p_m_crypt_listen_state = 0;
171 p_m_crypt_listen_len = 0;
172 p_m_crypt_listen_msg[0] = '\0';
173 p_m_crypt_listen_crc = 0;
174 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
175 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
176 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
180 /* if any channel requested by constructor */
181 if (channel == CHANNEL_ANY) {
182 /* reserve channel */
184 mISDNport->b_reserved++;
187 /* reserve channel */
188 if (channel > 0) // only if constructor was called with a channel resevation
189 seize_bchannel(channel, exclusive);
191 /* we increase the number of objects: */
193 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
194 //inband_receive_on();
203 struct lcr_msg *message;
205 del_timer(&p_m_timeout);
206 del_timer(&p_m_loadtimer);
208 /* remove bchannel relation */
212 while (p_epointlist) {
213 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
214 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
215 message->param.disconnectinfo.cause = 16;
216 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
217 message_put(message);
218 /* remove from list */
219 free_epointlist(p_epointlist);
222 /* we decrease the number of objects: */
223 p_m_mISDNport->use--;
224 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
231 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
233 /* init trace with given values */
234 start_trace(mISDNport?mISDNport->portnum:-1,
235 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
236 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
237 port?port->p_dialinginfo.id:NULL,
240 port?port->p_serial:0,
248 static struct isdn_message {
252 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
253 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
254 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
255 {"DL_RELEASE", L2_RELEASE_REQ},
256 {"UNKNOWN", L3_UNKNOWN_REQ},
257 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
258 {"MT_SETUP", L3_SETUP_REQ},
259 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
260 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
261 {"MT_ALERTING", L3_ALERTING_REQ},
262 {"MT_CONNECT", L3_CONNECT_REQ},
263 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
264 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
265 {"MT_RELEASE", L3_RELEASE_REQ},
266 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
267 {"MT_INFORMATION", L3_INFORMATION_REQ},
268 {"MT_PROGRESS", L3_PROGRESS_REQ},
269 {"MT_NOTIFY", L3_NOTIFY_REQ},
270 {"MT_SUSPEND", L3_SUSPEND_REQ},
271 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
272 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
273 {"MT_RESUME", L3_RESUME_REQ},
274 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
275 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
276 {"MT_HOLD", L3_HOLD_REQ},
277 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
278 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
279 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
280 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
281 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
282 {"MT_FACILITY", L3_FACILITY_REQ},
283 {"MT_STATUS", L3_STATUS_REQ},
284 {"MT_RESTART", L3_RESTART_REQ},
285 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
286 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
289 static const char *isdn_prim[4] = {
295 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
300 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
301 /* select message and primitive text */
303 while(isdn_message[i].name) {
304 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
305 if (isdn_message[i].value == (msg&0xffffff00)) {
306 SCPY(msgtext, isdn_message[i].name);
311 SCAT(msgtext, isdn_prim[msg&0x00000003]);
314 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
316 if (mISDNport->ntmode) {
317 if (direction == DIRECTION_OUT)
318 SCAT(msgtext, " N->U");
320 SCAT(msgtext, " N<-U");
322 if (direction == DIRECTION_OUT)
323 SCAT(msgtext, " U->N");
325 SCAT(msgtext, " U<-N");
330 /* init trace with given values */
331 start_trace(mISDNport?mISDNport->portnum:-1,
332 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
333 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
334 port?port->p_dialinginfo.id:NULL,
337 port?port->p_serial:0,
343 * send control information to the channel (dsp-module)
345 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
347 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
348 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
349 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
356 if (c1 == DTMF_TONE_START && c2 == 0) {
360 ctrl->prim = PH_CONTROL_REQ;
364 ret = sendto(sock, buffer, MISDN_HEADER_LEN+len, 0, NULL, 0);
366 PERROR("Failed to send to socket %d\n", sock);
367 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
368 if (c1 == DSP_CONF_JOIN)
369 add_trace(trace_name, NULL, "0x%08x", trace_value);
371 add_trace(trace_name, NULL, "%d", trace_value);
375 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)
377 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
378 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
379 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
385 ctrl->prim = PH_CONTROL_REQ;
388 memcpy(d, c2, c2_len);
389 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
391 PERROR("Failed to send to socket %d\n", sock);
392 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
393 add_trace(trace_name, NULL, "%d", trace_value);
397 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
400 * subfunction for bchannel_event
403 static int _bchannel_create(struct mISDNport *mISDNport, int i)
406 struct sockaddr_mISDN addr;
408 memset(&addr, 0, sizeof(addr));
410 if (mISDNport->b_sock[i].inuse) {
411 PERROR("Error: Socket already created for index %d\n", i);
416 //#warning testing without DSP
417 // 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);
418 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);
419 if (mISDNport->b_sock[i].fd < 0) {
420 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
424 /* register callback for read */
425 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
427 /* bind socket to bchannel */
428 addr.family = AF_ISDN;
429 addr.dev = mISDNport->portnum;
430 addr.channel = i+1+(i>=15);
431 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
433 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);
434 close(mISDNport->b_sock[i].fd);
435 unregister_fd(&mISDNport->b_sock[i]);
439 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
440 add_trace("channel", NULL, "%d", i+1+(i>=15));
441 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
449 * subfunction for bchannel_event
450 * activate / deactivate request
452 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
454 struct mISDNhead act;
457 if (!mISDNport->b_sock[i].inuse)
459 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
461 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
463 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
466 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
467 add_trace("channel", NULL, "%d", i+1+(i>=15));
469 add_trace("event", NULL, "timeout recovery");
475 * subfunction for bchannel_event
478 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
483 if (!mISDNport->b_sock[i].inuse)
485 handle = mISDNport->b_sock[i].fd;
486 port = mISDNport->b_port[i];
487 mode = mISDNport->b_mode[i];
489 PERROR("bchannel index i=%d not associated with a port object\n", i);
493 /* set dsp features */
494 if (port->p_m_txdata)
495 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
496 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
497 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
498 if (port->p_m_tx_dejitter && mode == B_MODE_TRANSPARENT)
499 ph_control(mISDNport, port, handle, DSP_TX_DEJITTER, port->p_m_tx_dejitter, "DSP-TX_DEJITTER", port->p_m_tx_dejitter);
500 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
501 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
502 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
503 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
504 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
505 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
506 if (port->p_m_conf && !port->p_m_mute)
507 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
509 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
510 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
511 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
513 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
514 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
515 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
516 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
517 ph_control(mISDNport, port, handle, DTMF_TONE_START, port->p_m_dtmf_threshold, "DSP-DTMF", 1);
518 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
519 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);
523 void PmISDN::set_conf(int oldconf, int newconf)
525 if (oldconf != newconf) {
526 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
527 if (p_m_b_index > -1)
528 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
529 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);
531 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
536 * subfunction for bchannel_event
539 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
541 if (!mISDNport->b_sock[i].inuse)
543 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
544 add_trace("channel", NULL, "%d", i+1+(i>=15));
545 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
547 close(mISDNport->b_sock[i].fd);
548 unregister_fd(&mISDNport->b_sock[i]);
556 A bchannel goes through the following states in this order:
559 No one is using the bchannel.
560 It is available and not linked to Port class, nor reserved.
563 The bchannel stack is created and an activation request is sent.
564 It MAY be linked to Port class, but already unlinked due to Port class removal.
567 The bchannel is active and cofigured to the Port class needs.
568 Also it is linked to a Port class, otherwhise it would be deactivated.
570 - B_STATE_DEACTIVATING
571 The bchannel is in deactivating state, due to deactivation request.
572 It may be linked to a Port class, that likes to reactivate it.
576 After deactivating bchannel, and if not used, the bchannel becomes idle again.
578 A bchannel can have the following events:
581 A bchannel is required by a Port class.
584 The bchannel beomes active.
587 The bchannel is not required by Port class anymore
589 - B_EVENT_DEACTIVATED
590 The bchannel becomes inactive.
592 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
597 * process bchannel events
598 * - mISDNport is a pointer to the port's structure
599 * - i is the index of the bchannel
600 * - event is the B_EVENT_* value
601 * - port is the PmISDN class pointer
603 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
605 class PmISDN *b_port = mISDNport->b_port[i];
606 int state = mISDNport->b_state[i];
607 int timer = -1; // no change
611 char *p_m_pipeline = NULL;
612 unsigned char *p_m_crypt_key = NULL;
613 int p_m_crypt_key_len = 0;
614 int p_m_crypt_key_type = 0;
617 p_m_tx_gain = b_port->p_m_tx_gain;
618 p_m_rx_gain = b_port->p_m_rx_gain;
619 p_m_pipeline = b_port->p_m_pipeline;
620 p_m_crypt_key = b_port->p_m_crypt_key;
621 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
622 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
628 /* port must be linked in order to allow activation */
630 FATAL("bchannel must be linked to a Port class\n");
633 /* create stack and send activation request */
634 if (_bchannel_create(mISDNport, i)) {
635 _bchannel_activate(mISDNport, i, 1, 0);
636 state = B_STATE_ACTIVATING;
637 timer = B_TIMER_ACTIVATING;
641 case B_STATE_ACTIVATING:
642 /* do nothing, because it is already activating */
646 /* problems that might ocurr:
647 * B_EVENT_USE is received when channel already in use.
649 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
654 case B_EVENT_ACTIVATED:
657 case B_STATE_ACTIVATING:
659 /* bchannel is active and used by Port class, so we configure bchannel */
660 _bchannel_configure(mISDNport, i);
661 state = B_STATE_ACTIVE;
662 b_port->p_m_load = 0;
663 b_port->update_load();
665 /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
666 _bchannel_activate(mISDNport, i, 0, 0);
667 state = B_STATE_DEACTIVATING;
668 timer = B_TIMER_DEACTIVATING;
673 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
679 FATAL("bchannel must be linked to a Port class\n");
682 /* bchannel is idle due to an error, so we do nothing */
685 case B_STATE_ACTIVATING:
686 /* do nothing because we must wait until bchanenl is active before deactivating */
690 /* bchannel is active, so we deactivate */
691 _bchannel_activate(mISDNport, i, 0, 0);
692 state = B_STATE_DEACTIVATING;
693 timer = B_TIMER_DEACTIVATING;
696 case B_STATE_DEACTIVATING:
697 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
701 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
705 case B_EVENT_DEACTIVATED:
709 /* ignore due to deactivation confirm after unloading */
712 case B_STATE_DEACTIVATING:
713 _bchannel_destroy(mISDNport, i);
714 state = B_STATE_IDLE;
716 /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
717 if (_bchannel_create(mISDNport, i)) {
718 _bchannel_activate(mISDNport, i, 1, 0);
719 state = B_STATE_ACTIVATING;
720 timer = B_TIMER_ACTIVATING;
726 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
730 case B_EVENT_TIMEOUT:
734 /* ignore due to deactivation confirm after unloading */
737 case B_STATE_ACTIVATING:
738 _bchannel_activate(mISDNport, i, 1, 1);
739 timer = B_TIMER_ACTIVATING;
742 case B_STATE_DEACTIVATING:
743 _bchannel_activate(mISDNport, i, 0, 1);
744 timer = B_TIMER_DEACTIVATING;
748 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
753 PERROR("Illegal event %d, please correct.\n", event);
756 mISDNport->b_state[i] = state;
758 unsched_timer(&mISDNport->b_timer[i]);
760 schedule_timer(&mISDNport->b_timer[i], timer, 0);
767 * check for available channel and reserve+set it.
768 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
770 * returns -(cause value) or x = channel x or 0 = no channel
771 * NOTE: no activation is done here
773 int PmISDN::seize_bchannel(int channel, int exclusive)
777 /* the channel is what we have */
778 if (p_m_b_channel == channel)
781 /* if channel already in use, release it */
786 if (channel==CHANNEL_NO || channel==0)
789 /* is channel in range ? */
791 || (channel>p_m_mISDNport->b_num && channel<16)
792 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
793 return(-6); /* channel unacceptable */
795 /* request exclusive channel */
796 if (exclusive && channel>0) {
797 i = channel-1-(channel>16);
798 if (p_m_mISDNport->b_port[i])
799 return(-44); /* requested channel not available */
803 /* ask for channel */
805 i = channel-1-(channel>16);
806 if (p_m_mISDNport->b_port[i] == NULL)
810 /* search for channel */
812 while(i < p_m_mISDNport->b_num) {
813 if (!p_m_mISDNport->b_port[i]) {
814 channel = i+1+(i>=15);
819 return(-34); /* no free channel */
822 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
824 /* link Port, set parameters */
825 p_m_mISDNport->b_port[i] = this;
827 p_m_b_channel = channel;
828 p_m_b_exclusive = exclusive;
829 p_m_mISDNport->b_mode[i] = p_m_b_mode;
831 /* reserve channel */
832 if (!p_m_b_reserve) {
834 p_m_mISDNport->b_reserved++;
841 * drop reserved channel and unset it.
842 * deactivation is also done
844 void PmISDN::drop_bchannel(void)
846 /* unreserve channel */
848 p_m_mISDNport->b_reserved--;
857 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
859 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
860 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
861 p_m_mISDNport->b_port[p_m_b_index] = NULL;
862 p_m_mISDNport->b_mode[p_m_b_index] = 0;
872 audio transmission procedure:
873 -----------------------------
876 three sources of audio transmission:
877 - crypto-data high priority
878 - tones high priority (also high)
879 - remote-data low priority
882 a variable that temporarily shows the number of samples elapsed since last transmission process.
883 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
886 a variable that is increased whenever data is transmitted.
887 it is decreased while time elapses. it stores the number of samples that
888 are currently loaded to dsp module.
889 since clock in dsp module is the same clock for user space process, these
893 there are two levels:
894 p_m_preload will give the load that have to be kept in dsp.
895 ISDN_MAXLOAD (2*p_m_preload) will give the maximum load before dropping.
897 * procedure for low priority data
898 see txfromup() for procedure
899 in short: remote data is ignored during high priority tones
901 * procedure for high priority data
902 whenever load is below p_m_preload, load is filled up to p_m_preload
903 if no more data is available, load becomes empty again.
906 0 p_m_preload ISDN_MAXLOAD
907 +--------------------+----------------------+
909 +--------------------+----------------------+
911 on empty load or on load below p_m_preload, the load is inceased to p_m_preload:
912 0 p_m_preload ISDN_MAXLOAD
913 +--------------------+----------------------+
914 |TTTTTTTTTTTTTTTTTTTT| |
915 +--------------------+----------------------+
917 on empty load, remote-audio causes the load with the remote audio to be increased to p_m_preload.
918 0 p_m_preload ISDN_MAXLOAD
919 +--------------------+----------------------+
920 |TTTTTTTTTTTTTTTTTTTTRRRRR |
921 +--------------------+----------------------+
924 void PmISDN::update_load(void)
926 /* don't trigger load event if event already active */
927 if (p_m_loadtimer.active)
930 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
933 static int load_timer(struct lcr_timer *timer, void *instance, int index)
935 class PmISDN *isdnport = (class PmISDN *)instance;
942 void PmISDN::load_tx(void)
946 struct timeval current_time;
949 gettimeofday(¤t_time, NULL);
950 if (p_m_last_tv_sec) {
951 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
952 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
954 /* set clock of last process! */
955 p_m_last_tv_sec = current_time.tv_sec;
956 p_m_last_tv_msec = current_time.tv_usec/1000;
958 /* process only if we have samples and we are active */
959 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
964 if (elapsed < p_m_load)
969 /* to send data, tone must be on */
970 if ((p_tone_name[0] || p_dov_tx || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
971 && (p_m_load < p_m_preload) /* not too much load? */
972 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
973 int tosend = p_m_preload - p_m_load, length;
974 unsigned char buf[MISDN_HEADER_LEN+tosend];
975 struct mISDNhead *frm = (struct mISDNhead *)buf;
976 unsigned char *p = buf+MISDN_HEADER_LEN;
978 /* copy inband signalling (e.g. used by ss5) */
979 if (p_m_inband_send_on && tosend) {
980 tosend -= inband_send(p, tosend);
983 /* copy crypto loops */
984 while (p_m_crypt_msg_loops && tosend) {
985 /* how much do we have to send */
986 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
992 /* copy message (part) to buffer */
993 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
996 p_m_crypt_msg_current += length;
997 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
999 p_m_crypt_msg_current = 0;
1000 p_m_crypt_msg_loops--;
1001 if (!p_m_crypt_msg_loops)
1003 // puts("eine loop weniger");
1012 tosend -= dov_tx(p, tosend);
1016 if (p_tone_name[0] && tosend) {
1017 tosend -= read_audio(p, tosend);
1021 if (p_m_preload - p_m_load - tosend > 0) {
1022 frm->prim = PH_DATA_REQ;
1024 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);
1026 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);
1027 p_m_load += p_m_preload - p_m_load - tosend;
1032 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
1035 /* handle timeouts */
1036 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1038 class PmISDN *isdnport = (class PmISDN *)instance;
1039 struct lcr_msg *message;
1041 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);
1042 /* send timeout to endpoint */
1043 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1044 message->param.state = isdnport->p_state;
1045 message_put(message);
1052 * whenever we get audio data from bchannel, we process it here
1054 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1056 unsigned int cont = *((unsigned int *)data);
1057 struct lcr_msg *message;
1061 if (hh->prim == PH_CONTROL_IND) {
1063 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1066 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1067 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1068 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1070 add_trace("info", NULL, "DTMF is disabled");
1074 if (p_type == PORT_TYPE_POTS_FXS_IN && p_state == PORT_STATE_IN_OVERLAP) {
1075 class Pfxs *pfxs = (class Pfxs *)this;
1076 if (!pfxs->p_m_fxs_allow_dtmf) {
1077 PDEBUG(DEBUG_PORT, "PmISDN(%s) DTMF for FXS currently disabled\n", p_name);
1080 SCCAT(p_dialinginfo.id, cont & DTMF_TONE_MASK);
1081 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
1082 message->param.information.id[0] = cont & DTMF_TONE_MASK;
1083 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION INFORMATION digit '%s'\n", p_name, message->param.information.id);
1084 message_put(message);
1086 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1087 message->param.dtmf = cont & DTMF_TONE_MASK;
1088 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1089 message_put(message);
1095 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1096 add_trace("DSP-CRYPT", NULL, "error");
1098 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1099 message->param.crypt.type = CC_ERROR_IND;
1100 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1101 message_put(message);
1105 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1106 add_trace("DSP-CRYPT", NULL, "ok");
1108 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1109 message->param.crypt.type = CC_ACTBF_CONF;
1110 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1111 message_put(message);
1115 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1116 add_trace("unknown", NULL, "0x%x", cont);
1121 if (hh->prim == PH_CONTROL_IND) {
1124 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1125 add_trace("unknown", NULL, "0x%x", hh->id);
1130 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1132 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1133 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1136 /* see below (same condition) */
1137 if (p_state!=PORT_STATE_CONNECT
1138 && !p_m_mISDNport->tones)
1140 // printf(".");fflush(stdout);return;
1142 record(data, len, 1); // from up
1144 tap(data, len, 1); // from up
1147 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1148 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1152 /* dov is processed */
1156 /* inband is processed */
1157 if (p_m_inband_receive_on)
1158 inband_receive(data, len);
1160 /* send to remote, if bridged */
1161 bridge_tx(data, len);
1163 /* calls will not process any audio data unless
1164 * the call is connected OR tones feature is enabled.
1166 #ifndef DEBUG_COREBRIDGE
1167 if (p_state!=PORT_STATE_CONNECT
1168 && !p_m_mISDNport->tones)
1173 /* the bearer capability must be audio in order to send and receive
1174 * audio prior or after connect.
1176 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1180 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1182 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1188 record(data, len, 0); // from down
1190 tap(data, len, 0); // from down
1192 /* randomize and listen to crypt message if enabled */
1193 if (p_m_crypt_listen) {
1194 /* the noisy randomizer */
1198 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1200 cryptman_listen_bch(data, len);
1208 void PmISDN::set_echotest(int echo)
1210 if (p_m_echo != echo) {
1212 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1214 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1215 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);
1222 void PmISDN::set_tone(const char *dir, const char *tone)
1227 /* if no directory is given (by extension), we use interface.conf or options.conf */
1228 if (!dir || !dir[0]) {
1229 if (p_tones_interface[0])
1230 dir = p_tones_interface;
1232 dir = options.tones_dir;
1237 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1243 /* check for dsp tones */
1244 if (!strcmp(dir, "american"))
1246 if (!strcmp(dir, "german"))
1248 if (!strcmp(dir, "oldgerman"))
1249 dsp = DSP_OLDGERMAN;
1251 /* check if we NOT really have to use a dsp-tone */
1252 if (dsp == DSP_NONE) {
1255 if (p_m_b_index > -1)
1256 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) {
1257 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1258 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1261 Port::set_tone(dir, tone);
1265 /* now we USE dsp-tone, convert name */
1266 if (!strcmp(tone, "dialtone")) {
1268 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1269 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1270 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1272 } else if (!strcmp(tone, "dialpbx")) {
1274 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1275 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1276 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1278 } else if (!strcmp(tone, "ringing")) {
1280 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1281 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1282 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1284 } else if (!strcmp(tone, "ringpbx")) {
1286 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1287 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1288 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1290 } else if (!strcmp(tone, "busy")) {
1293 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1294 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1295 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1297 } else if (!strcmp(tone, "release")) {
1300 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1301 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1302 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1304 } else if (!strcmp(tone, "cause_10"))
1306 else if (!strcmp(tone, "cause_11"))
1308 else if (!strcmp(tone, "cause_22")) {
1310 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1311 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1312 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1314 } else if (!strncmp(tone, "cause_", 6))
1315 id = TONE_SPECIAL_INFO;
1319 /* if we have a tone that is not supported by dsp */
1320 if (id==TONE_OFF && tone[0])
1324 if (p_m_tone != id) {
1327 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1328 if (p_m_b_index > -1)
1329 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)
1330 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);
1332 /* turn user-space tones off in cases of no tone OR dsp tone */
1333 Port::set_tone("",NULL);
1337 /* MESSAGE_mISDNSIGNAL */
1338 //extern struct lcr_msg *dddebug;
1339 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1341 int oldconf, newconf;
1342 switch(param->mISDNsignal.message) {
1343 case mISDNSIGNAL_VOLUME:
1344 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1345 p_m_tx_gain = param->mISDNsignal.tx_gain;
1346 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1347 if (p_m_b_index > -1)
1348 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)
1349 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);
1351 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1352 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1353 p_m_rx_gain = param->mISDNsignal.rx_gain;
1354 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1355 if (p_m_b_index > -1)
1356 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)
1357 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);
1359 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1362 case mISDNSIGNAL_CONF:
1363 oldconf = p_m_mute?0:p_m_conf;
1364 p_m_conf = param->mISDNsignal.conf;
1365 newconf = p_m_mute?0:p_m_conf;
1366 set_conf(oldconf, newconf);
1369 case mISDNSIGNAL_DELAY:
1370 if (p_m_delay != param->mISDNsignal.delay) {
1371 p_m_delay = param->mISDNsignal.delay;
1372 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1373 if (p_m_b_index > -1)
1374 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)
1375 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);
1377 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1381 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1386 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1388 struct lcr_msg *message;
1390 switch(param->crypt.type) {
1391 case CC_ACTBF_REQ: /* activate blowfish */
1393 p_m_crypt_key_len = param->crypt.len;
1394 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1395 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1396 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1397 message->param.crypt.type = CC_ERROR_IND;
1398 message_put(message);
1401 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1403 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1404 if (p_m_b_index > -1)
1405 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)
1406 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);
1409 case CC_DACT_REQ: /* deactivate session encryption */
1414 case CR_LISTEN_REQ: /* start listening to messages */
1415 p_m_crypt_listen = 1;
1417 p_m_crypt_listen_state = 0;
1420 case CR_UNLISTEN_REQ: /* stop listening to messages */
1421 p_m_crypt_listen = 0;
1425 case CR_MESSAGE_REQ: /* send message */
1426 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1427 if (!p_m_crypt_msg_len) {
1428 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1431 p_m_crypt_msg_current = 0; /* reset */
1432 p_m_crypt_msg_loops = 6; /* enable */
1435 /* disable txmix, or we get corrupt data due to audio process */
1436 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1437 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1438 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1444 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1450 void PmISDN::message_vootp(unsigned int epoint_id, int message_id, union parameter *param)
1452 struct lcr_msg *message;
1454 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_UPDATEBRIDGE);
1455 message_put(message);
1458 does not make sense, since remote port may dejitter
1459 if (param->vootp.enable) {
1460 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received vootp enable order, so we disable de-jitter.\n", p_name);
1461 p_m_disable_dejitter = 1;
1468 * endpoint sends messages to the port
1470 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1472 /* messages also handled by base class */
1473 switch(message_id) {
1474 case MESSAGE_VOOTP: /* crypt control command */
1475 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received VoOTP encryption\n", p_name);
1476 message_vootp(epoint_id, message_id, param);
1480 if (Port::message_epoint(epoint_id, message_id, param)) {
1481 if (message_id == MESSAGE_BRIDGE)
1486 /* messages not handled by base class */
1487 switch(message_id) {
1488 case MESSAGE_mISDNSIGNAL: /* user command */
1489 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1490 message_mISDNsignal(epoint_id, message_id, param);
1493 case MESSAGE_CRYPT: /* crypt control command */
1494 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1495 message_crypt(epoint_id, message_id, param);
1498 case MESSAGE_DISABLE_DEJITTER:
1499 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received de-jitter disable order.\n", p_name);
1500 p_m_disable_dejitter = 1;
1501 p_m_preload = param->queue;
1509 void PmISDN::update_rxoff(void)
1511 int tx_dejitter = 0;
1513 /* call bridges in user space OR crypto OR recording */
1514 if (p_bridge || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_tap || p_m_inband_receive_on || p_dov_rx) {
1515 /* rx IS required */
1519 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1520 if (p_m_b_index > -1)
1521 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1522 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1525 /* rx NOT required */
1529 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1530 if (p_m_b_index > -1)
1531 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1532 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1535 /* recording / tapping */
1536 if (p_record || p_tap) {
1537 /* txdata IS required */
1541 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1542 if (p_m_b_index > -1)
1543 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1544 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1547 /* txdata NOT required */
1551 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1552 if (p_m_b_index > -1)
1553 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1554 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1557 /* dejitter on bridge */
1558 if (p_bridge && !p_m_disable_dejitter)
1560 if (p_m_tx_dejitter != tx_dejitter) {
1561 p_m_tx_dejitter = tx_dejitter;
1562 PDEBUG(DEBUG_BCHANNEL, "we change dejitter mode to %s.\n", (p_m_tx_dejitter) ? "on" : "off");
1563 if (p_m_b_index > -1)
1564 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)
1565 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);
1569 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1571 struct mISDNport *mISDNport;
1575 int __attribute__((__unused__)) ret;
1577 /* unset global semaphore */
1579 // with a very small incident, upqueue_avail may be set by mISDN thread and
1580 // another byte may be sent to the pipe, which causes a call to this function
1581 // again with nothing in the upqueue. this is no problem.
1582 ret = read(fd->fd, &byte, 1);
1584 /* process all ports */
1585 mISDNport = mISDNport_first;
1587 /* handle queued up-messages (d-channel) */
1588 while ((mb = mdequeue(&mISDNport->upqueue))) {
1591 case MPH_ACTIVATE_IND:
1592 if (mISDNport->l1link != 1) {
1593 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1595 mISDNport->l1link = 1;
1599 case MPH_DEACTIVATE_IND:
1600 if (mISDNport->l1link != 0) {
1601 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1603 mISDNport->l1link = 0;
1607 case MPH_INFORMATION_IND:
1608 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1610 case L1_SIGNAL_LOS_ON:
1613 case L1_SIGNAL_LOS_OFF:
1616 case L1_SIGNAL_AIS_ON:
1619 case L1_SIGNAL_AIS_OFF:
1622 case L1_SIGNAL_RDI_ON:
1625 case L1_SIGNAL_RDI_OFF:
1628 case L1_SIGNAL_SLIP_TX:
1629 mISDNport->slip_tx++;
1631 case L1_SIGNAL_SLIP_RX:
1632 mISDNport->slip_rx++;
1637 case MT_L2ESTABLISH:
1638 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1639 add_trace("tei", NULL, "%d", l3m->pid);
1641 mISDNport->l2link = 1;
1643 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1644 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1645 if (mISDNport->l2establish.active) {
1646 unsched_timer(&mISDNport->l2establish);
1647 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1654 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1655 if (!mISDNport->l2establish.active) {
1656 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1657 add_trace("tei", NULL, "%d", l3m->pid);
1659 /* down if not nt-ptmp */
1660 if (!mISDNport->ntmode || mISDNport->ptp)
1661 mISDNport->l2link = 0;
1663 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1664 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1665 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1666 schedule_timer(&mISDNport->l2establish, 5, 0);
1667 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1673 /* l3-data is sent to LCR */
1674 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1679 mISDNport = mISDNport->next;
1684 /* l2 establish timer fires */
1685 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1687 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1689 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1690 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1691 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1692 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1698 /* handle frames from bchannel */
1699 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1701 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1702 unsigned char buffer[2048+MISDN_HEADER_LEN];
1703 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1706 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1708 PERROR("read error frame, errno %d\n", errno);
1711 if (ret < (int)MISDN_HEADER_LEN) {
1712 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1716 /* we don't care about confirms, we use rx data to sync tx */
1720 /* we receive audio data, we respond to it AND we send tones */
1725 case PH_CONTROL_IND:
1726 if (mISDNport->b_port[i])
1727 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1729 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1732 case PH_ACTIVATE_IND:
1733 case DL_ESTABLISH_IND:
1734 case PH_ACTIVATE_CNF:
1735 case DL_ESTABLISH_CNF:
1736 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1737 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1740 case PH_DEACTIVATE_IND:
1741 case DL_RELEASE_IND:
1742 case PH_DEACTIVATE_CNF:
1743 case DL_RELEASE_CNF:
1744 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
1745 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1749 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
1755 /* process timer events for bchannel handling */
1756 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
1758 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1760 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1766 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1770 * l3m must be queued, except for MT_ASSIGN
1773 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
1776 #ifdef OLD_MT_ASSIGN
1777 /* special MT_ASSIGN handling:
1779 * if we request a PID from mlayer, we always do it while lcr is locked.
1780 * therefore we must check the MT_ASSIGN reply first before we lock.
1781 * this is because the MT_ASSIGN reply is received with the requesting
1782 * process, not by the mlayer thread!
1783 * this means, that the reply is sent during call of the request.
1784 * we must check if we get a reply and we know that we lcr is currently
1787 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
1788 /* let's do some checking if someone changes stack behaviour */
1789 if (mt_assign_pid != 0)
1790 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
1791 mt_assign_pid = pid;
1795 /* queue message, create, if required */
1797 l3m = alloc_l3_msg();
1799 FATAL("No memory for layer 3 message\n");
1801 mb = container_of(l3m, struct mbuffer, l3);
1804 mqueue_tail(&mISDNport->upqueue, mb);
1805 if (!upqueue_avail) {
1806 // multiple threads may cause multiple calls of this section, but this
1807 // results only in multiple processing of the upqueue read.
1808 // this is no problem.
1811 int __attribute__((__unused__)) ret;
1812 ret = write(upqueue_pipe[1], &byte, 1);
1817 int mISDN_getportbyname(int sock, int cnt, char *portname)
1819 struct mISDN_devinfo devinfo;
1822 memset(&devinfo, 0, sizeof(devinfo));
1825 while (port < cnt) {
1827 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
1830 if (!strcasecmp(devinfo.name, portname))
1840 #ifdef ISDN_P_FXS_POTS
1841 /* handle frames from pots */
1842 static int pots_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1844 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1845 unsigned char buffer[2048+MISDN_HEADER_LEN];
1846 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1850 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1852 PERROR("read error frame, errno %d\n", errno);
1855 if (ret < (int)MISDN_HEADER_LEN) {
1856 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1860 case PH_CONTROL_IND:
1861 cont = *((unsigned int *)(buffer + MISDN_HEADER_LEN));
1862 /* l1-control is sent to LCR */
1863 if (mISDNport->ntmode)
1864 stack2manager_fxs(mISDNport, cont);
1866 PERROR("FXO not supported!\n");
1868 case PH_ACTIVATE_REQ:
1872 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
1880 * global function to add a new card (port)
1882 struct mISDNport *mISDNport_open(struct interface_port *ifport)
1885 struct mISDNport *mISDNport, **mISDNportp;
1886 int port = ifport->portnum;
1887 int ptp = ifport->ptp;
1888 int force_nt = ifport->nt;
1889 int l1hold = ifport->l1hold;
1890 int l2hold = ifport->l2hold;
1891 int ss5 = ifport->ss5;
1895 // struct mlayer3 *ml3;
1896 struct mISDN_devinfo devinfo;
1897 unsigned int protocol, prop;
1899 memset(&devinfo, 0, sizeof(devinfo));
1901 /* check port counts */
1902 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
1904 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
1909 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
1913 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
1915 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
1918 // note: 'port' has still the port number
1920 if (port>cnt || port<0) {
1921 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
1925 /* get port attributes */
1926 pri = bri = pots = nt = te = 0;
1928 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
1930 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
1933 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
1937 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
1941 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
1945 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
1949 #ifdef ISDN_P_FXS_POTS
1950 if (devinfo.Dprotocols & (1 << ISDN_P_FXO_POTS)) {
1954 if (devinfo.Dprotocols & (1 << ISDN_P_FXS_POTS)) {
1959 if (force_nt && !nt) {
1961 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
1963 PERROR_RUNTIME("Port %d does not support FXS-mode\n", port);
1967 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
1970 if (!bri && !pri && !pots) {
1971 PERROR_RUNTIME("Port %d does not support BRI nor PRI nor POTS!\n", port);
1975 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
1978 /* set NT by turning off TE */
1981 /* if TE an NT is supported (and not forced to NT), turn off NT */
1985 PERROR_RUNTIME("Port %d uses FXO-mode, but not supported by LCR!\n", port);
1989 /* check for double use of port */
1991 mISDNport = mISDNport_first;
1993 if (mISDNport->portnum == port)
1995 mISDNport = mISDNport->next;
1998 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2003 /* check for continous channelmap with no bchannel on slot 16 */
2004 if (test_channelmap(0, devinfo.channelmap)) {
2005 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2009 while(i < (int)devinfo.nrbchan + 1) {
2011 if (test_channelmap(i, devinfo.channelmap)) {
2012 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2016 if (!test_channelmap(i, devinfo.channelmap)) {
2017 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2024 /* add mISDNport structure */
2025 mISDNportp = &mISDNport_first;
2027 mISDNportp = &((*mISDNportp)->next);
2028 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2029 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2031 /* ss5 link is always active */
2032 mISDNport->l1link = 1;
2033 mISDNport->l2link = 1;
2035 mISDNport->l1link = -1;
2036 mISDNport->l2link = -1;
2039 *mISDNportp = mISDNport;
2041 /* if pri, must set PTP */
2045 /* set ss5 params */
2047 /* try to keep interface enabled */
2067 /* allocate ressources of port */
2070 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2071 prop = (1 << MISDN_FLG_L2_CLEAN);
2072 if (ptp) // ptp forced
2073 prop |= (1 << MISDN_FLG_PTP);
2074 if (nt) // supports hold/retrieve on nt-mode
2075 prop |= (1 << MISDN_FLG_NET_HOLD);
2076 if (l1hold) // supports layer 1 hold
2077 prop |= (1 << MISDN_FLG_L1_HOLD);
2078 if (l2hold) // supports layer 2 hold
2079 prop |= (1 << MISDN_FLG_L2_HOLD);
2080 /* open layer 3 and init upqueue */
2081 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2082 mqueue_init(&mISDNport->upqueue);
2083 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2084 if (!mISDNport->ml3) {
2085 mqueue_purge(&mISDNport->upqueue);
2086 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2094 "PORT (open failed)");
2096 mISDNport_close(mISDNport);
2100 #ifdef ISDN_P_FXS_POTS
2103 struct sockaddr_mISDN addr;
2104 struct mISDNhead act;
2107 /* queue must be initializes, because even pots interfaces are checked at mISDN_upqueue loop */
2108 mqueue_init(&mISDNport->upqueue);
2109 sock = socket(PF_ISDN, SOCK_DGRAM, (nt) ? ISDN_P_FXS_POTS : ISDN_P_FXO_POTS);
2111 PERROR_RUNTIME("Cannot open mISDN due to '%s'.\n", strerror(errno));
2114 /* bind socket to dchannel */
2115 addr.family = AF_ISDN;
2118 ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
2120 PERROR_RUNTIME("Error: Failed to bind pots control channel\n");
2128 "PORT (open failed)");
2132 act.prim = PH_ACTIVATE_REQ;
2134 ret = sendto(sock, &act, MISDN_HEADER_LEN, 0, NULL, 0);
2136 PERROR("Failed to send to socket %d\n", sock);
2137 mISDNport->pots_sock.fd = sock;
2138 register_fd(&mISDNport->pots_sock, LCR_FD_READ, pots_sock_callback, mISDNport, i);
2142 SCPY(mISDNport->name, devinfo.name);
2143 mISDNport->b_num = devinfo.nrbchan;
2144 mISDNport->portnum = port;
2145 mISDNport->ntmode = nt;
2146 mISDNport->pots = pots;
2147 mISDNport->tespecial = ifport->tespecial;
2148 mISDNport->pri = pri;
2149 mISDNport->ptp = ptp;
2150 mISDNport->l1hold = l1hold;
2151 mISDNport->l2hold = l2hold;
2152 mISDNport->ss5 = ss5;
2153 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2155 while(i < mISDNport->b_num) {
2156 mISDNport->b_state[i] = B_STATE_IDLE;
2157 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2161 /* if ptp, pull up the link */
2162 if (!pots && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2163 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2164 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2165 add_trace("tei", NULL, "%d", 0);
2167 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2170 /* for POTS or nt-mode ptmp the link is always up */
2171 if (pots || (mISDNport->ntmode && !mISDNport->ptp))
2172 mISDNport->l2link = 1;
2174 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2176 start_trace(mISDNport->portnum,
2185 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2187 add_trace("mode", NULL, (mISDNport->ntmode)?"FXS":"FXO");
2188 add_trace("channels", NULL, "%d", mISDNport->b_num);
2190 add_trace("ccitt#5", NULL, "enabled");
2198 * load static port instances, if required by mISDNport
2200 void mISDNport_static(struct mISDNport *mISDNport)
2205 while(i < mISDNport->b_num) {
2208 ss5_create_channel(mISDNport, i);
2216 * function to free ALL cards (ports)
2218 void mISDNport_close_all(void)
2220 /* free all ports */
2221 while(mISDNport_first)
2222 mISDNport_close(mISDNport_first);
2226 * free only one port
2228 void mISDNport_close(struct mISDNport *mISDNport)
2230 struct mISDNport **mISDNportp;
2232 class PmISDN *isdnport;
2235 /* remove all port instance that are linked to this mISDNport */
2239 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2240 isdnport = (class PmISDN *)port;
2241 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2242 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2250 /* only if we are already part of interface */
2251 if (mISDNport->ifport) {
2252 start_trace(mISDNport->portnum,
2253 mISDNport->ifport->interface,
2263 /* free bchannels */
2265 while(i < mISDNport->b_num) {
2266 if (mISDNport->b_sock[i].inuse) {
2267 _bchannel_destroy(mISDNport, i);
2268 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2270 if (mISDNport->b_timer[i].inuse) {
2271 del_timer(&mISDNport->b_timer[i]);
2275 del_timer(&mISDNport->l2establish);
2277 /* close layer 3, if open */
2278 if (mISDNport->ml3) {
2279 close_layer3(mISDNport->ml3);
2282 /* close layer 1, if open */
2283 if (mISDNport->pots_sock.fd) {
2284 unregister_fd(&mISDNport->pots_sock);
2285 close(mISDNport->pots_sock.fd);
2289 mqueue_purge(&mISDNport->upqueue);
2291 /* remove from list */
2292 mISDNportp = &mISDNport_first;
2293 while(*mISDNportp) {
2294 if (*mISDNportp == mISDNport) {
2295 *mISDNportp = (*mISDNportp)->next;
2299 mISDNportp = &((*mISDNportp)->next);
2303 FATAL("mISDNport not in list\n");
2305 FREE(mISDNport, sizeof(struct mISDNport));
2312 * enque data from remote port
2314 int PmISDN::bridge_rx(unsigned char *data, int length)
2316 unsigned char buf[MISDN_HEADER_LEN+((length>p_m_preload)?length:p_m_preload)];
2317 struct mISDNhead *hh = (struct mISDNhead *)buf;
2320 if ((ret = Port::bridge_rx(data, length)))
2323 if (p_m_b_index < 0)
2325 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2328 /* check if high priority tones exist
2329 * ignore data in this case
2331 if (p_tone_name[0] || p_dov_tx || p_m_crypt_msg_loops || p_m_inband_send_on)
2334 /* preload procedure
2335 * if transmit buffer in DSP module is empty,
2336 * preload it to DSP_LOAD to prevent jitter gaps.
2338 * if load runs empty, preload again.
2340 if (p_m_disable_dejitter && p_m_load == 0 && p_m_preload > 0) {
2341 //printf("preload=%d\n", p_m_preload);
2342 hh->prim = PH_DATA_REQ;
2344 memset(buf+MISDN_HEADER_LEN, silence, p_m_preload);
2345 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+p_m_preload, 0, NULL, 0);
2347 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2348 p_m_load += p_m_preload;
2349 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
2352 /* drop if load would exceed ISDN_MAXLOAD
2353 * this keeps the delay not too high
2355 //printf("load=%d len=%d 2*preload=%d\n", p_m_load, length, p_m_preload << 1);
2356 if (p_m_disable_dejitter && p_m_preload > 0 && p_m_load+length > (p_m_preload << 1))
2359 /* make and send frame */
2360 hh->prim = PH_DATA_REQ;
2362 memcpy(buf+MISDN_HEADER_LEN, data, length);
2363 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2365 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2371 int PmISDN::inband_send(unsigned char *buffer, int len)
2373 PERROR("this function must be derived to function!\n");
2377 void PmISDN::inband_send_on(void)
2379 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2380 p_m_inband_send_on = 1;
2383 void PmISDN::inband_send_off(void)
2385 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2386 p_m_inband_send_on = 0;
2389 void PmISDN::inband_receive(unsigned char *buffer, int len)
2392 // if (len >= SS5_DECODER_NPOINTS)
2393 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2394 PERROR("this function must be derived to function!\n");
2397 void PmISDN::inband_receive_on(void)
2399 /* this must work during constructor, see ss5.cpp */
2400 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2401 p_m_inband_receive_on = 1;
2405 void PmISDN::inband_receive_off(void)
2407 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2408 p_m_inband_receive_on = 0;
2412 void PmISDN::mute_on(void)
2416 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2418 set_conf(p_m_conf, 0);
2421 void PmISDN::mute_off(void)
2425 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2427 set_conf(0, p_m_conf);