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;
144 p_m_inband_send_on = 0;
145 p_m_inband_receive_on = 0;
146 p_m_dtmf = !mISDNport->ifport->nodtmf;
147 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
148 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
149 p_m_remote_ref = 0; /* channel shall be exported to given remote */
150 p_m_remote_id = 0; /* remote admin socket */
151 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
154 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
155 add_timer(&p_m_loadtimer, load_timer, this, 0);
161 p_m_crypt_listen = 0;
162 p_m_crypt_msg_loops = 0;
163 p_m_crypt_msg_loops = 0;
164 p_m_crypt_msg_len = 0;
165 p_m_crypt_msg[0] = '\0';
166 p_m_crypt_msg_current = 0;
167 p_m_crypt_key_len = 0;
168 p_m_crypt_listen = 0;
169 p_m_crypt_listen_state = 0;
170 p_m_crypt_listen_len = 0;
171 p_m_crypt_listen_msg[0] = '\0';
172 p_m_crypt_listen_crc = 0;
173 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
174 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
175 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
179 /* if any channel requested by constructor */
180 if (channel == CHANNEL_ANY) {
181 /* reserve channel */
183 mISDNport->b_reserved++;
186 /* reserve channel */
187 if (channel > 0) // only if constructor was called with a channel resevation
188 seize_bchannel(channel, exclusive);
190 /* we increase the number of objects: */
192 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
193 //inband_receive_on();
202 struct lcr_msg *message;
204 del_timer(&p_m_timeout);
205 del_timer(&p_m_loadtimer);
207 /* remove bchannel relation */
211 while (p_epointlist) {
212 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
213 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
214 message->param.disconnectinfo.cause = 16;
215 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
216 message_put(message);
217 /* remove from list */
218 free_epointlist(p_epointlist);
221 /* we decrease the number of objects: */
222 p_m_mISDNport->use--;
223 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
230 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
232 /* init trace with given values */
233 start_trace(mISDNport?mISDNport->portnum:-1,
234 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
235 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
236 port?port->p_dialinginfo.id:NULL,
239 port?port->p_serial:0,
247 static struct isdn_message {
251 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
252 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
253 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
254 {"DL_RELEASE", L2_RELEASE_REQ},
255 {"UNKNOWN", L3_UNKNOWN_REQ},
256 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
257 {"MT_SETUP", L3_SETUP_REQ},
258 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
259 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
260 {"MT_ALERTING", L3_ALERTING_REQ},
261 {"MT_CONNECT", L3_CONNECT_REQ},
262 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
263 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
264 {"MT_RELEASE", L3_RELEASE_REQ},
265 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
266 {"MT_INFORMATION", L3_INFORMATION_REQ},
267 {"MT_PROGRESS", L3_PROGRESS_REQ},
268 {"MT_NOTIFY", L3_NOTIFY_REQ},
269 {"MT_SUSPEND", L3_SUSPEND_REQ},
270 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
271 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
272 {"MT_RESUME", L3_RESUME_REQ},
273 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
274 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
275 {"MT_HOLD", L3_HOLD_REQ},
276 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
277 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
278 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
279 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
280 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
281 {"MT_FACILITY", L3_FACILITY_REQ},
282 {"MT_STATUS", L3_STATUS_REQ},
283 {"MT_RESTART", L3_RESTART_REQ},
284 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
285 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
288 static const char *isdn_prim[4] = {
294 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
299 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
300 /* select message and primitive text */
302 while(isdn_message[i].name) {
303 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
304 if (isdn_message[i].value == (msg&0xffffff00)) {
305 SCPY(msgtext, isdn_message[i].name);
310 SCAT(msgtext, isdn_prim[msg&0x00000003]);
313 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
315 if (mISDNport->ntmode) {
316 if (direction == DIRECTION_OUT)
317 SCAT(msgtext, " N->U");
319 SCAT(msgtext, " N<-U");
321 if (direction == DIRECTION_OUT)
322 SCAT(msgtext, " U->N");
324 SCAT(msgtext, " U<-N");
329 /* init trace with given values */
330 start_trace(mISDNport?mISDNport->portnum:-1,
331 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
332 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
333 port?port->p_dialinginfo.id:NULL,
336 port?port->p_serial:0,
342 * send control information to the channel (dsp-module)
344 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
346 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
347 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
348 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
354 ctrl->prim = PH_CONTROL_REQ;
358 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
360 PERROR("Failed to send to socket %d\n", sock);
361 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
362 if (c1 == DSP_CONF_JOIN)
363 add_trace(trace_name, NULL, "0x%08x", trace_value);
365 add_trace(trace_name, NULL, "%d", trace_value);
369 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)
371 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
372 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
373 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
379 ctrl->prim = PH_CONTROL_REQ;
382 memcpy(d, c2, c2_len);
383 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
385 PERROR("Failed to send to socket %d\n", sock);
386 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
387 add_trace(trace_name, NULL, "%d", trace_value);
391 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
394 * subfunction for bchannel_event
397 static int _bchannel_create(struct mISDNport *mISDNport, int i)
400 struct sockaddr_mISDN addr;
402 if (mISDNport->b_sock[i].inuse) {
403 PERROR("Error: Socket already created for index %d\n", i);
408 //#warning testing without DSP
409 // 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);
410 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);
411 if (mISDNport->b_sock[i].fd < 0) {
412 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
416 /* register callback for read */
417 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
419 /* bind socket to bchannel */
420 addr.family = AF_ISDN;
421 addr.dev = mISDNport->portnum;
422 addr.channel = i+1+(i>=15);
423 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
425 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);
426 close(mISDNport->b_sock[i].fd);
427 unregister_fd(&mISDNport->b_sock[i]);
431 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
432 add_trace("channel", NULL, "%d", i+1+(i>=15));
433 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
441 * subfunction for bchannel_event
442 * activate / deactivate request
444 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
446 struct mISDNhead act;
449 if (!mISDNport->b_sock[i].inuse)
451 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
453 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
455 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
458 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
459 add_trace("channel", NULL, "%d", i+1+(i>=15));
461 add_trace("event", NULL, "timeout recovery");
467 * subfunction for bchannel_event
470 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
475 if (!mISDNport->b_sock[i].inuse)
477 handle = mISDNport->b_sock[i].fd;
478 port = mISDNport->b_port[i];
479 mode = mISDNport->b_mode[i];
481 PERROR("bchannel index i=%d not associated with a port object\n", i);
485 /* set dsp features */
486 if (port->p_m_txdata)
487 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
488 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
489 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
490 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
491 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
492 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
493 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
494 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
495 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
496 if (port->p_m_conf && !port->p_m_mute)
497 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
499 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
500 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
501 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
503 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
504 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
505 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
506 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
507 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
508 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
509 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);
513 void PmISDN::set_conf(int oldconf, int newconf)
515 if (oldconf != newconf) {
516 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
517 if (p_m_b_index > -1)
518 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
519 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);
521 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
526 * subfunction for bchannel_event
529 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
531 if (!mISDNport->b_sock[i].inuse)
533 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
534 add_trace("channel", NULL, "%d", i+1+(i>=15));
535 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
537 close(mISDNport->b_sock[i].fd);
538 unregister_fd(&mISDNport->b_sock[i]);
546 A bchannel goes through the following states in this order:
549 No one is using the bchannel.
550 It is available and not linked to Port class, nor reserved.
553 The bchannel stack is created and an activation request is sent.
554 It MAY be linked to Port class, but already unlinked due to Port class removal.
557 The bchannel is active and cofigured to the Port class needs.
558 Also it is linked to a Port class, otherwhise it would be deactivated.
560 - B_STATE_DEACTIVATING
561 The bchannel is in deactivating state, due to deactivation request.
562 It may be linked to a Port class, that likes to reactivate it.
566 After deactivating bchannel, and if not used, the bchannel becomes idle again.
568 Also the bchannel may be exported, but only if the state is or becomes idle:
571 The bchannel assignment has been sent to the remove application.
574 The bchannel assignment is acknowledged by the remote application.
577 The bchannel is re-imported by mISDN port object.
581 After re-importing bchannel, and if not used, the bchannel becomes idle again.
584 A bchannel can have the following events:
587 A bchannel is required by a Port class.
590 The bchannel beomes active.
593 The bchannel is not required by Port class anymore
595 - B_EVENT_DEACTIVATED
596 The bchannel becomes inactive.
599 The bchannel is now used by remote application.
602 The bchannel is not used by remote application.
604 - B_EVENT_EXPORTREQUEST
605 The bchannel shall be exported to the remote application.
607 - B_EVENT_IMPORTREQUEST
608 The bchannel is released from the remote application.
610 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
612 if an export request is receive by remote application, p_m_remote_* is set.
613 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.)
614 - set on export request from remote application (if port is assigned)
615 - set on channel use, if requested by remote application (p_m_remote_*)
616 - cleared on drop request
618 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
619 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
620 the bchannel import/export is acknowledged with stack given.
622 if exporting, b_remote_*[index] is set to the remote socket id.
623 if importing has been acknowledged. b_remote_*[index] is cleared.
628 * process bchannel events
629 * - mISDNport is a pointer to the port's structure
630 * - i is the index of the bchannel
631 * - event is the B_EVENT_* value
632 * - port is the PmISDN class pointer
634 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
636 class PmISDN *b_port = mISDNport->b_port[i];
637 int state = mISDNport->b_state[i];
638 int timer = -1; // no change
639 unsigned int p_m_remote_ref = 0;
640 unsigned int p_m_remote_id = 0;
643 char *p_m_pipeline = NULL;
644 unsigned char *p_m_crypt_key = NULL;
645 int p_m_crypt_key_len = 0;
646 int p_m_crypt_key_type = 0;
647 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
650 p_m_remote_id = b_port->p_m_remote_id;
651 p_m_remote_ref = b_port->p_m_remote_ref;
652 p_m_tx_gain = b_port->p_m_tx_gain;
653 p_m_rx_gain = b_port->p_m_rx_gain;
654 p_m_pipeline = b_port->p_m_pipeline;
655 p_m_crypt_key = b_port->p_m_crypt_key;
656 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
657 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
662 /* port must be linked in order to allow activation */
664 FATAL("bchannel must be linked to a Port class\n");
667 if (p_m_remote_ref) {
668 /* export bchannel */
669 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);
670 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
671 add_trace("type", NULL, "assign");
672 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
674 state = B_STATE_EXPORTING;
675 mISDNport->b_remote_id[i] = p_m_remote_id;
676 mISDNport->b_remote_ref[i] = p_m_remote_ref;
678 /* create stack and send activation request */
679 if (_bchannel_create(mISDNport, i)) {
680 _bchannel_activate(mISDNport, i, 1, 0);
681 state = B_STATE_ACTIVATING;
682 timer = B_TIMER_ACTIVATING;
687 case B_STATE_ACTIVATING:
688 case B_STATE_EXPORTING:
689 /* do nothing, because it is already activating */
692 case B_STATE_DEACTIVATING:
693 case B_STATE_IMPORTING:
694 /* do nothing, because we must wait until we can reactivate */
698 /* problems that might ocurr:
699 * B_EVENT_USE is received when channel already in use.
700 * bchannel exported, but not freed by other port
702 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
706 case B_EVENT_EXPORTREQUEST:
707 /* special case where the bchannel is requested by remote */
708 if (!p_m_remote_ref) {
709 PERROR("export request without remote channel set, please correct.\n");
714 /* in case, the bchannel is exported right after seize_bchannel */
715 /* export bchannel */
716 /* p_m_remote_id is set, when this event happens. */
717 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);
718 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
719 add_trace("type", NULL, "assign");
720 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
722 state = B_STATE_EXPORTING;
723 mISDNport->b_remote_id[i] = p_m_remote_id;
724 mISDNport->b_remote_ref[i] = p_m_remote_ref;
727 case B_STATE_ACTIVATING:
728 case B_STATE_EXPORTING:
729 /* do nothing, because it is already activating */
732 case B_STATE_DEACTIVATING:
733 case B_STATE_IMPORTING:
734 /* do nothing, because we must wait until we can reactivate */
738 /* bchannel is active, so we deactivate */
739 _bchannel_activate(mISDNport, i, 0, 0);
740 state = B_STATE_DEACTIVATING;
741 timer = B_TIMER_DEACTIVATING;
745 /* problems that might ocurr:
746 * ... when channel already in use.
747 * bchannel exported, but not freed by other port
749 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
753 case B_EVENT_IMPORTREQUEST:
754 /* special case where the bchannel is released by remote */
755 if (p_m_remote_ref) {
756 PERROR("import request with remote channel set, please correct.\n");
762 /* bchannel is not exported */
765 case B_STATE_ACTIVATING:
766 case B_STATE_EXPORTING:
767 /* do nothing because we must wait until bchanenl is active before deactivating */
771 /* bchannel is exported, so we re-import */
772 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
773 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
774 add_trace("type", NULL, "remove");
775 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
777 state = B_STATE_IMPORTING;
780 case B_STATE_DEACTIVATING:
781 case B_STATE_IMPORTING:
782 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
786 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
790 case B_EVENT_ACTIVATED:
793 case B_STATE_ACTIVATING:
794 if (b_port && !p_m_remote_id) {
795 /* bchannel is active and used by Port class, so we configure bchannel */
796 _bchannel_configure(mISDNport, i);
797 state = B_STATE_ACTIVE;
798 b_port->p_m_load = 0;
800 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
801 _bchannel_activate(mISDNport, i, 0, 0);
802 state = B_STATE_DEACTIVATING;
803 timer = B_TIMER_DEACTIVATING;
808 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
812 case B_EVENT_EXPORTED:
814 case B_STATE_EXPORTING:
815 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
816 /* remote export done */
817 state = B_STATE_REMOTE;
819 /* bchannel is now exported, but we need bchannel back
820 * OR bchannel is not used anymore
821 * OR bchannel has been exported to an obsolete ref,
822 * so reimport, to later export to new remote */
823 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
824 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
825 add_trace("type", NULL, "remove");
826 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
828 state = B_STATE_IMPORTING;
833 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
839 FATAL("bchannel must be linked to a Port class\n");
842 /* bchannel is idle due to an error, so we do nothing */
845 case B_STATE_ACTIVATING:
846 case B_STATE_EXPORTING:
847 /* do nothing because we must wait until bchanenl is active before deactivating */
851 /* bchannel is active, so we deactivate */
852 _bchannel_activate(mISDNport, i, 0, 0);
853 state = B_STATE_DEACTIVATING;
854 timer = B_TIMER_DEACTIVATING;
858 /* bchannel is exported, so we re-import */
859 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
860 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
861 add_trace("type", NULL, "remove");
862 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
864 state = B_STATE_IMPORTING;
867 case B_STATE_DEACTIVATING:
868 case B_STATE_IMPORTING:
869 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
873 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
877 case B_EVENT_DEACTIVATED:
881 /* ignore due to deactivation confirm after unloading */
884 case B_STATE_DEACTIVATING:
885 _bchannel_destroy(mISDNport, i);
886 state = B_STATE_IDLE;
888 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
889 if (p_m_remote_ref) {
890 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);
891 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
892 add_trace("type", NULL, "assign");
893 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
895 state = B_STATE_EXPORTING;
896 mISDNport->b_remote_id[i] = p_m_remote_id;
897 mISDNport->b_remote_ref[i] = p_m_remote_ref;
899 if (_bchannel_create(mISDNport, i)) {
900 _bchannel_activate(mISDNport, i, 1, 0);
901 state = B_STATE_ACTIVATING;
902 timer = B_TIMER_ACTIVATING;
909 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
913 case B_EVENT_IMPORTED:
915 case B_STATE_IMPORTING:
916 state = B_STATE_IDLE;
917 mISDNport->b_remote_id[i] = 0;
918 mISDNport->b_remote_ref[i] = 0;
920 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
921 if (p_m_remote_ref) {
922 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);
923 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
924 add_trace("type", NULL, "assign");
925 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
927 state = B_STATE_EXPORTING;
928 mISDNport->b_remote_id[i] = p_m_remote_id;
929 mISDNport->b_remote_ref[i] = p_m_remote_ref;
931 if (_bchannel_create(mISDNport, i)) {
932 _bchannel_activate(mISDNport, i, 1, 0);
933 state = B_STATE_ACTIVATING;
934 timer = B_TIMER_ACTIVATING;
941 /* ignore, because not assigned */
946 case B_EVENT_TIMEOUT:
950 /* ignore due to deactivation confirm after unloading */
953 case B_STATE_ACTIVATING:
954 _bchannel_activate(mISDNport, i, 1, 1);
955 timer = B_TIMER_ACTIVATING;
958 case B_STATE_DEACTIVATING:
959 _bchannel_activate(mISDNport, i, 0, 1);
960 timer = B_TIMER_DEACTIVATING;
964 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
969 PERROR("Illegal event %d, please correct.\n", event);
972 mISDNport->b_state[i] = state;
974 unsched_timer(&mISDNport->b_timer[i]);
976 schedule_timer(&mISDNport->b_timer[i], timer, 0);
983 * check for available channel and reserve+set it.
984 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
986 * returns -(cause value) or x = channel x or 0 = no channel
987 * NOTE: no activation is done here
989 int PmISDN::seize_bchannel(int channel, int exclusive)
993 /* the channel is what we have */
994 if (p_m_b_channel == channel)
997 /* if channel already in use, release it */
1002 if (channel==CHANNEL_NO || channel==0)
1005 /* is channel in range ? */
1007 || (channel>p_m_mISDNport->b_num && channel<16)
1008 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1009 return(-6); /* channel unacceptable */
1011 /* request exclusive channel */
1012 if (exclusive && channel>0) {
1013 i = channel-1-(channel>16);
1014 if (p_m_mISDNport->b_port[i])
1015 return(-44); /* requested channel not available */
1019 /* ask for channel */
1021 i = channel-1-(channel>16);
1022 if (p_m_mISDNport->b_port[i] == NULL)
1026 /* search for channel */
1028 while(i < p_m_mISDNport->b_num) {
1029 if (!p_m_mISDNport->b_port[i]) {
1030 channel = i+1+(i>=15);
1035 return(-34); /* no free channel */
1038 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1040 /* link Port, set parameters */
1041 p_m_mISDNport->b_port[i] = this;
1043 p_m_b_channel = channel;
1044 p_m_b_exclusive = exclusive;
1045 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1047 /* reserve channel */
1048 if (!p_m_b_reserve) {
1050 p_m_mISDNport->b_reserved++;
1057 * drop reserved channel and unset it.
1058 * deactivation is also done
1060 void PmISDN::drop_bchannel(void)
1062 /* unreserve channel */
1064 p_m_mISDNport->b_reserved--;
1068 if (p_m_b_index < 0)
1073 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1075 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1076 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1077 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1078 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1081 p_m_b_exclusive = 0;
1084 /* process bchannel export/import message from join */
1085 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1087 class Endpoint *epoint;
1089 class PmISDN *isdnport;
1090 struct mISDNport *mISDNport;
1094 case BCHANNEL_REQUEST:
1095 /* find the port object for the join object ref */
1096 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1097 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1100 if (!epoint->ep_portlist) {
1101 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1104 if (epoint->ep_portlist->next) {
1105 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);
1107 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1108 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1111 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1112 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1114 isdnport = (class PmISDN *)port;
1117 if (isdnport->p_m_remote_id) {
1118 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1121 mISDNport = isdnport->p_m_mISDNport;
1122 i = isdnport->p_m_b_index;
1123 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1124 add_trace("type", NULL, "export request");
1126 isdnport->p_m_remote_ref = joinremote->j_remote_ref;
1127 isdnport->p_m_remote_id = joinremote->j_remote_id;
1128 if (mISDNport && i>=0) {
1129 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1133 case BCHANNEL_RELEASE:
1134 case BCHANNEL_ASSIGN_ACK:
1135 case BCHANNEL_REMOVE_ACK:
1136 /* find mISDNport for stack ID */
1137 mISDNport = mISDNport_first;
1140 ii = mISDNport->b_num;
1142 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1148 mISDNport = mISDNport->next;
1151 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1155 if (type!=BCHANNEL_RELEASE) {
1157 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1158 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1160 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1163 isdnport = mISDNport->b_port[i];
1164 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1165 add_trace("type", NULL, "import request");
1168 isdnport->p_m_remote_ref = 0;
1169 isdnport->p_m_remote_id = 0;
1171 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1175 PERROR("received wrong bchannel message type %d from remote\n", type);
1183 audio transmission procedure:
1184 -----------------------------
1187 three sources of audio transmission:
1188 - crypto-data high priority
1189 - tones high priority (also high)
1190 - remote-data low priority
1193 a variable that temporarily shows the number of samples elapsed since last transmission process.
1194 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1197 a variable that is increased whenever data is transmitted.
1198 it is decreased while time elapses. it stores the number of samples that
1199 are currently loaded to dsp module.
1200 since clock in dsp module is the same clock for user space process, these
1204 there are two levels:
1205 ISDN_LOAD will give the load that have to be kept in dsp.
1206 ISDN_MAXLOAD will give the maximum load before dropping.
1208 * procedure for low priority data
1209 see txfromup() for procedure
1210 in short: remote data is ignored during high priority tones
1212 * procedure for high priority data
1213 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1214 if no more data is available, load becomes empty again.
1217 0 ISDN_LOAD ISDN_MAXLOAD
1218 +--------------------+----------------------+
1220 +--------------------+----------------------+
1222 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1223 0 ISDN_LOAD ISDN_MAXLOAD
1224 +--------------------+----------------------+
1225 |TTTTTTTTTTTTTTTTTTTT| |
1226 +--------------------+----------------------+
1228 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1229 0 ISDN_LOAD ISDN_MAXLOAD
1230 +--------------------+----------------------+
1231 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1232 +--------------------+----------------------+
1235 void PmISDN::update_load(void)
1237 /* don't trigger load event if: */
1238 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1241 /* don't trigger load event if event already active */
1242 if (p_m_loadtimer.active)
1245 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1248 int load_timer(struct lcr_timer *timer, void *instance, int index)
1250 class PmISDN *isdnport = (class PmISDN *)instance;
1252 isdnport->load_tx();
1257 void PmISDN::load_tx(void)
1261 struct timeval current_time;
1264 gettimeofday(¤t_time, NULL);
1265 if (p_m_last_tv_sec) {
1266 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1267 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1269 /* set clock of last process! */
1270 p_m_last_tv_sec = current_time.tv_sec;
1271 p_m_last_tv_msec = current_time.tv_usec/1000;
1273 /* process only if we have samples and we are active */
1274 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1276 if (elapsed < p_m_load)
1277 p_m_load -= elapsed;
1281 /* to send data, tone must be on */
1282 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1283 && (p_m_load < ISDN_LOAD) /* not too much load? */
1284 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1285 int tosend = ISDN_LOAD - p_m_load, length;
1286 unsigned char buf[MISDN_HEADER_LEN+tosend];
1287 struct mISDNhead *frm = (struct mISDNhead *)buf;
1288 unsigned char *p = buf+MISDN_HEADER_LEN;
1290 /* copy inband signalling (e.g. used by ss5) */
1291 if (p_m_inband_send_on && tosend) {
1292 tosend -= inband_send(p, tosend);
1295 /* copy crypto loops */
1296 while (p_m_crypt_msg_loops && tosend) {
1297 /* how much do we have to send */
1298 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1301 if (length > tosend)
1304 /* copy message (part) to buffer */
1305 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1308 p_m_crypt_msg_current += length;
1309 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1311 p_m_crypt_msg_current = 0;
1312 p_m_crypt_msg_loops--;
1313 if (!p_m_crypt_msg_loops)
1315 // puts("eine loop weniger");
1323 if (p_tone_name[0] && tosend) {
1324 tosend -= read_audio(p, tosend);
1328 if (ISDN_LOAD - p_m_load - tosend > 0) {
1329 frm->prim = PH_DATA_REQ;
1331 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);
1333 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);
1334 p_m_load += ISDN_LOAD - p_m_load - tosend;
1339 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1340 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
1344 /* handle timeouts */
1345 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1347 class PmISDN *isdnport = (class PmISDN *)instance;
1348 struct lcr_msg *message;
1350 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);
1351 /* send timeout to endpoint */
1352 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1353 message->param.state = isdnport->p_state;
1354 message_put(message);
1361 * whenever we get audio data from bchannel, we process it here
1363 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1365 unsigned int cont = *((unsigned int *)data);
1366 struct lcr_msg *message;
1370 if (hh->prim == PH_CONTROL_IND) {
1372 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1375 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1376 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1377 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1379 add_trace("info", NULL, "DTMF is disabled");
1383 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1384 message->param.dtmf = cont & DTMF_TONE_MASK;
1385 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1386 message_put(message);
1391 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1392 add_trace("DSP-CRYPT", NULL, "error");
1394 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1395 message->param.crypt.type = CC_ERROR_IND;
1396 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1397 message_put(message);
1401 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1402 add_trace("DSP-CRYPT", NULL, "ok");
1404 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1405 message->param.crypt.type = CC_ACTBF_CONF;
1406 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1407 message_put(message);
1411 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1412 add_trace("unknown", NULL, "0x%x", cont);
1417 if (hh->prim == PH_CONTROL_IND) {
1420 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1421 add_trace("unknown", NULL, "0x%x", hh->id);
1426 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1428 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1429 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1432 /* see below (same condition) */
1433 if (p_state!=PORT_STATE_CONNECT
1434 && !p_m_mISDNport->tones)
1436 // printf(".");fflush(stdout);return;
1438 record(data, len, 1); // from up
1441 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1442 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1446 /* inband is processed */
1447 if (p_m_inband_receive_on)
1448 inband_receive(data, len);
1450 /* calls will not process any audio data unless
1451 * the call is connected OR tones feature is enabled.
1453 #ifndef DEBUG_COREBRIDGE
1454 if (p_state!=PORT_STATE_CONNECT
1455 && !p_m_mISDNport->tones)
1460 /* the bearer capability must be audio in order to send and receive
1461 * audio prior or after connect.
1463 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1467 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1469 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1475 record(data, len, 0); // from down
1477 /* randomize and listen to crypt message if enabled */
1478 if (p_m_crypt_listen) {
1479 /* the noisy randomizer */
1483 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1485 cryptman_listen_bch(data, len);
1488 /* send to remote, if bridged */
1489 bridge_tx(data, len);
1496 void PmISDN::set_echotest(int echo)
1498 if (p_m_echo != echo) {
1500 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1502 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1503 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);
1510 void PmISDN::set_tone(const char *dir, const char *tone)
1515 /* if no directory is given (by extension), we use interface.conf or options.conf */
1516 if (!dir || !dir[0]) {
1517 if (p_m_mISDNport->ifport->tones_dir[0])
1518 dir = p_m_mISDNport->ifport->tones_dir;
1519 else if (options.tones_dir[0])
1520 dir = options.tones_dir;
1525 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1531 /* check for dsp tones */
1532 if (!strcmp(dir, "american"))
1534 if (!strcmp(dir, "german"))
1536 if (!strcmp(dir, "oldgerman"))
1537 dsp = DSP_OLDGERMAN;
1539 /* check if we NOT really have to use a dsp-tone */
1540 if (dsp == DSP_NONE) {
1543 if (p_m_b_index > -1)
1544 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) {
1545 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1546 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1549 Port::set_tone(dir, tone);
1553 /* now we USE dsp-tone, convert name */
1554 if (!strcmp(tone, "dialtone")) {
1556 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1557 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1558 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1560 } else if (!strcmp(tone, "dialpbx")) {
1562 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1563 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1564 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1566 } else if (!strcmp(tone, "ringing")) {
1568 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1569 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1570 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1572 } else if (!strcmp(tone, "ringpbx")) {
1574 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1575 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1576 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1578 } else if (!strcmp(tone, "busy")) {
1581 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1582 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1583 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1585 } else if (!strcmp(tone, "release")) {
1588 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1589 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1590 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1592 } else if (!strcmp(tone, "cause_10"))
1594 else if (!strcmp(tone, "cause_11"))
1596 else if (!strcmp(tone, "cause_22")) {
1598 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1599 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1600 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1602 } else if (!strncmp(tone, "cause_", 6))
1603 id = TONE_SPECIAL_INFO;
1607 /* if we have a tone that is not supported by dsp */
1608 if (id==TONE_OFF && tone[0])
1612 if (p_m_tone != id) {
1615 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1616 if (p_m_b_index > -1)
1617 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)
1618 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);
1620 /* turn user-space tones off in cases of no tone OR dsp tone */
1621 Port::set_tone("",NULL);
1625 /* MESSAGE_mISDNSIGNAL */
1626 //extern struct lcr_msg *dddebug;
1627 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1629 int oldconf, newconf;
1630 switch(param->mISDNsignal.message) {
1631 case mISDNSIGNAL_VOLUME:
1632 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1633 p_m_tx_gain = param->mISDNsignal.tx_gain;
1634 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1635 if (p_m_b_index > -1)
1636 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)
1637 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);
1639 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1640 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1641 p_m_rx_gain = param->mISDNsignal.rx_gain;
1642 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1643 if (p_m_b_index > -1)
1644 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)
1645 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);
1647 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1650 case mISDNSIGNAL_CONF:
1651 oldconf = p_m_mute?0:p_m_conf;
1652 p_m_conf = param->mISDNsignal.conf;
1653 newconf = p_m_mute?0:p_m_conf;
1654 set_conf(oldconf, newconf);
1657 case mISDNSIGNAL_DELAY:
1658 if (p_m_delay != param->mISDNsignal.delay) {
1659 p_m_delay = param->mISDNsignal.delay;
1660 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1661 if (p_m_b_index > -1)
1662 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)
1663 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);
1665 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1669 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1674 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1676 struct lcr_msg *message;
1678 switch(param->crypt.type) {
1679 case CC_ACTBF_REQ: /* activate blowfish */
1681 p_m_crypt_key_len = param->crypt.len;
1682 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1683 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1684 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1685 message->param.crypt.type = CC_ERROR_IND;
1686 message_put(message);
1689 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1691 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1692 if (p_m_b_index > -1)
1693 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)
1694 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);
1697 case CC_DACT_REQ: /* deactivate session encryption */
1702 case CR_LISTEN_REQ: /* start listening to messages */
1703 p_m_crypt_listen = 1;
1705 p_m_crypt_listen_state = 0;
1708 case CR_UNLISTEN_REQ: /* stop listening to messages */
1709 p_m_crypt_listen = 0;
1713 case CR_MESSAGE_REQ: /* send message */
1714 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1715 if (!p_m_crypt_msg_len) {
1716 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1719 p_m_crypt_msg_current = 0; /* reset */
1720 p_m_crypt_msg_loops = 6; /* enable */
1724 /* disable txmix, or we get corrupt data due to audio process */
1725 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1726 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1727 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1733 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1739 * endpoint sends messages to the port
1741 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1743 if (Port::message_epoint(epoint_id, message_id, param)) {
1744 if (message_id == MESSAGE_BRIDGE)
1749 switch(message_id) {
1750 case MESSAGE_mISDNSIGNAL: /* user command */
1751 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1752 message_mISDNsignal(epoint_id, message_id, param);
1755 case MESSAGE_CRYPT: /* crypt control command */
1756 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1757 message_crypt(epoint_id, message_id, param);
1764 void PmISDN::update_rxoff(void)
1766 /* call bridges in user space OR crypto OR recording */
1767 if (p_bridge || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1768 /* rx IS required */
1772 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1773 if (p_m_b_index > -1)
1774 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1775 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1778 /* rx NOT required */
1782 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1783 if (p_m_b_index > -1)
1784 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1785 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1790 /* txdata IS required */
1794 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1795 if (p_m_b_index > -1)
1796 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1797 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1800 /* txdata NOT required */
1804 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1805 if (p_m_b_index > -1)
1806 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1807 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1812 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1814 struct mISDNport *mISDNport;
1820 /* unset global semaphore */
1822 // with a very small incident, upqueue_avail may be set by mISDN thread and
1823 // another byte may be sent to the pipe, which causes a call to this function
1824 // again with nothing in the upqueue. this is no problem.
1825 ret = read(fd->fd, &byte, 1);
1827 /* process all ports */
1828 mISDNport = mISDNport_first;
1830 /* handle queued up-messages (d-channel) */
1831 if (!mISDNport->isloopback) {
1832 while ((mb = mdequeue(&mISDNport->upqueue))) {
1835 case MPH_ACTIVATE_IND:
1836 if (mISDNport->l1link != 1) {
1837 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1839 mISDNport->l1link = 1;
1843 case MPH_DEACTIVATE_IND:
1844 if (mISDNport->l1link != 0) {
1845 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1847 mISDNport->l1link = 0;
1851 case MPH_INFORMATION_IND:
1852 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1854 case L1_SIGNAL_LOS_ON:
1857 case L1_SIGNAL_LOS_OFF:
1860 case L1_SIGNAL_AIS_ON:
1863 case L1_SIGNAL_AIS_OFF:
1866 case L1_SIGNAL_RDI_ON:
1869 case L1_SIGNAL_RDI_OFF:
1872 case L1_SIGNAL_SLIP_TX:
1873 mISDNport->slip_tx++;
1875 case L1_SIGNAL_SLIP_RX:
1876 mISDNport->slip_rx++;
1881 case MT_L2ESTABLISH:
1882 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1883 add_trace("tei", NULL, "%d", l3m->pid);
1885 mISDNport->l2link = 1;
1887 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1888 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1889 if (mISDNport->l2establish.active) {
1890 unsched_timer(&mISDNport->l2establish);
1891 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1898 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1899 if (!mISDNport->l2establish.active) {
1900 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1901 add_trace("tei", NULL, "%d", l3m->pid);
1903 /* down if not nt-ptmp */
1904 if (!mISDNport->ntmode || mISDNport->ptp)
1905 mISDNport->l2link = 0;
1907 if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1908 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1909 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1910 schedule_timer(&mISDNport->l2establish, 5, 0);
1911 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1917 /* l3-data is sent to LCR */
1918 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1924 mISDNport = mISDNport->next;
1929 /* l2 establish timer fires */
1930 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1932 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1934 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1935 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1936 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1937 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1943 /* handle frames from bchannel */
1944 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1946 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1947 unsigned char buffer[2048+MISDN_HEADER_LEN];
1948 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1951 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1953 PERROR("read error frame, errno %d\n", errno);
1956 if (ret < (int)MISDN_HEADER_LEN) {
1957 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1961 /* we don't care about confirms, we use rx data to sync tx */
1965 /* we receive audio data, we respond to it AND we send tones */
1970 case PH_CONTROL_IND:
1971 if (mISDNport->b_port[i])
1972 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1974 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1977 case PH_ACTIVATE_IND:
1978 case DL_ESTABLISH_IND:
1979 case PH_ACTIVATE_CNF:
1980 case DL_ESTABLISH_CNF:
1981 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1982 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1985 case PH_DEACTIVATE_IND:
1986 case DL_RELEASE_IND:
1987 case PH_DEACTIVATE_CNF:
1988 case DL_RELEASE_CNF:
1989 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
1990 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1994 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2000 /* process timer events for bchannel handling */
2001 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2003 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2005 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2011 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2015 * l3m must be queued, except for MT_ASSIGN
2018 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2021 #ifdef OLD_MT_ASSIGN
2022 /* special MT_ASSIGN handling:
2024 * if we request a PID from mlayer, we always do it while lcr is locked.
2025 * therefore we must check the MT_ASSIGN reply first before we lock.
2026 * this is because the MT_ASSIGN reply is received with the requesting
2027 * process, not by the mlayer thread!
2028 * this means, that the reply is sent during call of the request.
2029 * we must check if we get a reply and we know that we lcr is currently
2032 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2033 /* let's do some checking if someone changes stack behaviour */
2034 if (mt_assign_pid != 0)
2035 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2036 mt_assign_pid = pid;
2040 /* queue message, create, if required */
2042 l3m = alloc_l3_msg();
2044 FATAL("No memory for layer 3 message\n");
2046 mb = container_of(l3m, struct mbuffer, l3);
2049 mqueue_tail(&mISDNport->upqueue, mb);
2050 if (!upqueue_avail) {
2051 // multiple threads may cause multiple calls of this section, but this
2052 // results only in multiple processing of the upqueue read.
2053 // this is no problem.
2057 ret = write(upqueue_pipe[1], &byte, 1);
2062 int mISDN_getportbyname(int sock, int cnt, char *portname)
2064 struct mISDN_devinfo devinfo;
2068 while (port < cnt) {
2070 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2073 if (!strcasecmp(devinfo.name, portname))
2084 * global function to add a new card (port)
2086 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2089 struct mISDNport *mISDNport, **mISDNportp;
2090 int port = ifport->portnum;
2091 int ptp = ifport->ptp;
2092 int force_nt = ifport->nt;
2093 int l1hold = ifport->l1hold;
2094 int l2hold = ifport->l2hold;
2096 int ss5 = ifport->ss5;
2100 // struct mlayer3 *ml3;
2101 struct mISDN_devinfo devinfo;
2102 unsigned int protocol, prop;
2105 //printf("%s == %s\n", ifport->portname, options.loopback_int);
2106 if (!strcmp(ifport->portname, options.loopback_lcr))
2110 if (mISDNloop_open())
2114 /* check port counts */
2115 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2117 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2122 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2126 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2129 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
2131 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2134 // note: 'port' has still the port number
2136 if (port>cnt || port<0) {
2137 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2141 /* get port attributes */
2142 pri = bri = pots = nt = te = 0;
2144 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2146 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2149 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2153 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2157 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2161 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2166 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2172 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2177 if (force_nt && !nt) {
2178 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2182 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2185 if (pots && !bri && !pri) {
2186 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2190 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2194 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2197 /* set NT by turning off TE */
2200 /* if TE an NT is supported (and not forced to NT), turn off NT */
2204 /* check for double use of port */
2206 mISDNport = mISDNport_first;
2208 if (mISDNport->portnum == port)
2210 mISDNport = mISDNport->next;
2213 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2218 /* check for continous channelmap with no bchannel on slot 16 */
2219 if (test_channelmap(0, devinfo.channelmap)) {
2220 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2224 while(i < (int)devinfo.nrbchan + 1) {
2226 if (test_channelmap(i, devinfo.channelmap)) {
2227 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2231 if (!test_channelmap(i, devinfo.channelmap)) {
2232 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2239 /* add mISDNport structure */
2240 mISDNportp = &mISDNport_first;
2242 mISDNportp = &((*mISDNportp)->next);
2243 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2244 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2246 /* loop/ss5 link is always active */
2247 mISDNport->l1link = 1;
2248 mISDNport->l2link = 1;
2250 mISDNport->l1link = -1;
2251 mISDNport->l2link = -1;
2253 mISDNport->isloopback = loop;
2255 *mISDNportp = mISDNport;
2257 /* if pri, must set PTP */
2261 /* set ss5 params */
2263 /* try to keep interface enabled */
2283 /* allocate ressources of port */
2284 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2285 prop = (1 << MISDN_FLG_L2_CLEAN);
2286 if (ptp) // ptp forced
2287 prop |= (1 << MISDN_FLG_PTP);
2288 if (nt) // supports hold/retrieve on nt-mode
2289 prop |= (1 << MISDN_FLG_NET_HOLD);
2290 if (l1hold) // supports layer 1 hold
2291 prop |= (1 << MISDN_FLG_L1_HOLD);
2292 if (l2hold) // supports layer 2 hold
2293 prop |= (1 << MISDN_FLG_L2_HOLD);
2294 /* open layer 3 and init upqueue */
2296 unsigned long on = 1;
2297 struct sockaddr_mISDN addr;
2299 if (devinfo.nrbchan < 8) {
2300 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);
2301 // mISDNport_close(mISDNport);
2305 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
2306 PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
2307 mISDNport_close(mISDNport);
2310 /* set nonblocking io */
2311 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2312 PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
2313 mISDNport_close(mISDNport);
2316 /* bind socket to dchannel */
2317 memset(&addr, 0, sizeof(addr));
2318 addr.family = AF_ISDN;
2321 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2322 PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
2323 mISDNport_close(mISDNport);
2327 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2328 mqueue_init(&mISDNport->upqueue);
2329 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2330 if (!mISDNport->ml3) {
2331 mqueue_purge(&mISDNport->upqueue);
2332 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2340 "PORT (open failed)");
2342 mISDNport_close(mISDNport);
2347 SCPY(mISDNport->name, devinfo.name);
2348 mISDNport->b_num = devinfo.nrbchan;
2349 mISDNport->portnum = port;
2350 mISDNport->ntmode = nt;
2351 mISDNport->tespecial = ifport->tespecial;
2352 mISDNport->pri = pri;
2353 mISDNport->ptp = ptp;
2354 mISDNport->l1hold = l1hold;
2355 mISDNport->l2hold = l2hold;
2356 mISDNport->ss5 = ss5;
2357 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2359 while(i < mISDNport->b_num) {
2360 mISDNport->b_state[i] = B_STATE_IDLE;
2361 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2365 /* if ptp, pull up the link */
2366 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2367 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2368 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2369 add_trace("tei", NULL, "%d", 0);
2371 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2374 /* for nt-mode ptmp the link is always up */
2375 if (mISDNport->ntmode && !mISDNport->ptp)
2376 mISDNport->l2link = 1;
2378 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2380 start_trace(mISDNport->portnum,
2388 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2389 add_trace("channels", NULL, "%d", mISDNport->b_num);
2391 add_trace("ccitt#5", NULL, "enabled");
2399 * load static port instances, if required by mISDNport
2401 void mISDNport_static(struct mISDNport *mISDNport)
2406 while(i < mISDNport->b_num) {
2409 ss5_create_channel(mISDNport, i);
2417 * function to free ALL cards (ports)
2419 void mISDNport_close_all(void)
2421 /* free all ports */
2422 while(mISDNport_first)
2423 mISDNport_close(mISDNport_first);
2427 * free only one port
2429 void mISDNport_close(struct mISDNport *mISDNport)
2431 struct mISDNport **mISDNportp;
2433 class PmISDN *isdnport;
2436 /* remove all port instance that are linked to this mISDNport */
2440 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2441 isdnport = (class PmISDN *)port;
2442 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2443 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2451 /* only if we are already part of interface */
2452 if (mISDNport->ifport) {
2453 start_trace(mISDNport->portnum,
2454 mISDNport->ifport->interface,
2464 /* free bchannels */
2466 while(i < mISDNport->b_num) {
2467 if (mISDNport->b_sock[i].inuse) {
2468 _bchannel_destroy(mISDNport, i);
2469 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2471 if (mISDNport->b_timer[i].inuse) {
2472 del_timer(&mISDNport->b_timer[i]);
2476 del_timer(&mISDNport->l2establish);
2478 /* close layer 3, if open */
2479 if (!mISDNport->isloopback && mISDNport->ml3) {
2480 close_layer3(mISDNport->ml3);
2483 /* close gsm socket, if open */
2484 if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
2485 close(mISDNport->lcr_sock);
2489 if (!mISDNport->isloopback)
2490 mqueue_purge(&mISDNport->upqueue);
2492 /* remove from list */
2493 mISDNportp = &mISDNport_first;
2494 while(*mISDNportp) {
2495 if (*mISDNportp == mISDNport) {
2496 *mISDNportp = (*mISDNportp)->next;
2500 mISDNportp = &((*mISDNportp)->next);
2504 FATAL("mISDNport not in list\n");
2506 FREE(mISDNport, sizeof(struct mISDNport));
2513 * enque data from upper buffer
2515 int PmISDN::bridge_rx(unsigned char *data, int length)
2517 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2518 struct mISDNhead *hh = (struct mISDNhead *)buf;
2521 if (p_m_b_index < 0)
2523 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2526 /* check if high priority tones exist
2527 * ignore data in this case
2529 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2532 /* preload procedure
2533 * if transmit buffer in DSP module is empty,
2534 * preload it to DSP_LOAD to prevent jitter gaps.
2536 if (p_m_load == 0 && ISDN_LOAD > 0) {
2537 hh->prim = PH_DATA_REQ;
2539 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2540 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2542 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2543 p_m_load += ISDN_LOAD;
2544 schedule_timer(&p_m_loadtimer, 0, PORT_TRANSMIT * 125);
2547 /* drop if load would exceed ISDN_MAXLOAD
2548 * this keeps the delay not too high
2550 if (p_m_load+length > ISDN_MAXLOAD)
2553 /* make and send frame */
2554 hh->prim = PH_DATA_REQ;
2556 memcpy(buf+MISDN_HEADER_LEN, data, length);
2557 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2559 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2565 int PmISDN::inband_send(unsigned char *buffer, int len)
2567 PERROR("this function must be derived to function!\n");
2571 void PmISDN::inband_send_on(void)
2573 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2574 p_m_inband_send_on = 1;
2575 /* trigger inband transmit */
2579 void PmISDN::inband_send_off(void)
2581 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2582 p_m_inband_send_on = 0;
2585 void PmISDN::inband_receive(unsigned char *buffer, int len)
2588 // if (len >= SS5_DECODER_NPOINTS)
2589 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2590 PERROR("this function must be derived to function!\n");
2593 void PmISDN::inband_receive_on(void)
2595 /* this must work during constructor, see ss5.cpp */
2596 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2597 p_m_inband_receive_on = 1;
2601 void PmISDN::inband_receive_off(void)
2603 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2604 p_m_inband_receive_on = 0;
2608 void PmISDN::mute_on(void)
2612 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2614 set_conf(p_m_conf, 0);
2617 void PmISDN::mute_off(void)
2621 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2623 set_conf(0, p_m_conf);