1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
15 #include <mISDN/mISDNcompat.h>
16 int __af_isdn = MISDN_AF_ISDN;
17 #include <mISDN/q931.h>
20 #ifdef __compiler_offsetof
21 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
23 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
27 #define container_of(ptr, type, member) ({ \
28 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
29 (type *)( (char *)__mptr - offsetof(type,member) );})
32 // timeouts if activating/deactivating response from mISDN got lost
33 #define B_TIMER_ACTIVATING 1 // seconds
34 #define B_TIMER_DEACTIVATING 1 // seconds
36 /* list of mISDN ports */
37 struct mISDNport *mISDNport_first;
39 /* noise randomizer */
40 unsigned char mISDN_rand[256];
41 int mISDN_rand_count = 0;
43 unsigned int mt_assign_pid = ~0;
46 static int upqueue_pipe[2];
47 static struct lcr_fd upqueue_fd;
48 int upqueue_avail = 0;
50 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
51 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
53 int mISDN_initialize(void)
57 /* try to open raw socket to check kernel */
58 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
59 if (mISDNsocket < 0) {
60 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
65 init_layer3(4); // buffer of 4
67 /* open debug, if enabled and not only stack debugging */
69 SPRINT(filename, "%s/debug.log", LOG_DIR);
70 debug_fp = fopen(filename, "a");
73 if (options.deb & DEBUG_STACK) {
74 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
75 mISDN_debug_init(0xfffffeff, filename, filename, filename);
77 mISDN_debug_init(0, NULL, NULL, NULL);
79 if (pipe(upqueue_pipe) < 0)
80 FATAL("Failed to open pipe\n");
81 memset(&upqueue_fd, 0, sizeof(upqueue_fd));
82 upqueue_fd.fd = upqueue_pipe[0];
83 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
88 void mISDN_deinitialize(void)
101 if (upqueue_fd.inuse) {
102 unregister_fd(&upqueue_fd);
103 close(upqueue_pipe[0]);
104 close(upqueue_pipe[1]);
109 int load_timer(struct lcr_timer *timer, void *instance, int index);
114 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
116 p_m_mISDNport = mISDNport;
117 p_m_portnum = mISDNport->portnum;
124 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
125 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
134 p_m_inband_send_on = 0;
135 p_m_inband_receive_on = 0;
136 p_m_dtmf = !mISDNport->ifport->nodtmf;
137 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
138 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
139 p_m_remote_ref = 0; /* channel shall be exported to given remote */
140 p_m_remote_id = 0; /* remote admin socket */
141 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
144 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
145 add_timer(&p_m_loadtimer, load_timer, this, 0);
151 p_m_crypt_listen = 0;
152 p_m_crypt_msg_loops = 0;
153 p_m_crypt_msg_loops = 0;
154 p_m_crypt_msg_len = 0;
155 p_m_crypt_msg[0] = '\0';
156 p_m_crypt_msg_current = 0;
157 p_m_crypt_key_len = 0;
158 p_m_crypt_listen = 0;
159 p_m_crypt_listen_state = 0;
160 p_m_crypt_listen_len = 0;
161 p_m_crypt_listen_msg[0] = '\0';
162 p_m_crypt_listen_crc = 0;
163 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
164 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
165 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
169 /* if any channel requested by constructor */
170 if (channel == CHANNEL_ANY) {
171 /* reserve channel */
173 mISDNport->b_reserved++;
176 /* reserve channel */
177 if (channel > 0) // only if constructor was called with a channel resevation
178 seize_bchannel(channel, exclusive);
180 /* we increase the number of objects: */
182 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
183 //inband_receive_on();
192 struct lcr_msg *message;
194 del_timer(&p_m_timeout);
195 del_timer(&p_m_loadtimer);
197 /* remove bchannel relation */
201 while (p_epointlist) {
202 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
203 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
204 message->param.disconnectinfo.cause = 16;
205 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
206 message_put(message);
207 /* remove from list */
208 free_epointlist(p_epointlist);
211 /* we decrease the number of objects: */
212 p_m_mISDNport->use--;
213 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
220 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
222 /* init trace with given values */
223 start_trace(mISDNport?mISDNport->portnum:-1,
224 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
225 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
226 port?port->p_dialinginfo.id:NULL,
229 port?port->p_serial:0,
237 static struct isdn_message {
241 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
242 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
243 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
244 {"DL_RELEASE", L2_RELEASE_REQ},
245 {"UNKNOWN", L3_UNKNOWN_REQ},
246 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
247 {"MT_SETUP", L3_SETUP_REQ},
248 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
249 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
250 {"MT_ALERTING", L3_ALERTING_REQ},
251 {"MT_CONNECT", L3_CONNECT_REQ},
252 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
253 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
254 {"MT_RELEASE", L3_RELEASE_REQ},
255 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
256 {"MT_INFORMATION", L3_INFORMATION_REQ},
257 {"MT_PROGRESS", L3_PROGRESS_REQ},
258 {"MT_NOTIFY", L3_NOTIFY_REQ},
259 {"MT_SUSPEND", L3_SUSPEND_REQ},
260 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
261 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
262 {"MT_RESUME", L3_RESUME_REQ},
263 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
264 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
265 {"MT_HOLD", L3_HOLD_REQ},
266 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
267 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
268 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
269 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
270 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
271 {"MT_FACILITY", L3_FACILITY_REQ},
272 {"MT_STATUS", L3_STATUS_REQ},
273 {"MT_RESTART", L3_RESTART_REQ},
274 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
275 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
278 static const char *isdn_prim[4] = {
284 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
289 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
290 /* select message and primitive text */
292 while(isdn_message[i].name) {
293 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
294 if (isdn_message[i].value == (msg&0xffffff00)) {
295 SCPY(msgtext, isdn_message[i].name);
300 SCAT(msgtext, isdn_prim[msg&0x00000003]);
303 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
305 if (mISDNport->ntmode) {
306 if (direction == DIRECTION_OUT)
307 SCAT(msgtext, " N->U");
309 SCAT(msgtext, " N<-U");
311 if (direction == DIRECTION_OUT)
312 SCAT(msgtext, " U->N");
314 SCAT(msgtext, " U<-N");
319 /* init trace with given values */
320 start_trace(mISDNport?mISDNport->portnum:-1,
321 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
322 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
323 port?port->p_dialinginfo.id:NULL,
326 port?port->p_serial:0,
332 * send control information to the channel (dsp-module)
334 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
336 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
337 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
338 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
344 ctrl->prim = PH_CONTROL_REQ;
348 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
350 PERROR("Failed to send to socket %d\n", sock);
351 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
352 if (c1 == DSP_CONF_JOIN)
353 add_trace(trace_name, NULL, "0x%08x", trace_value);
355 add_trace(trace_name, NULL, "%d", trace_value);
359 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)
361 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
362 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
363 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
369 ctrl->prim = PH_CONTROL_REQ;
372 memcpy(d, c2, c2_len);
373 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
375 PERROR("Failed to send to socket %d\n", sock);
376 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
377 add_trace(trace_name, NULL, "%d", trace_value);
381 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
384 * subfunction for bchannel_event
387 static int _bchannel_create(struct mISDNport *mISDNport, int i)
390 struct sockaddr_mISDN addr;
392 if (mISDNport->b_sock[i].inuse) {
393 PERROR("Error: Socket already created for index %d\n", i);
398 //#warning testing without DSP
399 // 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);
400 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);
401 if (mISDNport->b_sock[i].fd < 0) {
402 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
406 /* register callback for read */
407 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
409 /* bind socket to bchannel */
410 addr.family = AF_ISDN;
411 addr.dev = mISDNport->portnum;
412 addr.channel = i+1+(i>=15);
413 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
415 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);
416 close(mISDNport->b_sock[i].fd);
417 unregister_fd(&mISDNport->b_sock[i]);
421 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
422 add_trace("channel", NULL, "%d", i+1+(i>=15));
423 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
431 * subfunction for bchannel_event
432 * activate / deactivate request
434 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
436 struct mISDNhead act;
439 if (!mISDNport->b_sock[i].inuse)
441 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
443 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
445 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
448 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
449 add_trace("channel", NULL, "%d", i+1+(i>=15));
451 add_trace("event", NULL, "timeout recovery");
457 * subfunction for bchannel_event
460 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
465 if (!mISDNport->b_sock[i].inuse)
467 handle = mISDNport->b_sock[i].fd;
468 port = mISDNport->b_port[i];
469 mode = mISDNport->b_mode[i];
471 PERROR("bchannel index i=%d not associated with a port object\n", i);
475 /* set dsp features */
476 if (port->p_m_txdata)
477 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
478 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
479 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
480 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
481 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
482 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
483 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
484 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
485 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
486 if (port->p_m_conf && !port->p_m_mute)
487 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
489 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
490 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
491 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
493 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
494 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
495 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
496 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
497 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
498 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
499 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);
503 void PmISDN::set_conf(int oldconf, int newconf)
505 if (oldconf != newconf) {
506 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
507 if (p_m_b_index > -1)
508 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
509 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);
511 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
516 * subfunction for bchannel_event
519 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
521 if (!mISDNport->b_sock[i].inuse)
523 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
524 add_trace("channel", NULL, "%d", i+1+(i>=15));
525 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
527 close(mISDNport->b_sock[i].fd);
528 unregister_fd(&mISDNport->b_sock[i]);
536 A bchannel goes through the following states in this order:
539 No one is using the bchannel.
540 It is available and not linked to Port class, nor reserved.
543 The bchannel stack is created and an activation request is sent.
544 It MAY be linked to Port class, but already unlinked due to Port class removal.
547 The bchannel is active and cofigured to the Port class needs.
548 Also it is linked to a Port class, otherwhise it would be deactivated.
550 - B_STATE_DEACTIVATING
551 The bchannel is in deactivating state, due to deactivation request.
552 It may be linked to a Port class, that likes to reactivate it.
556 After deactivating bchannel, and if not used, the bchannel becomes idle again.
558 Also the bchannel may be exported, but only if the state is or becomes idle:
561 The bchannel assignment has been sent to the remove application.
564 The bchannel assignment is acknowledged by the remote application.
567 The bchannel is re-imported by mISDN port object.
571 After re-importing bchannel, and if not used, the bchannel becomes idle again.
574 A bchannel can have the following events:
577 A bchannel is required by a Port class.
580 The bchannel beomes active.
583 The bchannel is not required by Port class anymore
585 - B_EVENT_DEACTIVATED
586 The bchannel becomes inactive.
589 The bchannel is now used by remote application.
592 The bchannel is not used by remote application.
594 - B_EVENT_EXPORTREQUEST
595 The bchannel shall be exported to the remote application.
597 - B_EVENT_IMPORTREQUEST
598 The bchannel is released from the remote application.
600 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
602 if an export request is receive by remote application, p_m_remote_* is set.
603 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.)
604 - set on export request from remote application (if port is assigned)
605 - set on channel use, if requested by remote application (p_m_remote_*)
606 - cleared on drop request
608 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
609 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
610 the bchannel import/export is acknowledged with stack given.
612 if exporting, b_remote_*[index] is set to the remote socket id.
613 if importing has been acknowledged. b_remote_*[index] is cleared.
618 * process bchannel events
619 * - mISDNport is a pointer to the port's structure
620 * - i is the index of the bchannel
621 * - event is the B_EVENT_* value
622 * - port is the PmISDN class pointer
624 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
626 class PmISDN *b_port = mISDNport->b_port[i];
627 int state = mISDNport->b_state[i];
628 int timer = -1; // no change
629 unsigned int p_m_remote_ref = 0;
630 unsigned int p_m_remote_id = 0;
633 char *p_m_pipeline = NULL;
634 unsigned char *p_m_crypt_key = NULL;
635 int p_m_crypt_key_len = 0;
636 int p_m_crypt_key_type = 0;
637 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
640 p_m_remote_id = b_port->p_m_remote_id;
641 p_m_remote_ref = b_port->p_m_remote_ref;
642 p_m_tx_gain = b_port->p_m_tx_gain;
643 p_m_rx_gain = b_port->p_m_rx_gain;
644 p_m_pipeline = b_port->p_m_pipeline;
645 p_m_crypt_key = b_port->p_m_crypt_key;
646 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
647 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
652 /* port must be linked in order to allow activation */
654 FATAL("bchannel must be linked to a Port class\n");
657 if (p_m_remote_ref) {
658 /* export bchannel */
659 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);
660 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
661 add_trace("type", NULL, "assign");
662 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
664 state = B_STATE_EXPORTING;
665 mISDNport->b_remote_id[i] = p_m_remote_id;
666 mISDNport->b_remote_ref[i] = p_m_remote_ref;
668 /* create stack and send activation request */
669 if (_bchannel_create(mISDNport, i)) {
670 _bchannel_activate(mISDNport, i, 1, 0);
671 state = B_STATE_ACTIVATING;
672 timer = B_TIMER_ACTIVATING;
677 case B_STATE_ACTIVATING:
678 case B_STATE_EXPORTING:
679 /* do nothing, because it is already activating */
682 case B_STATE_DEACTIVATING:
683 case B_STATE_IMPORTING:
684 /* do nothing, because we must wait until we can reactivate */
688 /* problems that might ocurr:
689 * B_EVENT_USE is received when channel already in use.
690 * bchannel exported, but not freed by other port
692 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
696 case B_EVENT_EXPORTREQUEST:
697 /* special case where the bchannel is requested by remote */
698 if (!p_m_remote_ref) {
699 PERROR("export request without remote channel set, please correct.\n");
704 /* in case, the bchannel is exported right after seize_bchannel */
705 /* export bchannel */
706 /* p_m_remote_id is set, when this event happens. */
707 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);
708 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
709 add_trace("type", NULL, "assign");
710 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
712 state = B_STATE_EXPORTING;
713 mISDNport->b_remote_id[i] = p_m_remote_id;
714 mISDNport->b_remote_ref[i] = p_m_remote_ref;
717 case B_STATE_ACTIVATING:
718 case B_STATE_EXPORTING:
719 /* do nothing, because it is already activating */
722 case B_STATE_DEACTIVATING:
723 case B_STATE_IMPORTING:
724 /* do nothing, because we must wait until we can reactivate */
728 /* bchannel is active, so we deactivate */
729 _bchannel_activate(mISDNport, i, 0, 0);
730 state = B_STATE_DEACTIVATING;
731 timer = B_TIMER_DEACTIVATING;
735 /* problems that might ocurr:
736 * ... when channel already in use.
737 * bchannel exported, but not freed by other port
739 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
743 case B_EVENT_IMPORTREQUEST:
744 /* special case where the bchannel is released by remote */
745 if (p_m_remote_ref) {
746 PERROR("import request with remote channel set, please correct.\n");
752 /* bchannel is not exported */
755 case B_STATE_ACTIVATING:
756 case B_STATE_EXPORTING:
757 /* do nothing because we must wait until bchanenl is active before deactivating */
761 /* bchannel is exported, so we re-import */
762 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
763 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
764 add_trace("type", NULL, "remove");
765 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
767 state = B_STATE_IMPORTING;
770 case B_STATE_DEACTIVATING:
771 case B_STATE_IMPORTING:
772 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
776 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
780 case B_EVENT_ACTIVATED:
783 case B_STATE_ACTIVATING:
784 if (b_port && !p_m_remote_id) {
785 /* bchannel is active and used by Port class, so we configure bchannel */
786 _bchannel_configure(mISDNport, i);
787 state = B_STATE_ACTIVE;
788 b_port->p_m_load = 0;
790 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
791 _bchannel_activate(mISDNport, i, 0, 0);
792 state = B_STATE_DEACTIVATING;
793 timer = B_TIMER_DEACTIVATING;
798 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
802 case B_EVENT_EXPORTED:
804 case B_STATE_EXPORTING:
805 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
806 /* remote export done */
807 state = B_STATE_REMOTE;
809 /* bchannel is now exported, but we need bchannel back
810 * OR bchannel is not used anymore
811 * OR bchannel has been exported to an obsolete ref,
812 * so reimport, to later export to new remote */
813 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
814 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
815 add_trace("type", NULL, "remove");
816 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
818 state = B_STATE_IMPORTING;
823 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
829 FATAL("bchannel must be linked to a Port class\n");
832 /* bchannel is idle due to an error, so we do nothing */
835 case B_STATE_ACTIVATING:
836 case B_STATE_EXPORTING:
837 /* do nothing because we must wait until bchanenl is active before deactivating */
841 /* bchannel is active, so we deactivate */
842 _bchannel_activate(mISDNport, i, 0, 0);
843 state = B_STATE_DEACTIVATING;
844 timer = B_TIMER_DEACTIVATING;
848 /* bchannel is exported, so we re-import */
849 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
850 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
851 add_trace("type", NULL, "remove");
852 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
854 state = B_STATE_IMPORTING;
857 case B_STATE_DEACTIVATING:
858 case B_STATE_IMPORTING:
859 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
863 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
867 case B_EVENT_DEACTIVATED:
871 /* ignore due to deactivation confirm after unloading */
874 case B_STATE_DEACTIVATING:
875 _bchannel_destroy(mISDNport, i);
876 state = B_STATE_IDLE;
878 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
879 if (p_m_remote_ref) {
880 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);
881 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
882 add_trace("type", NULL, "assign");
883 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
885 state = B_STATE_EXPORTING;
886 mISDNport->b_remote_id[i] = p_m_remote_id;
887 mISDNport->b_remote_ref[i] = p_m_remote_ref;
889 if (_bchannel_create(mISDNport, i)) {
890 _bchannel_activate(mISDNport, i, 1, 0);
891 state = B_STATE_ACTIVATING;
892 timer = B_TIMER_ACTIVATING;
899 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
903 case B_EVENT_IMPORTED:
905 case B_STATE_IMPORTING:
906 state = B_STATE_IDLE;
907 mISDNport->b_remote_id[i] = 0;
908 mISDNport->b_remote_ref[i] = 0;
910 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
911 if (p_m_remote_ref) {
912 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);
913 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
914 add_trace("type", NULL, "assign");
915 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
917 state = B_STATE_EXPORTING;
918 mISDNport->b_remote_id[i] = p_m_remote_id;
919 mISDNport->b_remote_ref[i] = p_m_remote_ref;
921 if (_bchannel_create(mISDNport, i)) {
922 _bchannel_activate(mISDNport, i, 1, 0);
923 state = B_STATE_ACTIVATING;
924 timer = B_TIMER_ACTIVATING;
931 /* ignore, because not assigned */
936 case B_EVENT_TIMEOUT:
940 /* ignore due to deactivation confirm after unloading */
943 case B_STATE_ACTIVATING:
944 _bchannel_activate(mISDNport, i, 1, 1);
945 timer = B_TIMER_ACTIVATING;
948 case B_STATE_DEACTIVATING:
949 _bchannel_activate(mISDNport, i, 0, 1);
950 timer = B_TIMER_DEACTIVATING;
954 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
959 PERROR("Illegal event %d, please correct.\n", event);
962 mISDNport->b_state[i] = state;
964 unsched_timer(&mISDNport->b_timer[i]);
966 schedule_timer(&mISDNport->b_timer[i], timer, 0);
973 * check for available channel and reserve+set it.
974 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
976 * returns -(cause value) or x = channel x or 0 = no channel
977 * NOTE: no activation is done here
979 int PmISDN::seize_bchannel(int channel, int exclusive)
983 /* the channel is what we have */
984 if (p_m_b_channel == channel)
987 /* if channel already in use, release it */
992 if (channel==CHANNEL_NO || channel==0)
995 /* is channel in range ? */
997 || (channel>p_m_mISDNport->b_num && channel<16)
998 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
999 return(-6); /* channel unacceptable */
1001 /* request exclusive channel */
1002 if (exclusive && channel>0) {
1003 i = channel-1-(channel>16);
1004 if (p_m_mISDNport->b_port[i])
1005 return(-44); /* requested channel not available */
1009 /* ask for channel */
1011 i = channel-1-(channel>16);
1012 if (p_m_mISDNport->b_port[i] == NULL)
1016 /* search for channel */
1018 while(i < p_m_mISDNport->b_num) {
1019 if (!p_m_mISDNport->b_port[i]) {
1020 channel = i+1+(i>=15);
1025 return(-34); /* no free channel */
1028 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1030 /* link Port, set parameters */
1031 p_m_mISDNport->b_port[i] = this;
1033 p_m_b_channel = channel;
1034 p_m_b_exclusive = exclusive;
1035 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1037 /* reserve channel */
1038 if (!p_m_b_reserve) {
1040 p_m_mISDNport->b_reserved++;
1047 * drop reserved channel and unset it.
1048 * deactivation is also done
1050 void PmISDN::drop_bchannel(void)
1052 /* unreserve channel */
1054 p_m_mISDNport->b_reserved--;
1058 if (p_m_b_index < 0)
1063 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1065 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1066 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1067 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1068 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1071 p_m_b_exclusive = 0;
1074 /* process bchannel export/import message from join */
1075 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1077 class Endpoint *epoint;
1079 class PmISDN *isdnport;
1080 struct mISDNport *mISDNport;
1084 case BCHANNEL_REQUEST:
1085 /* find the port object for the join object ref */
1086 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1087 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1090 if (!epoint->ep_portlist) {
1091 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1094 if (epoint->ep_portlist->next) {
1095 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);
1097 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1098 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1101 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1102 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1104 isdnport = (class PmISDN *)port;
1107 if (isdnport->p_m_remote_id) {
1108 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1111 mISDNport = isdnport->p_m_mISDNport;
1112 i = isdnport->p_m_b_index;
1113 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1114 add_trace("type", NULL, "export request");
1116 isdnport->p_m_remote_ref = joinremote->j_remote_ref;
1117 isdnport->p_m_remote_id = joinremote->j_remote_id;
1118 if (mISDNport && i>=0) {
1119 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1123 case BCHANNEL_RELEASE:
1124 case BCHANNEL_ASSIGN_ACK:
1125 case BCHANNEL_REMOVE_ACK:
1126 /* find mISDNport for stack ID */
1127 mISDNport = mISDNport_first;
1130 ii = mISDNport->b_num;
1132 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1138 mISDNport = mISDNport->next;
1141 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1145 if (type!=BCHANNEL_RELEASE) {
1147 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1148 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1150 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1153 isdnport = mISDNport->b_port[i];
1154 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1155 add_trace("type", NULL, "import request");
1158 isdnport->p_m_remote_ref = 0;
1159 isdnport->p_m_remote_id = 0;
1161 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1165 PERROR("received wrong bchannel message type %d from remote\n", type);
1173 audio transmission procedure:
1174 -----------------------------
1177 three sources of audio transmission:
1178 - crypto-data high priority
1179 - tones high priority (also high)
1180 - remote-data low priority
1183 a variable that temporarily shows the number of samples elapsed since last transmission process.
1184 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1187 a variable that is increased whenever data is transmitted.
1188 it is decreased while time elapses. it stores the number of samples that
1189 are currently loaded to dsp module.
1190 since clock in dsp module is the same clock for user space process, these
1194 there are two levels:
1195 ISDN_LOAD will give the load that have to be kept in dsp.
1196 ISDN_MAXLOAD will give the maximum load before dropping.
1198 * procedure for low priority data
1199 see txfromup() for procedure
1200 in short: remote data is ignored during high priority tones
1202 * procedure for high priority data
1203 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1204 if no more data is available, load becomes empty again.
1207 0 ISDN_LOAD ISDN_MAXLOAD
1208 +--------------------+----------------------+
1210 +--------------------+----------------------+
1212 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1213 0 ISDN_LOAD ISDN_MAXLOAD
1214 +--------------------+----------------------+
1215 |TTTTTTTTTTTTTTTTTTTT| |
1216 +--------------------+----------------------+
1218 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1219 0 ISDN_LOAD ISDN_MAXLOAD
1220 +--------------------+----------------------+
1221 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1222 +--------------------+----------------------+
1225 void PmISDN::update_load(void)
1227 /* don't trigger load event if: */
1228 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1231 /* don't trigger load event if event already active */
1232 if (p_m_loadtimer.active)
1235 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1238 int load_timer(struct lcr_timer *timer, void *instance, int index)
1240 class PmISDN *isdnport = (class PmISDN *)instance;
1242 isdnport->load_tx();
1247 void PmISDN::load_tx(void)
1251 struct timeval current_time;
1254 gettimeofday(¤t_time, NULL);
1255 if (p_m_last_tv_sec) {
1256 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1257 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1259 /* set clock of last process! */
1260 p_m_last_tv_sec = current_time.tv_sec;
1261 p_m_last_tv_msec = current_time.tv_usec/1000;
1263 /* process only if we have samples and we are active */
1264 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1266 if (elapsed < p_m_load)
1267 p_m_load -= elapsed;
1271 /* to send data, tone must be on */
1272 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1273 && (p_m_load < ISDN_LOAD) /* not too much load? */
1274 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1275 int tosend = ISDN_LOAD - p_m_load, length;
1276 unsigned char buf[MISDN_HEADER_LEN+tosend];
1277 struct mISDNhead *frm = (struct mISDNhead *)buf;
1278 unsigned char *p = buf+MISDN_HEADER_LEN;
1280 /* copy inband signalling (e.g. used by ss5) */
1281 if (p_m_inband_send_on && tosend) {
1282 tosend -= inband_send(p, tosend);
1285 /* copy crypto loops */
1286 while (p_m_crypt_msg_loops && tosend) {
1287 /* how much do we have to send */
1288 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1291 if (length > tosend)
1294 /* copy message (part) to buffer */
1295 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1298 p_m_crypt_msg_current += length;
1299 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1301 p_m_crypt_msg_current = 0;
1302 p_m_crypt_msg_loops--;
1303 if (!p_m_crypt_msg_loops)
1305 // puts("eine loop weniger");
1313 if (p_tone_name[0] && tosend) {
1314 tosend -= read_audio(p, tosend);
1318 if (ISDN_LOAD - p_m_load - tosend > 0) {
1319 frm->prim = PH_DATA_REQ;
1321 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);
1323 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);
1324 p_m_load += ISDN_LOAD - p_m_load - tosend;
1329 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1330 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
1334 /* handle timeouts */
1335 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1337 class PmISDN *isdnport = (class PmISDN *)instance;
1338 struct lcr_msg *message;
1340 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);
1341 /* send timeout to endpoint */
1342 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1343 message->param.state = isdnport->p_state;
1344 message_put(message);
1351 * whenever we get audio data from bchannel, we process it here
1353 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1355 unsigned int cont = *((unsigned int *)data);
1356 unsigned char *data_temp;
1357 unsigned int length_temp;
1358 struct lcr_msg *message;
1362 if (hh->prim == PH_CONTROL_IND) {
1364 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1367 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1368 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1369 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1371 add_trace("info", NULL, "DTMF is disabled");
1375 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1376 message->param.dtmf = cont & DTMF_TONE_MASK;
1377 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1378 message_put(message);
1383 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1384 add_trace("DSP-CRYPT", NULL, "error");
1386 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1387 message->param.crypt.type = CC_ERROR_IND;
1388 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1389 message_put(message);
1393 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1394 add_trace("DSP-CRYPT", NULL, "ok");
1396 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1397 message->param.crypt.type = CC_ACTBF_CONF;
1398 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1399 message_put(message);
1403 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1404 add_trace("unknown", NULL, "0x%x", cont);
1409 if (hh->prim == PH_CONTROL_IND) {
1412 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1413 add_trace("unknown", NULL, "0x%x", hh->id);
1418 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1420 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1421 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1424 /* see below (same condition) */
1425 if (p_state!=PORT_STATE_CONNECT
1426 && !p_m_mISDNport->tones)
1428 // printf(".");fflush(stdout);return;
1430 record(data, len, 1); // from up
1433 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1434 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1438 /* inband is processed */
1439 if (p_m_inband_receive_on)
1440 inband_receive(data, len);
1442 /* calls will not process any audio data unless
1443 * the call is connected OR tones feature is enabled.
1445 #ifndef DEBUG_COREBRIDGE
1446 if (p_state!=PORT_STATE_CONNECT
1447 && !p_m_mISDNport->tones)
1452 /* the bearer capability must be audio in order to send and receive
1453 * audio prior or after connect.
1455 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1459 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1461 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1467 record(data, len, 0); // from down
1469 /* randomize and listen to crypt message if enabled */
1470 if (p_m_crypt_listen) {
1471 /* the noisy randomizer */
1475 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1477 cryptman_listen_bch(data, len);
1482 /* send data to epoint */
1483 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1486 while(length_temp) {
1487 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1488 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1489 memcpy(message->param.data.data, data_temp, message->param.data.len);
1490 message_put(message);
1491 if (length_temp <= sizeof(message->param.data.data))
1493 data_temp += sizeof(message->param.data.data);
1494 length_temp -= sizeof(message->param.data.data);
1503 void PmISDN::set_echotest(int echo)
1505 if (p_m_echo != echo) {
1507 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1509 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1510 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);
1517 void PmISDN::set_tone(const char *dir, const char *tone)
1522 /* if no directory is given (by extension), we use interface.conf or options.conf */
1523 if (!dir || !dir[0]) {
1524 if (p_m_mISDNport->ifport->tones_dir[0])
1525 dir = p_m_mISDNport->ifport->tones_dir;
1526 else if (options.tones_dir[0])
1527 dir = options.tones_dir;
1532 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1538 /* check for dsp tones */
1539 if (!strcmp(dir, "american"))
1541 if (!strcmp(dir, "german"))
1543 if (!strcmp(dir, "oldgerman"))
1544 dsp = DSP_OLDGERMAN;
1546 /* check if we NOT really have to use a dsp-tone */
1547 if (dsp == DSP_NONE) {
1550 if (p_m_b_index > -1)
1551 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) {
1552 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1553 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1556 Port::set_tone(dir, tone);
1560 /* now we USE dsp-tone, convert name */
1561 if (!strcmp(tone, "dialtone")) {
1563 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1564 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1565 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1567 } else if (!strcmp(tone, "dialpbx")) {
1569 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1570 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1571 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1573 } else if (!strcmp(tone, "ringing")) {
1575 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1576 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1577 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1579 } else if (!strcmp(tone, "ringpbx")) {
1581 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1582 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1583 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1585 } else if (!strcmp(tone, "busy")) {
1588 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1589 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1590 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1592 } else if (!strcmp(tone, "release")) {
1595 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1596 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1597 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1599 } else if (!strcmp(tone, "cause_10"))
1601 else if (!strcmp(tone, "cause_11"))
1603 else if (!strcmp(tone, "cause_22")) {
1605 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1606 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1607 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1609 } else if (!strncmp(tone, "cause_", 6))
1610 id = TONE_SPECIAL_INFO;
1614 /* if we have a tone that is not supported by dsp */
1615 if (id==TONE_OFF && tone[0])
1619 if (p_m_tone != id) {
1622 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1623 if (p_m_b_index > -1)
1624 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)
1625 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);
1627 /* turn user-space tones off in cases of no tone OR dsp tone */
1628 Port::set_tone("",NULL);
1632 /* MESSAGE_mISDNSIGNAL */
1633 //extern struct lcr_msg *dddebug;
1634 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1636 int oldconf, newconf;
1637 switch(param->mISDNsignal.message) {
1638 case mISDNSIGNAL_VOLUME:
1639 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1640 p_m_tx_gain = param->mISDNsignal.tx_gain;
1641 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1642 if (p_m_b_index > -1)
1643 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)
1644 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);
1646 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1647 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1648 p_m_rx_gain = param->mISDNsignal.rx_gain;
1649 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1650 if (p_m_b_index > -1)
1651 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)
1652 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);
1654 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1657 case mISDNSIGNAL_CONF:
1658 oldconf = p_m_mute?0:p_m_conf;
1659 p_m_conf = param->mISDNsignal.conf;
1660 newconf = p_m_mute?0:p_m_conf;
1661 set_conf(oldconf, newconf);
1664 case mISDNSIGNAL_JOINDATA:
1665 if (p_m_joindata != param->mISDNsignal.joindata) {
1666 p_m_joindata = param->mISDNsignal.joindata;
1667 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1670 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1673 case mISDNSIGNAL_DELAY:
1674 if (p_m_delay != param->mISDNsignal.delay) {
1675 p_m_delay = param->mISDNsignal.delay;
1676 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1677 if (p_m_b_index > -1)
1678 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)
1679 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);
1681 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1685 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1690 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1692 struct lcr_msg *message;
1694 switch(param->crypt.type) {
1695 case CC_ACTBF_REQ: /* activate blowfish */
1697 p_m_crypt_key_len = param->crypt.len;
1698 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1699 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1700 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1701 message->param.crypt.type = CC_ERROR_IND;
1702 message_put(message);
1705 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1707 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1708 if (p_m_b_index > -1)
1709 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)
1710 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);
1713 case CC_DACT_REQ: /* deactivate session encryption */
1718 case CR_LISTEN_REQ: /* start listening to messages */
1719 p_m_crypt_listen = 1;
1721 p_m_crypt_listen_state = 0;
1724 case CR_UNLISTEN_REQ: /* stop listening to messages */
1725 p_m_crypt_listen = 0;
1729 case CR_MESSAGE_REQ: /* send message */
1730 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1731 if (!p_m_crypt_msg_len) {
1732 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1735 p_m_crypt_msg_current = 0; /* reset */
1736 p_m_crypt_msg_loops = 6; /* enable */
1740 /* disable txmix, or we get corrupt data due to audio process */
1741 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1742 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1743 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1749 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1755 * endpoint sends messages to the port
1757 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1759 if (Port::message_epoint(epoint_id, message_id, param))
1762 switch(message_id) {
1763 case MESSAGE_DATA: /* tx-data from upper layer */
1764 txfromup(param->data.data, param->data.len);
1767 case MESSAGE_mISDNSIGNAL: /* user command */
1768 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1769 message_mISDNsignal(epoint_id, message_id, param);
1772 case MESSAGE_CRYPT: /* crypt control command */
1773 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1774 message_crypt(epoint_id, message_id, param);
1781 void PmISDN::update_rxoff(void)
1783 /* call bridges in user space OR crypto OR recording */
1784 if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1785 /* rx IS required */
1789 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1790 if (p_m_b_index > -1)
1791 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1792 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1795 /* rx NOT required */
1799 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\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_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1807 /* txdata IS required */
1811 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1812 if (p_m_b_index > -1)
1813 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1814 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1817 /* txdata NOT required */
1821 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1822 if (p_m_b_index > -1)
1823 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1824 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1829 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1831 struct mISDNport *mISDNport;
1837 /* unset global semaphore */
1839 // with a very small incident, upqueue_avail may be set by mISDN thread and
1840 // another byte may be sent to the pipe, which causes a call to this function
1841 // again with nothing in the upqueue. this is no problem.
1842 ret = read(fd->fd, &byte, 1);
1844 /* process all ports */
1845 mISDNport = mISDNport_first;
1847 /* handle queued up-messages (d-channel) */
1848 if (!mISDNport->isloopback) {
1849 while ((mb = mdequeue(&mISDNport->upqueue))) {
1852 case MPH_ACTIVATE_IND:
1853 if (mISDNport->l1link != 1) {
1854 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1856 mISDNport->l1link = 1;
1860 case MPH_DEACTIVATE_IND:
1861 if (mISDNport->l1link != 0) {
1862 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1864 mISDNport->l1link = 0;
1868 case MPH_INFORMATION_IND:
1869 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1871 case L1_SIGNAL_LOS_ON:
1874 case L1_SIGNAL_LOS_OFF:
1877 case L1_SIGNAL_AIS_ON:
1880 case L1_SIGNAL_AIS_OFF:
1883 case L1_SIGNAL_RDI_ON:
1886 case L1_SIGNAL_RDI_OFF:
1889 case L1_SIGNAL_SLIP_TX:
1890 mISDNport->slip_tx++;
1892 case L1_SIGNAL_SLIP_RX:
1893 mISDNport->slip_rx++;
1898 case MT_L2ESTABLISH:
1899 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1900 add_trace("tei", NULL, "%d", l3m->pid);
1902 mISDNport->l2link = 1;
1904 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1905 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1906 if (mISDNport->l2establish.active) {
1907 unsched_timer(&mISDNport->l2establish);
1908 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1915 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1916 if (!mISDNport->l2establish.active) {
1917 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1918 add_trace("tei", NULL, "%d", l3m->pid);
1920 /* down if not nt-ptmp */
1921 if (!mISDNport->ntmode || mISDNport->ptp)
1922 mISDNport->l2link = 0;
1924 if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1925 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1926 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1927 schedule_timer(&mISDNport->l2establish, 5, 0);
1928 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1934 /* l3-data is sent to LCR */
1935 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1941 mISDNport = mISDNport->next;
1946 /* l2 establish timer fires */
1947 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1949 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1951 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1952 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1953 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1954 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1960 /* handle frames from bchannel */
1961 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1963 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1964 unsigned char buffer[2048+MISDN_HEADER_LEN];
1965 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1968 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1970 PERROR("read error frame, errno %d\n", errno);
1973 if (ret < (int)MISDN_HEADER_LEN) {
1974 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1978 /* we don't care about confirms, we use rx data to sync tx */
1982 /* we receive audio data, we respond to it AND we send tones */
1987 case PH_CONTROL_IND:
1988 if (mISDNport->b_port[i])
1989 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1991 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1994 case PH_ACTIVATE_IND:
1995 case DL_ESTABLISH_IND:
1996 case PH_ACTIVATE_CNF:
1997 case DL_ESTABLISH_CNF:
1998 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1999 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2002 case PH_DEACTIVATE_IND:
2003 case DL_RELEASE_IND:
2004 case PH_DEACTIVATE_CNF:
2005 case DL_RELEASE_CNF:
2006 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2007 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2011 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2017 /* process timer events for bchannel handling */
2018 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2020 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2023 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2029 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2033 * l3m must be queued, except for MT_ASSIGN
2036 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2039 /* special MT_ASSIGN handling:
2041 * if we request a PID from mlayer, we always do it while lcr is locked.
2042 * therefore we must check the MT_ASSIGN reply first before we lock.
2043 * this is because the MT_ASSIGN reply is received with the requesting
2044 * process, not by the mlayer thread!
2045 * this means, that the reply is sent during call of the request.
2046 * we must check if we get a reply and we know that we lcr is currently
2049 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2050 /* let's do some checking if someone changes stack behaviour */
2051 if (mt_assign_pid != 0)
2052 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2053 mt_assign_pid = pid;
2056 /* queue message, create, if required */
2058 l3m = alloc_l3_msg();
2060 FATAL("No memory for layer 3 message\n");
2062 mb = container_of(l3m, struct mbuffer, l3);
2065 mqueue_tail(&mISDNport->upqueue, mb);
2066 if (!upqueue_avail) {
2067 // multiple threads may cause multiple calls of this section, but this
2068 // results only in multiple processing of the upqueue read.
2069 // this is no problem.
2073 ret = write(upqueue_pipe[1], &byte, 1);
2078 int mISDN_getportbyname(int sock, int cnt, char *portname)
2080 struct mISDN_devinfo devinfo;
2084 while (port < cnt) {
2086 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2089 if (!strcasecmp(devinfo.name, portname))
2100 * global function to add a new card (port)
2102 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2105 struct mISDNport *mISDNport, **mISDNportp;
2106 int port = ifport->portnum;
2107 int ptp = ifport->ptp;
2108 int force_nt = ifport->nt;
2109 int l1hold = ifport->l1hold;
2110 int l2hold = ifport->l2hold;
2112 int ss5 = ifport->ss5;
2116 // struct mlayer3 *ml3;
2117 struct mISDN_devinfo devinfo;
2118 unsigned int protocol, prop;
2120 #if defined WITH_GSM_BS && defined WITH_GSM_MS
2121 loop = ifport->gsm_ms | ifport->gsm_bs;
2124 loop = ifport->gsm_bs;
2127 loop = ifport->gsm_ms;
2130 //printf("%s == %s\n", ifport->portname, options.loopback_int);
2131 if (!strcmp(ifport->portname, options.loopback_lcr))
2135 if (mISDNloop_open())
2139 /* check port counts */
2140 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2142 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2147 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2151 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2154 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
2156 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2159 // note: 'port' has still the port number
2161 if (port>cnt || port<0) {
2162 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2166 /* get port attributes */
2167 pri = bri = pots = nt = te = 0;
2169 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2171 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2174 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2178 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2182 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2186 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2191 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2197 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2202 if (force_nt && !nt) {
2203 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2207 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2210 if (pots && !bri && !pri) {
2211 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2215 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2219 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2222 /* set NT by turning off TE */
2225 /* if TE an NT is supported (and not forced to NT), turn off NT */
2229 /* check for double use of port */
2231 mISDNport = mISDNport_first;
2233 if (mISDNport->portnum == port)
2235 mISDNport = mISDNport->next;
2238 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2243 /* check for continous channelmap with no bchannel on slot 16 */
2244 if (test_channelmap(0, devinfo.channelmap)) {
2245 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2249 while(i < (int)devinfo.nrbchan + 1) {
2251 if (test_channelmap(i, devinfo.channelmap)) {
2252 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2256 if (!test_channelmap(i, devinfo.channelmap)) {
2257 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2264 /* add mISDNport structure */
2265 mISDNportp = &mISDNport_first;
2267 mISDNportp = &((*mISDNportp)->next);
2268 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2269 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2271 /* loop/ss5 link is always active */
2272 mISDNport->l1link = 1;
2273 mISDNport->l2link = 1;
2275 mISDNport->l1link = -1;
2276 mISDNport->l2link = -1;
2279 mISDNport->gsm_bs = ifport->gsm_bs;
2282 mISDNport->gsm_ms = ifport->gsm_ms;
2284 mISDNport->isloopback = loop;
2286 *mISDNportp = mISDNport;
2288 /* if pri, must set PTP */
2292 /* set ss5 params */
2294 /* try to keep interface enabled */
2314 /* allocate ressources of port */
2315 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2316 prop = (1 << MISDN_FLG_L2_CLEAN);
2317 if (ptp) // ptp forced
2318 prop |= (1 << MISDN_FLG_PTP);
2319 if (nt) // supports hold/retrieve on nt-mode
2320 prop |= (1 << MISDN_FLG_NET_HOLD);
2321 if (l1hold) // supports layer 1 hold
2322 prop |= (1 << MISDN_FLG_L1_HOLD);
2323 if (l2hold) // supports layer 2 hold
2324 prop |= (1 << MISDN_FLG_L2_HOLD);
2325 /* open layer 3 and init upqueue */
2327 unsigned long on = 1;
2328 struct sockaddr_mISDN addr;
2330 if (devinfo.nrbchan < 8) {
2331 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);
2332 // mISDNport_close(mISDNport);
2336 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
2337 PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
2338 mISDNport_close(mISDNport);
2341 /* set nonblocking io */
2342 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2343 PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
2344 mISDNport_close(mISDNport);
2347 /* bind socket to dchannel */
2348 memset(&addr, 0, sizeof(addr));
2349 addr.family = AF_ISDN;
2352 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2353 PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
2354 mISDNport_close(mISDNport);
2358 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2359 mqueue_init(&mISDNport->upqueue);
2360 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2361 if (!mISDNport->ml3) {
2362 mqueue_purge(&mISDNport->upqueue);
2363 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2371 "PORT (open failed)");
2373 mISDNport_close(mISDNport);
2378 SCPY(mISDNport->name, devinfo.name);
2379 mISDNport->b_num = devinfo.nrbchan;
2380 mISDNport->portnum = port;
2381 mISDNport->ntmode = nt;
2382 mISDNport->tespecial = ifport->tespecial;
2383 mISDNport->pri = pri;
2384 mISDNport->ptp = ptp;
2385 mISDNport->l1hold = l1hold;
2386 mISDNport->l2hold = l2hold;
2387 mISDNport->ss5 = ss5;
2388 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2390 while(i < mISDNport->b_num) {
2391 mISDNport->b_state[i] = B_STATE_IDLE;
2392 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2396 /* if ptp, pull up the link */
2397 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2398 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2399 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2400 add_trace("tei", NULL, "%d", 0);
2402 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2405 /* for nt-mode ptmp the link is always up */
2406 if (mISDNport->ntmode && !mISDNport->ptp)
2407 mISDNport->l2link = 1;
2409 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2411 start_trace(mISDNport->portnum,
2419 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2420 add_trace("channels", NULL, "%d", mISDNport->b_num);
2422 add_trace("ccitt#5", NULL, "enabled");
2430 * load static port instances, if required by mISDNport
2432 void mISDNport_static(struct mISDNport *mISDNport)
2437 while(i < mISDNport->b_num) {
2440 ss5_create_channel(mISDNport, i);
2448 * function to free ALL cards (ports)
2450 void mISDNport_close_all(void)
2452 /* free all ports */
2453 while(mISDNport_first)
2454 mISDNport_close(mISDNport_first);
2458 * free only one port
2460 void mISDNport_close(struct mISDNport *mISDNport)
2462 struct mISDNport **mISDNportp;
2464 class PmISDN *isdnport;
2467 /* remove all port instance that are linked to this mISDNport */
2471 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2472 isdnport = (class PmISDN *)port;
2473 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2474 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2482 /* only if we are already part of interface */
2483 if (mISDNport->ifport) {
2484 start_trace(mISDNport->portnum,
2485 mISDNport->ifport->interface,
2495 /* free bchannels */
2497 while(i < mISDNport->b_num) {
2498 if (mISDNport->b_sock[i].inuse) {
2499 _bchannel_destroy(mISDNport, i);
2500 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2502 if (mISDNport->b_timer[i].inuse) {
2503 del_timer(&mISDNport->b_timer[i]);
2507 del_timer(&mISDNport->l2establish);
2509 /* close layer 3, if open */
2510 if (!mISDNport->isloopback && mISDNport->ml3) {
2511 close_layer3(mISDNport->ml3);
2514 /* close gsm socket, if open */
2515 if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
2516 close(mISDNport->lcr_sock);
2520 if (!mISDNport->isloopback)
2521 mqueue_purge(&mISDNport->upqueue);
2523 /* remove from list */
2524 mISDNportp = &mISDNport_first;
2525 while(*mISDNportp) {
2526 if (*mISDNportp == mISDNport) {
2527 *mISDNportp = (*mISDNportp)->next;
2531 mISDNportp = &((*mISDNportp)->next);
2535 FATAL("mISDNport not in list\n");
2537 FREE(mISDNport, sizeof(struct mISDNport));
2544 * enque data from upper buffer
2546 void PmISDN::txfromup(unsigned char *data, int length)
2548 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2549 struct mISDNhead *hh = (struct mISDNhead *)buf;
2552 if (p_m_b_index < 0)
2554 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2557 /* check if high priority tones exist
2558 * ignore data in this case
2560 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2563 /* preload procedure
2564 * if transmit buffer in DSP module is empty,
2565 * preload it to DSP_LOAD to prevent jitter gaps.
2567 if (p_m_load == 0 && ISDN_LOAD > 0) {
2568 hh->prim = PH_DATA_REQ;
2570 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2571 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2573 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2574 p_m_load += ISDN_LOAD;
2575 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2578 /* drop if load would exceed ISDN_MAXLOAD
2579 * this keeps the delay not too high
2581 if (p_m_load+length > ISDN_MAXLOAD)
2584 /* make and send frame */
2585 hh->prim = PH_DATA_REQ;
2587 memcpy(buf+MISDN_HEADER_LEN, data, length);
2588 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2590 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2594 int PmISDN::inband_send(unsigned char *buffer, int len)
2596 PERROR("this function must be derived to function!\n");
2600 void PmISDN::inband_send_on(void)
2602 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2603 p_m_inband_send_on = 1;
2604 /* trigger inband transmit */
2608 void PmISDN::inband_send_off(void)
2610 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2611 p_m_inband_send_on = 0;
2614 void PmISDN::inband_receive(unsigned char *buffer, int len)
2617 // if (len >= SS5_DECODER_NPOINTS)
2618 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2619 PERROR("this function must be derived to function!\n");
2622 void PmISDN::inband_receive_on(void)
2624 /* this must work during constructor, see ss5.cpp */
2625 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2626 p_m_inband_receive_on = 1;
2630 void PmISDN::inband_receive_off(void)
2632 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2633 p_m_inband_receive_on = 0;
2637 void PmISDN::mute_on(void)
2641 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2643 set_conf(p_m_conf, 0);
2646 void PmISDN::mute_off(void)
2650 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2652 set_conf(0, p_m_conf);