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 int load_timer(struct lcr_timer *timer, void *instance, int index);
125 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
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;
145 p_m_inband_send_on = 0;
146 p_m_inband_receive_on = 0;
147 p_m_dtmf = !mISDNport->ifport->nodtmf;
148 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
149 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
150 p_m_remote_ref = 0; /* channel shall be exported to given remote */
151 p_m_remote_id = 0; /* remote admin socket */
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);
355 ctrl->prim = PH_CONTROL_REQ;
359 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
361 PERROR("Failed to send to socket %d\n", sock);
362 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
363 if (c1 == DSP_CONF_JOIN)
364 add_trace(trace_name, NULL, "0x%08x", trace_value);
366 add_trace(trace_name, NULL, "%d", trace_value);
370 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)
372 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
373 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
374 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
380 ctrl->prim = PH_CONTROL_REQ;
383 memcpy(d, c2, c2_len);
384 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
386 PERROR("Failed to send to socket %d\n", sock);
387 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
388 add_trace(trace_name, NULL, "%d", trace_value);
392 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
395 * subfunction for bchannel_event
398 static int _bchannel_create(struct mISDNport *mISDNport, int i)
401 struct sockaddr_mISDN addr;
403 if (mISDNport->b_sock[i].inuse) {
404 PERROR("Error: Socket already created for index %d\n", i);
409 //#warning testing without DSP
410 // 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);
411 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);
412 if (mISDNport->b_sock[i].fd < 0) {
413 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
417 /* register callback for read */
418 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
420 /* bind socket to bchannel */
421 addr.family = AF_ISDN;
422 addr.dev = mISDNport->portnum;
423 addr.channel = i+1+(i>=15);
424 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
426 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);
427 close(mISDNport->b_sock[i].fd);
428 unregister_fd(&mISDNport->b_sock[i]);
432 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
433 add_trace("channel", NULL, "%d", i+1+(i>=15));
434 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
442 * subfunction for bchannel_event
443 * activate / deactivate request
445 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
447 struct mISDNhead act;
450 if (!mISDNport->b_sock[i].inuse)
452 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
454 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
456 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
459 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
460 add_trace("channel", NULL, "%d", i+1+(i>=15));
462 add_trace("event", NULL, "timeout recovery");
468 * subfunction for bchannel_event
471 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
476 if (!mISDNport->b_sock[i].inuse)
478 handle = mISDNport->b_sock[i].fd;
479 port = mISDNport->b_port[i];
480 mode = mISDNport->b_mode[i];
482 PERROR("bchannel index i=%d not associated with a port object\n", i);
486 /* set dsp features */
487 if (port->p_m_txdata)
488 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
489 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
490 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
491 if (port->p_m_tx_dejitter && mode == B_MODE_TRANSPARENT)
492 ph_control(mISDNport, port, handle, DSP_TX_DEJITTER, port->p_m_tx_dejitter, "DSP-TX_DEJITTER", port->p_m_tx_dejitter);
493 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
494 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
495 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
496 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
497 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
498 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
499 if (port->p_m_conf && !port->p_m_mute)
500 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
502 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
503 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
504 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
506 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
507 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
508 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
509 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
510 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
511 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
512 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);
516 void PmISDN::set_conf(int oldconf, int newconf)
518 if (oldconf != newconf) {
519 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
520 if (p_m_b_index > -1)
521 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
522 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);
524 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
529 * subfunction for bchannel_event
532 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
534 if (!mISDNport->b_sock[i].inuse)
536 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
537 add_trace("channel", NULL, "%d", i+1+(i>=15));
538 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
540 close(mISDNport->b_sock[i].fd);
541 unregister_fd(&mISDNport->b_sock[i]);
549 A bchannel goes through the following states in this order:
552 No one is using the bchannel.
553 It is available and not linked to Port class, nor reserved.
556 The bchannel stack is created and an activation request is sent.
557 It MAY be linked to Port class, but already unlinked due to Port class removal.
560 The bchannel is active and cofigured to the Port class needs.
561 Also it is linked to a Port class, otherwhise it would be deactivated.
563 - B_STATE_DEACTIVATING
564 The bchannel is in deactivating state, due to deactivation request.
565 It may be linked to a Port class, that likes to reactivate it.
569 After deactivating bchannel, and if not used, the bchannel becomes idle again.
571 Also the bchannel may be exported, but only if the state is or becomes idle:
574 The bchannel assignment has been sent to the remove application.
577 The bchannel assignment is acknowledged by the remote application.
580 The bchannel is re-imported by mISDN port object.
584 After re-importing bchannel, and if not used, the bchannel becomes idle again.
587 A bchannel can have the following events:
590 A bchannel is required by a Port class.
593 The bchannel beomes active.
596 The bchannel is not required by Port class anymore
598 - B_EVENT_DEACTIVATED
599 The bchannel becomes inactive.
602 The bchannel is now used by remote application.
605 The bchannel is not used by remote application.
607 - B_EVENT_EXPORTREQUEST
608 The bchannel shall be exported to the remote application.
610 - B_EVENT_IMPORTREQUEST
611 The bchannel is released from the remote application.
613 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
615 if an export request is receive by remote application, p_m_remote_* is set.
616 the b_remote_*[index] indicates if and where the channel is exported to. (set from the point on, where export is initiated, until imported is acknowledged.)
617 - set on export request from remote application (if port is assigned)
618 - set on channel use, if requested by remote application (p_m_remote_*)
619 - cleared on drop request
621 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
622 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
623 the bchannel import/export is acknowledged with stack given.
625 if exporting, b_remote_*[index] is set to the remote socket id.
626 if importing has been acknowledged. b_remote_*[index] is cleared.
631 * process bchannel events
632 * - mISDNport is a pointer to the port's structure
633 * - i is the index of the bchannel
634 * - event is the B_EVENT_* value
635 * - port is the PmISDN class pointer
637 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
639 class PmISDN *b_port = mISDNport->b_port[i];
640 int state = mISDNport->b_state[i];
641 int timer = -1; // no change
642 unsigned int p_m_remote_ref = 0;
643 unsigned int p_m_remote_id = 0;
646 char *p_m_pipeline = NULL;
647 unsigned char *p_m_crypt_key = NULL;
648 int p_m_crypt_key_len = 0;
649 int p_m_crypt_key_type = 0;
650 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
653 p_m_remote_id = b_port->p_m_remote_id;
654 p_m_remote_ref = b_port->p_m_remote_ref;
655 p_m_tx_gain = b_port->p_m_tx_gain;
656 p_m_rx_gain = b_port->p_m_rx_gain;
657 p_m_pipeline = b_port->p_m_pipeline;
658 p_m_crypt_key = b_port->p_m_crypt_key;
659 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
660 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
665 /* port must be linked in order to allow activation */
667 FATAL("bchannel must be linked to a Port class\n");
670 if (p_m_remote_ref) {
671 /* export bchannel */
672 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
673 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
674 add_trace("type", NULL, "assign");
675 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
677 state = B_STATE_EXPORTING;
678 mISDNport->b_remote_id[i] = p_m_remote_id;
679 mISDNport->b_remote_ref[i] = p_m_remote_ref;
681 /* create stack and send activation request */
682 if (_bchannel_create(mISDNport, i)) {
683 _bchannel_activate(mISDNport, i, 1, 0);
684 state = B_STATE_ACTIVATING;
685 timer = B_TIMER_ACTIVATING;
690 case B_STATE_ACTIVATING:
691 case B_STATE_EXPORTING:
692 /* do nothing, because it is already activating */
695 case B_STATE_DEACTIVATING:
696 case B_STATE_IMPORTING:
697 /* do nothing, because we must wait until we can reactivate */
701 /* problems that might ocurr:
702 * B_EVENT_USE is received when channel already in use.
703 * bchannel exported, but not freed by other port
705 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
709 case B_EVENT_EXPORTREQUEST:
710 /* special case where the bchannel is requested by remote */
711 if (!p_m_remote_ref) {
712 PERROR("export request without remote channel set, please correct.\n");
717 /* in case, the bchannel is exported right after seize_bchannel */
718 /* export bchannel */
719 /* p_m_remote_id is set, when this event happens. */
720 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
721 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
722 add_trace("type", NULL, "assign");
723 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
725 state = B_STATE_EXPORTING;
726 mISDNport->b_remote_id[i] = p_m_remote_id;
727 mISDNport->b_remote_ref[i] = p_m_remote_ref;
730 case B_STATE_ACTIVATING:
731 case B_STATE_EXPORTING:
732 /* do nothing, because it is already activating */
735 case B_STATE_DEACTIVATING:
736 case B_STATE_IMPORTING:
737 /* do nothing, because we must wait until we can reactivate */
741 /* bchannel is active, so we deactivate */
742 _bchannel_activate(mISDNport, i, 0, 0);
743 state = B_STATE_DEACTIVATING;
744 timer = B_TIMER_DEACTIVATING;
748 /* problems that might ocurr:
749 * ... when channel already in use.
750 * bchannel exported, but not freed by other port
752 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
756 case B_EVENT_IMPORTREQUEST:
757 /* special case where the bchannel is released by remote */
758 if (p_m_remote_ref) {
759 PERROR("import request with remote channel set, please correct.\n");
765 /* bchannel is not exported */
768 case B_STATE_ACTIVATING:
769 case B_STATE_EXPORTING:
770 /* do nothing because we must wait until bchanenl is active before deactivating */
774 /* bchannel is exported, so we re-import */
775 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
776 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
777 add_trace("type", NULL, "remove");
778 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
780 state = B_STATE_IMPORTING;
783 case B_STATE_DEACTIVATING:
784 case B_STATE_IMPORTING:
785 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
789 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
793 case B_EVENT_ACTIVATED:
796 case B_STATE_ACTIVATING:
797 if (b_port && !p_m_remote_id) {
798 /* bchannel is active and used by Port class, so we configure bchannel */
799 _bchannel_configure(mISDNport, i);
800 state = B_STATE_ACTIVE;
801 b_port->p_m_load = 0;
803 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
804 _bchannel_activate(mISDNport, i, 0, 0);
805 state = B_STATE_DEACTIVATING;
806 timer = B_TIMER_DEACTIVATING;
811 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
815 case B_EVENT_EXPORTED:
817 case B_STATE_EXPORTING:
818 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
819 /* remote export done */
820 state = B_STATE_REMOTE;
822 /* bchannel is now exported, but we need bchannel back
823 * OR bchannel is not used anymore
824 * OR bchannel has been exported to an obsolete ref,
825 * so reimport, to later export to new remote */
826 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
827 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
828 add_trace("type", NULL, "remove");
829 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
831 state = B_STATE_IMPORTING;
836 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
842 FATAL("bchannel must be linked to a Port class\n");
845 /* bchannel is idle due to an error, so we do nothing */
848 case B_STATE_ACTIVATING:
849 case B_STATE_EXPORTING:
850 /* do nothing because we must wait until bchanenl is active before deactivating */
854 /* bchannel is active, so we deactivate */
855 _bchannel_activate(mISDNport, i, 0, 0);
856 state = B_STATE_DEACTIVATING;
857 timer = B_TIMER_DEACTIVATING;
861 /* bchannel is exported, so we re-import */
862 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
863 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
864 add_trace("type", NULL, "remove");
865 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
867 state = B_STATE_IMPORTING;
870 case B_STATE_DEACTIVATING:
871 case B_STATE_IMPORTING:
872 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
876 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
880 case B_EVENT_DEACTIVATED:
884 /* ignore due to deactivation confirm after unloading */
887 case B_STATE_DEACTIVATING:
888 _bchannel_destroy(mISDNport, i);
889 state = B_STATE_IDLE;
891 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
892 if (p_m_remote_ref) {
893 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
894 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
895 add_trace("type", NULL, "assign");
896 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
898 state = B_STATE_EXPORTING;
899 mISDNport->b_remote_id[i] = p_m_remote_id;
900 mISDNport->b_remote_ref[i] = p_m_remote_ref;
902 if (_bchannel_create(mISDNport, i)) {
903 _bchannel_activate(mISDNport, i, 1, 0);
904 state = B_STATE_ACTIVATING;
905 timer = B_TIMER_ACTIVATING;
912 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
916 case B_EVENT_IMPORTED:
918 case B_STATE_IMPORTING:
919 state = B_STATE_IDLE;
920 mISDNport->b_remote_id[i] = 0;
921 mISDNport->b_remote_ref[i] = 0;
923 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
924 if (p_m_remote_ref) {
925 message_bchannel_to_remote(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type, 0);
926 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
927 add_trace("type", NULL, "assign");
928 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
930 state = B_STATE_EXPORTING;
931 mISDNport->b_remote_id[i] = p_m_remote_id;
932 mISDNport->b_remote_ref[i] = p_m_remote_ref;
934 if (_bchannel_create(mISDNport, i)) {
935 _bchannel_activate(mISDNport, i, 1, 0);
936 state = B_STATE_ACTIVATING;
937 timer = B_TIMER_ACTIVATING;
944 /* ignore, because not assigned */
949 case B_EVENT_TIMEOUT:
953 /* ignore due to deactivation confirm after unloading */
956 case B_STATE_ACTIVATING:
957 _bchannel_activate(mISDNport, i, 1, 1);
958 timer = B_TIMER_ACTIVATING;
961 case B_STATE_DEACTIVATING:
962 _bchannel_activate(mISDNport, i, 0, 1);
963 timer = B_TIMER_DEACTIVATING;
967 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
972 PERROR("Illegal event %d, please correct.\n", event);
975 mISDNport->b_state[i] = state;
977 unsched_timer(&mISDNport->b_timer[i]);
979 schedule_timer(&mISDNport->b_timer[i], timer, 0);
986 * check for available channel and reserve+set it.
987 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
989 * returns -(cause value) or x = channel x or 0 = no channel
990 * NOTE: no activation is done here
992 int PmISDN::seize_bchannel(int channel, int exclusive)
996 /* the channel is what we have */
997 if (p_m_b_channel == channel)
1000 /* if channel already in use, release it */
1005 if (channel==CHANNEL_NO || channel==0)
1008 /* is channel in range ? */
1010 || (channel>p_m_mISDNport->b_num && channel<16)
1011 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1012 return(-6); /* channel unacceptable */
1014 /* request exclusive channel */
1015 if (exclusive && channel>0) {
1016 i = channel-1-(channel>16);
1017 if (p_m_mISDNport->b_port[i])
1018 return(-44); /* requested channel not available */
1022 /* ask for channel */
1024 i = channel-1-(channel>16);
1025 if (p_m_mISDNport->b_port[i] == NULL)
1029 /* search for channel */
1031 while(i < p_m_mISDNport->b_num) {
1032 if (!p_m_mISDNport->b_port[i]) {
1033 channel = i+1+(i>=15);
1038 return(-34); /* no free channel */
1041 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1043 /* link Port, set parameters */
1044 p_m_mISDNport->b_port[i] = this;
1046 p_m_b_channel = channel;
1047 p_m_b_exclusive = exclusive;
1048 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1050 /* reserve channel */
1051 if (!p_m_b_reserve) {
1053 p_m_mISDNport->b_reserved++;
1060 * drop reserved channel and unset it.
1061 * deactivation is also done
1063 void PmISDN::drop_bchannel(void)
1065 /* unreserve channel */
1067 p_m_mISDNport->b_reserved--;
1071 if (p_m_b_index < 0)
1076 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1078 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1079 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1080 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1081 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1084 p_m_b_exclusive = 0;
1087 /* process bchannel export/import message from join */
1088 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1090 class Endpoint *epoint;
1092 class PmISDN *isdnport;
1093 struct mISDNport *mISDNport;
1097 case BCHANNEL_REQUEST:
1098 /* find the port object for the join object ref */
1099 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1100 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1103 if (!epoint->ep_portlist) {
1104 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1107 if (epoint->ep_portlist->next) {
1108 PERROR("join %d has enpoint %d with more than one port. this shall not happen to remote joins.\n", joinremote->j_serial, epoint->ep_serial);
1110 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1111 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1114 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1115 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1117 isdnport = (class PmISDN *)port;
1120 if (isdnport->p_m_remote_id) {
1121 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1124 mISDNport = isdnport->p_m_mISDNport;
1125 i = isdnport->p_m_b_index;
1126 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1127 add_trace("type", NULL, "export request");
1129 isdnport->p_m_remote_ref = joinremote->j_remote_ref;
1130 isdnport->p_m_remote_id = joinremote->j_remote_id;
1131 if (mISDNport && i>=0) {
1132 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1136 case BCHANNEL_RELEASE:
1137 case BCHANNEL_ASSIGN_ACK:
1138 case BCHANNEL_REMOVE_ACK:
1139 /* find mISDNport for stack ID */
1140 mISDNport = mISDNport_first;
1143 ii = mISDNport->b_num;
1145 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1151 mISDNport = mISDNport->next;
1154 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1158 if (type!=BCHANNEL_RELEASE) {
1160 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1161 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1163 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1166 isdnport = mISDNport->b_port[i];
1167 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1168 add_trace("type", NULL, "import request");
1171 isdnport->p_m_remote_ref = 0;
1172 isdnport->p_m_remote_id = 0;
1174 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1178 PERROR("received wrong bchannel message type %d from remote\n", type);
1186 audio transmission procedure:
1187 -----------------------------
1190 three sources of audio transmission:
1191 - crypto-data high priority
1192 - tones high priority (also high)
1193 - remote-data low priority
1196 a variable that temporarily shows the number of samples elapsed since last transmission process.
1197 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1200 a variable that is increased whenever data is transmitted.
1201 it is decreased while time elapses. it stores the number of samples that
1202 are currently loaded to dsp module.
1203 since clock in dsp module is the same clock for user space process, these
1207 there are two levels:
1208 ISDN_LOAD will give the load that have to be kept in dsp.
1209 ISDN_MAXLOAD will give the maximum load before dropping.
1211 * procedure for low priority data
1212 see txfromup() for procedure
1213 in short: remote data is ignored during high priority tones
1215 * procedure for high priority data
1216 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1217 if no more data is available, load becomes empty again.
1220 0 ISDN_LOAD ISDN_MAXLOAD
1221 +--------------------+----------------------+
1223 +--------------------+----------------------+
1225 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1226 0 ISDN_LOAD ISDN_MAXLOAD
1227 +--------------------+----------------------+
1228 |TTTTTTTTTTTTTTTTTTTT| |
1229 +--------------------+----------------------+
1231 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1232 0 ISDN_LOAD ISDN_MAXLOAD
1233 +--------------------+----------------------+
1234 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1235 +--------------------+----------------------+
1238 void PmISDN::update_load(void)
1240 /* don't trigger load event if: */
1241 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1244 /* don't trigger load event if event already active */
1245 if (p_m_loadtimer.active)
1248 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1251 int load_timer(struct lcr_timer *timer, void *instance, int index)
1253 class PmISDN *isdnport = (class PmISDN *)instance;
1255 isdnport->load_tx();
1260 void PmISDN::load_tx(void)
1264 struct timeval current_time;
1267 gettimeofday(¤t_time, NULL);
1268 if (p_m_last_tv_sec) {
1269 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1270 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1272 /* set clock of last process! */
1273 p_m_last_tv_sec = current_time.tv_sec;
1274 p_m_last_tv_msec = current_time.tv_usec/1000;
1276 /* process only if we have samples and we are active */
1277 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1279 if (elapsed < p_m_load)
1280 p_m_load -= elapsed;
1284 /* to send data, tone must be on */
1285 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1286 && (p_m_load < ISDN_LOAD) /* not too much load? */
1287 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1288 int tosend = ISDN_LOAD - p_m_load, length;
1289 unsigned char buf[MISDN_HEADER_LEN+tosend];
1290 struct mISDNhead *frm = (struct mISDNhead *)buf;
1291 unsigned char *p = buf+MISDN_HEADER_LEN;
1293 /* copy inband signalling (e.g. used by ss5) */
1294 if (p_m_inband_send_on && tosend) {
1295 tosend -= inband_send(p, tosend);
1298 /* copy crypto loops */
1299 while (p_m_crypt_msg_loops && tosend) {
1300 /* how much do we have to send */
1301 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1304 if (length > tosend)
1307 /* copy message (part) to buffer */
1308 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1311 p_m_crypt_msg_current += length;
1312 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1314 p_m_crypt_msg_current = 0;
1315 p_m_crypt_msg_loops--;
1316 if (!p_m_crypt_msg_loops)
1318 // puts("eine loop weniger");
1326 if (p_tone_name[0] && tosend) {
1327 tosend -= read_audio(p, tosend);
1331 if (ISDN_LOAD - p_m_load - tosend > 0) {
1332 frm->prim = PH_DATA_REQ;
1334 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1336 PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_sock[p_m_b_index].fd, ISDN_LOAD-p_m_load-tosend);
1337 p_m_load += ISDN_LOAD - p_m_load - tosend;
1342 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1343 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
1347 /* handle timeouts */
1348 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1350 class PmISDN *isdnport = (class PmISDN *)instance;
1351 struct lcr_msg *message;
1353 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);
1354 /* send timeout to endpoint */
1355 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1356 message->param.state = isdnport->p_state;
1357 message_put(message);
1364 * whenever we get audio data from bchannel, we process it here
1366 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1368 unsigned int cont = *((unsigned int *)data);
1369 struct lcr_msg *message;
1373 if (hh->prim == PH_CONTROL_IND) {
1375 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1378 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1379 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1380 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1382 add_trace("info", NULL, "DTMF is disabled");
1386 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1387 message->param.dtmf = cont & DTMF_TONE_MASK;
1388 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1389 message_put(message);
1394 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1395 add_trace("DSP-CRYPT", NULL, "error");
1397 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1398 message->param.crypt.type = CC_ERROR_IND;
1399 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1400 message_put(message);
1404 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1405 add_trace("DSP-CRYPT", NULL, "ok");
1407 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1408 message->param.crypt.type = CC_ACTBF_CONF;
1409 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1410 message_put(message);
1414 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1415 add_trace("unknown", NULL, "0x%x", cont);
1420 if (hh->prim == PH_CONTROL_IND) {
1423 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1424 add_trace("unknown", NULL, "0x%x", hh->id);
1429 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1431 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1432 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1435 /* see below (same condition) */
1436 if (p_state!=PORT_STATE_CONNECT
1437 && !p_m_mISDNport->tones)
1439 // printf(".");fflush(stdout);return;
1441 record(data, len, 1); // from up
1444 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1445 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1449 /* inband is processed */
1450 if (p_m_inband_receive_on)
1451 inband_receive(data, len);
1453 /* send to remote, if bridged */
1454 bridge_tx(data, len);
1456 /* calls will not process any audio data unless
1457 * the call is connected OR tones feature is enabled.
1459 #ifndef DEBUG_COREBRIDGE
1460 if (p_state!=PORT_STATE_CONNECT
1461 && !p_m_mISDNport->tones)
1466 /* the bearer capability must be audio in order to send and receive
1467 * audio prior or after connect.
1469 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1473 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1475 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1481 record(data, len, 0); // from down
1483 /* randomize and listen to crypt message if enabled */
1484 if (p_m_crypt_listen) {
1485 /* the noisy randomizer */
1489 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1491 cryptman_listen_bch(data, len);
1499 void PmISDN::set_echotest(int echo)
1501 if (p_m_echo != echo) {
1503 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1505 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1506 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);
1513 void PmISDN::set_tone(const char *dir, const char *tone)
1518 /* if no directory is given (by extension), we use interface.conf or options.conf */
1519 if (!dir || !dir[0]) {
1520 if (p_m_mISDNport->ifport->tones_dir[0])
1521 dir = p_m_mISDNport->ifport->tones_dir;
1522 else if (options.tones_dir[0])
1523 dir = options.tones_dir;
1528 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1534 /* check for dsp tones */
1535 if (!strcmp(dir, "american"))
1537 if (!strcmp(dir, "german"))
1539 if (!strcmp(dir, "oldgerman"))
1540 dsp = DSP_OLDGERMAN;
1542 /* check if we NOT really have to use a dsp-tone */
1543 if (dsp == DSP_NONE) {
1546 if (p_m_b_index > -1)
1547 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) {
1548 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1549 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1552 Port::set_tone(dir, tone);
1556 /* now we USE dsp-tone, convert name */
1557 if (!strcmp(tone, "dialtone")) {
1559 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1560 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1561 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1563 } else if (!strcmp(tone, "dialpbx")) {
1565 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1566 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1567 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1569 } else if (!strcmp(tone, "ringing")) {
1571 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1572 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1573 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1575 } else if (!strcmp(tone, "ringpbx")) {
1577 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1578 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1579 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1581 } else if (!strcmp(tone, "busy")) {
1584 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1585 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1586 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1588 } else if (!strcmp(tone, "release")) {
1591 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1592 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1593 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1595 } else if (!strcmp(tone, "cause_10"))
1597 else if (!strcmp(tone, "cause_11"))
1599 else if (!strcmp(tone, "cause_22")) {
1601 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1602 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1603 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1605 } else if (!strncmp(tone, "cause_", 6))
1606 id = TONE_SPECIAL_INFO;
1610 /* if we have a tone that is not supported by dsp */
1611 if (id==TONE_OFF && tone[0])
1615 if (p_m_tone != id) {
1618 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1619 if (p_m_b_index > -1)
1620 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)
1621 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);
1623 /* turn user-space tones off in cases of no tone OR dsp tone */
1624 Port::set_tone("",NULL);
1628 /* MESSAGE_mISDNSIGNAL */
1629 //extern struct lcr_msg *dddebug;
1630 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1632 int oldconf, newconf;
1633 switch(param->mISDNsignal.message) {
1634 case mISDNSIGNAL_VOLUME:
1635 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1636 p_m_tx_gain = param->mISDNsignal.tx_gain;
1637 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1638 if (p_m_b_index > -1)
1639 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)
1640 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);
1642 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1643 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1644 p_m_rx_gain = param->mISDNsignal.rx_gain;
1645 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1646 if (p_m_b_index > -1)
1647 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)
1648 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);
1650 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1653 case mISDNSIGNAL_CONF:
1654 oldconf = p_m_mute?0:p_m_conf;
1655 p_m_conf = param->mISDNsignal.conf;
1656 newconf = p_m_mute?0:p_m_conf;
1657 set_conf(oldconf, newconf);
1660 case mISDNSIGNAL_DELAY:
1661 if (p_m_delay != param->mISDNsignal.delay) {
1662 p_m_delay = param->mISDNsignal.delay;
1663 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1664 if (p_m_b_index > -1)
1665 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)
1666 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);
1668 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1672 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1677 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1679 struct lcr_msg *message;
1681 switch(param->crypt.type) {
1682 case CC_ACTBF_REQ: /* activate blowfish */
1684 p_m_crypt_key_len = param->crypt.len;
1685 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1686 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1687 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1688 message->param.crypt.type = CC_ERROR_IND;
1689 message_put(message);
1692 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1694 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1695 if (p_m_b_index > -1)
1696 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)
1697 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);
1700 case CC_DACT_REQ: /* deactivate session encryption */
1705 case CR_LISTEN_REQ: /* start listening to messages */
1706 p_m_crypt_listen = 1;
1708 p_m_crypt_listen_state = 0;
1711 case CR_UNLISTEN_REQ: /* stop listening to messages */
1712 p_m_crypt_listen = 0;
1716 case CR_MESSAGE_REQ: /* send message */
1717 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1718 if (!p_m_crypt_msg_len) {
1719 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1722 p_m_crypt_msg_current = 0; /* reset */
1723 p_m_crypt_msg_loops = 6; /* enable */
1727 /* disable txmix, or we get corrupt data due to audio process */
1728 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1729 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1730 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1736 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1742 * endpoint sends messages to the port
1744 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1746 if (Port::message_epoint(epoint_id, message_id, param)) {
1747 if (message_id == MESSAGE_BRIDGE)
1752 switch(message_id) {
1753 case MESSAGE_mISDNSIGNAL: /* user command */
1754 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1755 message_mISDNsignal(epoint_id, message_id, param);
1758 case MESSAGE_CRYPT: /* crypt control command */
1759 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1760 message_crypt(epoint_id, message_id, param);
1767 void PmISDN::update_rxoff(void)
1769 int tx_dejitter = 0;
1771 /* call bridges in user space OR crypto OR recording */
1772 if (p_bridge || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1773 /* rx IS required */
1777 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1778 if (p_m_b_index > -1)
1779 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1780 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1783 /* rx NOT required */
1787 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1788 if (p_m_b_index > -1)
1789 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1790 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1795 /* txdata IS required */
1799 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1800 if (p_m_b_index > -1)
1801 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1802 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1805 /* txdata NOT required */
1809 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1810 if (p_m_b_index > -1)
1811 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1812 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1815 /* dejitter on bridge */
1818 if (p_m_tx_dejitter != tx_dejitter) {
1819 p_m_tx_dejitter = tx_dejitter;
1820 PDEBUG(DEBUG_BCHANNEL, "we change dejitter mode to delay=%d.\n", p_m_tx_dejitter);
1821 if (p_m_b_index > -1)
1822 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)
1823 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);
1827 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1829 struct mISDNport *mISDNport;
1835 /* unset global semaphore */
1837 // with a very small incident, upqueue_avail may be set by mISDN thread and
1838 // another byte may be sent to the pipe, which causes a call to this function
1839 // again with nothing in the upqueue. this is no problem.
1840 ret = read(fd->fd, &byte, 1);
1842 /* process all ports */
1843 mISDNport = mISDNport_first;
1845 /* handle queued up-messages (d-channel) */
1846 if (!mISDNport->isloopback) {
1847 while ((mb = mdequeue(&mISDNport->upqueue))) {
1850 case MPH_ACTIVATE_IND:
1851 if (mISDNport->l1link != 1) {
1852 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1854 mISDNport->l1link = 1;
1858 case MPH_DEACTIVATE_IND:
1859 if (mISDNport->l1link != 0) {
1860 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1862 mISDNport->l1link = 0;
1866 case MPH_INFORMATION_IND:
1867 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1869 case L1_SIGNAL_LOS_ON:
1872 case L1_SIGNAL_LOS_OFF:
1875 case L1_SIGNAL_AIS_ON:
1878 case L1_SIGNAL_AIS_OFF:
1881 case L1_SIGNAL_RDI_ON:
1884 case L1_SIGNAL_RDI_OFF:
1887 case L1_SIGNAL_SLIP_TX:
1888 mISDNport->slip_tx++;
1890 case L1_SIGNAL_SLIP_RX:
1891 mISDNport->slip_rx++;
1896 case MT_L2ESTABLISH:
1897 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1898 add_trace("tei", NULL, "%d", l3m->pid);
1900 mISDNport->l2link = 1;
1902 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1903 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1904 if (mISDNport->l2establish.active) {
1905 unsched_timer(&mISDNport->l2establish);
1906 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1913 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1914 if (!mISDNport->l2establish.active) {
1915 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1916 add_trace("tei", NULL, "%d", l3m->pid);
1918 /* down if not nt-ptmp */
1919 if (!mISDNport->ntmode || mISDNport->ptp)
1920 mISDNport->l2link = 0;
1922 if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1923 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1924 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1925 schedule_timer(&mISDNport->l2establish, 5, 0);
1926 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1932 /* l3-data is sent to LCR */
1933 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1939 mISDNport = mISDNport->next;
1944 /* l2 establish timer fires */
1945 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1947 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1949 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1950 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1951 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1952 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1958 /* handle frames from bchannel */
1959 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1961 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1962 unsigned char buffer[2048+MISDN_HEADER_LEN];
1963 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1966 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1968 PERROR("read error frame, errno %d\n", errno);
1971 if (ret < (int)MISDN_HEADER_LEN) {
1972 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1976 /* we don't care about confirms, we use rx data to sync tx */
1980 /* we receive audio data, we respond to it AND we send tones */
1985 case PH_CONTROL_IND:
1986 if (mISDNport->b_port[i])
1987 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1989 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1992 case PH_ACTIVATE_IND:
1993 case DL_ESTABLISH_IND:
1994 case PH_ACTIVATE_CNF:
1995 case DL_ESTABLISH_CNF:
1996 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1997 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2000 case PH_DEACTIVATE_IND:
2001 case DL_RELEASE_IND:
2002 case PH_DEACTIVATE_CNF:
2003 case DL_RELEASE_CNF:
2004 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2005 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2009 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2015 /* process timer events for bchannel handling */
2016 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2018 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2020 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2026 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2030 * l3m must be queued, except for MT_ASSIGN
2033 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2036 #ifdef OLD_MT_ASSIGN
2037 /* special MT_ASSIGN handling:
2039 * if we request a PID from mlayer, we always do it while lcr is locked.
2040 * therefore we must check the MT_ASSIGN reply first before we lock.
2041 * this is because the MT_ASSIGN reply is received with the requesting
2042 * process, not by the mlayer thread!
2043 * this means, that the reply is sent during call of the request.
2044 * we must check if we get a reply and we know that we lcr is currently
2047 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2048 /* let's do some checking if someone changes stack behaviour */
2049 if (mt_assign_pid != 0)
2050 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2051 mt_assign_pid = pid;
2055 /* queue message, create, if required */
2057 l3m = alloc_l3_msg();
2059 FATAL("No memory for layer 3 message\n");
2061 mb = container_of(l3m, struct mbuffer, l3);
2064 mqueue_tail(&mISDNport->upqueue, mb);
2065 if (!upqueue_avail) {
2066 // multiple threads may cause multiple calls of this section, but this
2067 // results only in multiple processing of the upqueue read.
2068 // this is no problem.
2072 ret = write(upqueue_pipe[1], &byte, 1);
2077 int mISDN_getportbyname(int sock, int cnt, char *portname)
2079 struct mISDN_devinfo devinfo;
2083 while (port < cnt) {
2085 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2088 if (!strcasecmp(devinfo.name, portname))
2099 * global function to add a new card (port)
2101 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2104 struct mISDNport *mISDNport, **mISDNportp;
2105 int port = ifport->portnum;
2106 int ptp = ifport->ptp;
2107 int force_nt = ifport->nt;
2108 int l1hold = ifport->l1hold;
2109 int l2hold = ifport->l2hold;
2111 int ss5 = ifport->ss5;
2115 // struct mlayer3 *ml3;
2116 struct mISDN_devinfo devinfo;
2117 unsigned int protocol, prop;
2120 //printf("%s == %s\n", ifport->portname, options.loopback_int);
2121 if (!strcmp(ifport->portname, options.loopback_lcr))
2125 if (mISDNloop_open())
2129 /* check port counts */
2130 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2132 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2137 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2141 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2144 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
2146 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2149 // note: 'port' has still the port number
2151 if (port>cnt || port<0) {
2152 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2156 /* get port attributes */
2157 pri = bri = pots = nt = te = 0;
2159 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2161 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2164 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2168 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2172 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2176 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2181 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2187 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2192 if (force_nt && !nt) {
2193 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2197 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2200 if (pots && !bri && !pri) {
2201 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2205 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2209 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2212 /* set NT by turning off TE */
2215 /* if TE an NT is supported (and not forced to NT), turn off NT */
2219 /* check for double use of port */
2221 mISDNport = mISDNport_first;
2223 if (mISDNport->portnum == port)
2225 mISDNport = mISDNport->next;
2228 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2233 /* check for continous channelmap with no bchannel on slot 16 */
2234 if (test_channelmap(0, devinfo.channelmap)) {
2235 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2239 while(i < (int)devinfo.nrbchan + 1) {
2241 if (test_channelmap(i, devinfo.channelmap)) {
2242 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2246 if (!test_channelmap(i, devinfo.channelmap)) {
2247 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2254 /* add mISDNport structure */
2255 mISDNportp = &mISDNport_first;
2257 mISDNportp = &((*mISDNportp)->next);
2258 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2259 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2261 /* loop/ss5 link is always active */
2262 mISDNport->l1link = 1;
2263 mISDNport->l2link = 1;
2265 mISDNport->l1link = -1;
2266 mISDNport->l2link = -1;
2268 mISDNport->isloopback = loop;
2270 *mISDNportp = mISDNport;
2272 /* if pri, must set PTP */
2276 /* set ss5 params */
2278 /* try to keep interface enabled */
2298 /* allocate ressources of port */
2299 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2300 prop = (1 << MISDN_FLG_L2_CLEAN);
2301 if (ptp) // ptp forced
2302 prop |= (1 << MISDN_FLG_PTP);
2303 if (nt) // supports hold/retrieve on nt-mode
2304 prop |= (1 << MISDN_FLG_NET_HOLD);
2305 if (l1hold) // supports layer 1 hold
2306 prop |= (1 << MISDN_FLG_L1_HOLD);
2307 if (l2hold) // supports layer 2 hold
2308 prop |= (1 << MISDN_FLG_L2_HOLD);
2309 /* open layer 3 and init upqueue */
2311 unsigned long on = 1;
2312 struct sockaddr_mISDN addr;
2314 if (devinfo.nrbchan < 8) {
2315 printf("loop port %d has a low number of bchannels. (only %d) remember that all interfaces that requires a loopback could run out of channels\n", port, devinfo.nrbchan);
2316 // mISDNport_close(mISDNport);
2320 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
2321 PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
2322 mISDNport_close(mISDNport);
2325 /* set nonblocking io */
2326 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2327 PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
2328 mISDNport_close(mISDNport);
2331 /* bind socket to dchannel */
2332 memset(&addr, 0, sizeof(addr));
2333 addr.family = AF_ISDN;
2336 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2337 PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
2338 mISDNport_close(mISDNport);
2342 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2343 mqueue_init(&mISDNport->upqueue);
2344 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2345 if (!mISDNport->ml3) {
2346 mqueue_purge(&mISDNport->upqueue);
2347 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2355 "PORT (open failed)");
2357 mISDNport_close(mISDNport);
2362 SCPY(mISDNport->name, devinfo.name);
2363 mISDNport->b_num = devinfo.nrbchan;
2364 mISDNport->portnum = port;
2365 mISDNport->ntmode = nt;
2366 mISDNport->tespecial = ifport->tespecial;
2367 mISDNport->pri = pri;
2368 mISDNport->ptp = ptp;
2369 mISDNport->l1hold = l1hold;
2370 mISDNport->l2hold = l2hold;
2371 mISDNport->ss5 = ss5;
2372 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2374 while(i < mISDNport->b_num) {
2375 mISDNport->b_state[i] = B_STATE_IDLE;
2376 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2380 /* if ptp, pull up the link */
2381 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2382 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2383 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2384 add_trace("tei", NULL, "%d", 0);
2386 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2389 /* for nt-mode ptmp the link is always up */
2390 if (mISDNport->ntmode && !mISDNport->ptp)
2391 mISDNport->l2link = 1;
2393 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2395 start_trace(mISDNport->portnum,
2403 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2404 add_trace("channels", NULL, "%d", mISDNport->b_num);
2406 add_trace("ccitt#5", NULL, "enabled");
2414 * load static port instances, if required by mISDNport
2416 void mISDNport_static(struct mISDNport *mISDNport)
2421 while(i < mISDNport->b_num) {
2424 ss5_create_channel(mISDNport, i);
2432 * function to free ALL cards (ports)
2434 void mISDNport_close_all(void)
2436 /* free all ports */
2437 while(mISDNport_first)
2438 mISDNport_close(mISDNport_first);
2442 * free only one port
2444 void mISDNport_close(struct mISDNport *mISDNport)
2446 struct mISDNport **mISDNportp;
2448 class PmISDN *isdnport;
2451 /* remove all port instance that are linked to this mISDNport */
2455 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2456 isdnport = (class PmISDN *)port;
2457 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2458 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2466 /* only if we are already part of interface */
2467 if (mISDNport->ifport) {
2468 start_trace(mISDNport->portnum,
2469 mISDNport->ifport->interface,
2479 /* free bchannels */
2481 while(i < mISDNport->b_num) {
2482 if (mISDNport->b_sock[i].inuse) {
2483 _bchannel_destroy(mISDNport, i);
2484 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2486 if (mISDNport->b_timer[i].inuse) {
2487 del_timer(&mISDNport->b_timer[i]);
2491 del_timer(&mISDNport->l2establish);
2493 /* close layer 3, if open */
2494 if (!mISDNport->isloopback && mISDNport->ml3) {
2495 close_layer3(mISDNport->ml3);
2498 /* close gsm socket, if open */
2499 if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
2500 close(mISDNport->lcr_sock);
2504 if (!mISDNport->isloopback)
2505 mqueue_purge(&mISDNport->upqueue);
2507 /* remove from list */
2508 mISDNportp = &mISDNport_first;
2509 while(*mISDNportp) {
2510 if (*mISDNportp == mISDNport) {
2511 *mISDNportp = (*mISDNportp)->next;
2515 mISDNportp = &((*mISDNportp)->next);
2519 FATAL("mISDNport not in list\n");
2521 FREE(mISDNport, sizeof(struct mISDNport));
2528 * enque data from upper buffer
2530 int PmISDN::bridge_rx(unsigned char *data, int length)
2532 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2533 struct mISDNhead *hh = (struct mISDNhead *)buf;
2536 if (p_m_b_index < 0)
2538 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2541 /* check if high priority tones exist
2542 * ignore data in this case
2544 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2547 /* preload procedure
2548 * if transmit buffer in DSP module is empty,
2549 * preload it to DSP_LOAD to prevent jitter gaps.
2551 if (p_m_load == 0 && ISDN_LOAD > 0) {
2552 hh->prim = PH_DATA_REQ;
2554 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2555 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2557 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2558 p_m_load += ISDN_LOAD;
2559 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
2562 /* drop if load would exceed ISDN_MAXLOAD
2563 * this keeps the delay not too high
2565 if (p_m_load+length > ISDN_MAXLOAD)
2568 /* make and send frame */
2569 hh->prim = PH_DATA_REQ;
2571 memcpy(buf+MISDN_HEADER_LEN, data, length);
2572 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2574 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2580 int PmISDN::inband_send(unsigned char *buffer, int len)
2582 PERROR("this function must be derived to function!\n");
2586 void PmISDN::inband_send_on(void)
2588 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2589 p_m_inband_send_on = 1;
2590 /* trigger inband transmit */
2594 void PmISDN::inband_send_off(void)
2596 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2597 p_m_inband_send_on = 0;
2600 void PmISDN::inband_receive(unsigned char *buffer, int len)
2603 // if (len >= SS5_DECODER_NPOINTS)
2604 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2605 PERROR("this function must be derived to function!\n");
2608 void PmISDN::inband_receive_on(void)
2610 /* this must work during constructor, see ss5.cpp */
2611 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2612 p_m_inband_receive_on = 1;
2616 void PmISDN::inband_receive_off(void)
2618 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2619 p_m_inband_receive_on = 0;
2623 void PmISDN::mute_on(void)
2627 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2629 set_conf(p_m_conf, 0);
2632 void PmISDN::mute_off(void)
2636 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2638 set_conf(0, p_m_conf);