1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
14 #include <mISDN/q931.h>
17 #ifdef __compiler_offsetof
18 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
20 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
24 #define container_of(ptr, type, member) ({ \
25 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
26 (type *)( (char *)__mptr - offsetof(type,member) );})
29 // timeouts if activating/deactivating response from mISDN got lost
30 #define B_TIMER_ACTIVATING 1 // seconds
31 #define B_TIMER_DEACTIVATING 1 // seconds
33 /* list of mISDN ports */
34 struct mISDNport *mISDNport_first;
36 /* noise randomizer */
37 unsigned char mISDN_rand[256];
38 int mISDN_rand_count = 0;
41 unsigned int mt_assign_pid = ~0;
45 static int upqueue_pipe[2];
46 static struct lcr_fd upqueue_fd;
47 int upqueue_avail = 0;
49 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
50 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
52 static int my_mISDNlib_debug(const char *file, int line, const char *func, int level, const char *fmt, va_list va)
57 ret = vfprintf(debug_fp, fmt, va);
61 static struct mi_ext_fn_s myfn;
63 int mISDN_initialize(void)
68 /* try to open raw socket to check kernel */
69 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
70 if (mISDNsocket < 0) {
71 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
76 // set debug printout function
77 myfn.prt_debug = my_mISDNlib_debug;
79 ver = init_layer3(4, &myfn); // buffer of 4
81 /* open debug, if enabled and not only stack debugging */
83 SPRINT(filename, "%s/debug.log", LOG_DIR);
84 debug_fp = fopen(filename, "a");
87 if (options.deb & DEBUG_STACK)
88 mISDN_set_debug_level(0xfffffeff);
90 mISDN_set_debug_level(0);
92 if (pipe(upqueue_pipe) < 0)
93 FATAL("Failed to open pipe\n");
94 memset(&upqueue_fd, 0, sizeof(upqueue_fd));
95 upqueue_fd.fd = upqueue_pipe[0];
96 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
101 void mISDN_deinitialize(void)
109 if (mISDNsocket > -1)
112 if (upqueue_fd.inuse) {
113 unregister_fd(&upqueue_fd);
114 close(upqueue_pipe[0]);
115 close(upqueue_pipe[1]);
120 int load_timer(struct lcr_timer *timer, void *instance, int index);
125 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
127 p_m_mISDNport = mISDNport;
128 p_m_portnum = mISDNport->portnum;
135 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
136 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
145 p_m_inband_send_on = 0;
146 p_m_inband_receive_on = 0;
147 p_m_dtmf = !mISDNport->ifport->nodtmf;
148 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
149 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
150 p_m_remote_ref = 0; /* channel shall be exported to given remote */
151 p_m_remote_id = 0; /* remote admin socket */
152 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
155 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
156 add_timer(&p_m_loadtimer, load_timer, this, 0);
162 p_m_crypt_listen = 0;
163 p_m_crypt_msg_loops = 0;
164 p_m_crypt_msg_loops = 0;
165 p_m_crypt_msg_len = 0;
166 p_m_crypt_msg[0] = '\0';
167 p_m_crypt_msg_current = 0;
168 p_m_crypt_key_len = 0;
169 p_m_crypt_listen = 0;
170 p_m_crypt_listen_state = 0;
171 p_m_crypt_listen_len = 0;
172 p_m_crypt_listen_msg[0] = '\0';
173 p_m_crypt_listen_crc = 0;
174 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
175 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
176 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
180 /* if any channel requested by constructor */
181 if (channel == CHANNEL_ANY) {
182 /* reserve channel */
184 mISDNport->b_reserved++;
187 /* reserve channel */
188 if (channel > 0) // only if constructor was called with a channel resevation
189 seize_bchannel(channel, exclusive);
191 /* we increase the number of objects: */
193 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
194 //inband_receive_on();
203 struct lcr_msg *message;
205 del_timer(&p_m_timeout);
206 del_timer(&p_m_loadtimer);
208 /* remove bchannel relation */
212 while (p_epointlist) {
213 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
214 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
215 message->param.disconnectinfo.cause = 16;
216 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
217 message_put(message);
218 /* remove from list */
219 free_epointlist(p_epointlist);
222 /* we decrease the number of objects: */
223 p_m_mISDNport->use--;
224 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
231 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
233 /* init trace with given values */
234 start_trace(mISDNport?mISDNport->portnum:-1,
235 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
236 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
237 port?port->p_dialinginfo.id:NULL,
240 port?port->p_serial:0,
248 static struct isdn_message {
252 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
253 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
254 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
255 {"DL_RELEASE", L2_RELEASE_REQ},
256 {"UNKNOWN", L3_UNKNOWN_REQ},
257 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
258 {"MT_SETUP", L3_SETUP_REQ},
259 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
260 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
261 {"MT_ALERTING", L3_ALERTING_REQ},
262 {"MT_CONNECT", L3_CONNECT_REQ},
263 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
264 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
265 {"MT_RELEASE", L3_RELEASE_REQ},
266 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
267 {"MT_INFORMATION", L3_INFORMATION_REQ},
268 {"MT_PROGRESS", L3_PROGRESS_REQ},
269 {"MT_NOTIFY", L3_NOTIFY_REQ},
270 {"MT_SUSPEND", L3_SUSPEND_REQ},
271 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
272 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
273 {"MT_RESUME", L3_RESUME_REQ},
274 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
275 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
276 {"MT_HOLD", L3_HOLD_REQ},
277 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
278 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
279 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
280 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
281 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
282 {"MT_FACILITY", L3_FACILITY_REQ},
283 {"MT_STATUS", L3_STATUS_REQ},
284 {"MT_RESTART", L3_RESTART_REQ},
285 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
286 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
289 static const char *isdn_prim[4] = {
295 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
300 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
301 /* select message and primitive text */
303 while(isdn_message[i].name) {
304 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
305 if (isdn_message[i].value == (msg&0xffffff00)) {
306 SCPY(msgtext, isdn_message[i].name);
311 SCAT(msgtext, isdn_prim[msg&0x00000003]);
314 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
316 if (mISDNport->ntmode) {
317 if (direction == DIRECTION_OUT)
318 SCAT(msgtext, " N->U");
320 SCAT(msgtext, " N<-U");
322 if (direction == DIRECTION_OUT)
323 SCAT(msgtext, " U->N");
325 SCAT(msgtext, " U<-N");
330 /* init trace with given values */
331 start_trace(mISDNport?mISDNport->portnum:-1,
332 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
333 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
334 port?port->p_dialinginfo.id:NULL,
337 port?port->p_serial:0,
343 * send control information to the channel (dsp-module)
345 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
347 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
348 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
349 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
355 ctrl->prim = PH_CONTROL_REQ;
359 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
361 PERROR("Failed to send to socket %d\n", sock);
362 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
363 if (c1 == DSP_CONF_JOIN)
364 add_trace(trace_name, NULL, "0x%08x", trace_value);
366 add_trace(trace_name, NULL, "%d", trace_value);
370 void ph_control_block(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, void *c2, int c2_len, const char *trace_name, int trace_value)
372 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
373 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
374 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
380 ctrl->prim = PH_CONTROL_REQ;
383 memcpy(d, c2, c2_len);
384 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
386 PERROR("Failed to send to socket %d\n", sock);
387 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
388 add_trace(trace_name, NULL, "%d", trace_value);
392 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
395 * subfunction for bchannel_event
398 static int _bchannel_create(struct mISDNport *mISDNport, int i)
401 struct sockaddr_mISDN addr;
403 if (mISDNport->b_sock[i].inuse) {
404 PERROR("Error: Socket already created for index %d\n", i);
409 //#warning testing without DSP
410 // mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
411 mISDNport->b_sock[i].fd = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
412 if (mISDNport->b_sock[i].fd < 0) {
413 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
417 /* register callback for read */
418 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
420 /* bind socket to bchannel */
421 addr.family = AF_ISDN;
422 addr.dev = mISDNport->portnum;
423 addr.channel = i+1+(i>=15);
424 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
426 PERROR("Error: Failed to bind bchannel-socket for index %d with mISDN-DSP layer (errno=%d). Did you load mISDN_dsp.ko?\n", i, errno);
427 close(mISDNport->b_sock[i].fd);
428 unregister_fd(&mISDNport->b_sock[i]);
432 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
433 add_trace("channel", NULL, "%d", i+1+(i>=15));
434 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
442 * subfunction for bchannel_event
443 * activate / deactivate request
445 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
447 struct mISDNhead act;
450 if (!mISDNport->b_sock[i].inuse)
452 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
454 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
456 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
459 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
460 add_trace("channel", NULL, "%d", i+1+(i>=15));
462 add_trace("event", NULL, "timeout recovery");
468 * subfunction for bchannel_event
471 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
476 if (!mISDNport->b_sock[i].inuse)
478 handle = mISDNport->b_sock[i].fd;
479 port = mISDNport->b_port[i];
480 mode = mISDNport->b_mode[i];
482 PERROR("bchannel index i=%d not associated with a port object\n", i);
486 /* set dsp features */
487 if (port->p_m_txdata)
488 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
489 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
490 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
491 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
492 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
493 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
494 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
495 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
496 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
497 if (port->p_m_conf && !port->p_m_mute)
498 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
500 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
501 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
502 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
504 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
505 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
506 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
507 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
508 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
509 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
510 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);
514 void PmISDN::set_conf(int oldconf, int newconf)
516 if (oldconf != newconf) {
517 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
518 if (p_m_b_index > -1)
519 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
520 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);
522 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
527 * subfunction for bchannel_event
530 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
532 if (!mISDNport->b_sock[i].inuse)
534 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
535 add_trace("channel", NULL, "%d", i+1+(i>=15));
536 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
538 close(mISDNport->b_sock[i].fd);
539 unregister_fd(&mISDNport->b_sock[i]);
547 A bchannel goes through the following states in this order:
550 No one is using the bchannel.
551 It is available and not linked to Port class, nor reserved.
554 The bchannel stack is created and an activation request is sent.
555 It MAY be linked to Port class, but already unlinked due to Port class removal.
558 The bchannel is active and cofigured to the Port class needs.
559 Also it is linked to a Port class, otherwhise it would be deactivated.
561 - B_STATE_DEACTIVATING
562 The bchannel is in deactivating state, due to deactivation request.
563 It may be linked to a Port class, that likes to reactivate it.
567 After deactivating bchannel, and if not used, the bchannel becomes idle again.
569 Also the bchannel may be exported, but only if the state is or becomes idle:
572 The bchannel assignment has been sent to the remove application.
575 The bchannel assignment is acknowledged by the remote application.
578 The bchannel is re-imported by mISDN port object.
582 After re-importing bchannel, and if not used, the bchannel becomes idle again.
585 A bchannel can have the following events:
588 A bchannel is required by a Port class.
591 The bchannel beomes active.
594 The bchannel is not required by Port class anymore
596 - B_EVENT_DEACTIVATED
597 The bchannel becomes inactive.
600 The bchannel is now used by remote application.
603 The bchannel is not used by remote application.
605 - B_EVENT_EXPORTREQUEST
606 The bchannel shall be exported to the remote application.
608 - B_EVENT_IMPORTREQUEST
609 The bchannel is released from the remote application.
611 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
613 if an export request is receive by remote application, p_m_remote_* is set.
614 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.)
615 - set on export request from remote application (if port is assigned)
616 - set on channel use, if requested by remote application (p_m_remote_*)
617 - cleared on drop request
619 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
620 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
621 the bchannel import/export is acknowledged with stack given.
623 if exporting, b_remote_*[index] is set to the remote socket id.
624 if importing has been acknowledged. b_remote_*[index] is cleared.
629 * process bchannel events
630 * - mISDNport is a pointer to the port's structure
631 * - i is the index of the bchannel
632 * - event is the B_EVENT_* value
633 * - port is the PmISDN class pointer
635 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
637 class PmISDN *b_port = mISDNport->b_port[i];
638 int state = mISDNport->b_state[i];
639 int timer = -1; // no change
640 unsigned int p_m_remote_ref = 0;
641 unsigned int p_m_remote_id = 0;
644 char *p_m_pipeline = NULL;
645 unsigned char *p_m_crypt_key = NULL;
646 int p_m_crypt_key_len = 0;
647 int p_m_crypt_key_type = 0;
648 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
651 p_m_remote_id = b_port->p_m_remote_id;
652 p_m_remote_ref = b_port->p_m_remote_ref;
653 p_m_tx_gain = b_port->p_m_tx_gain;
654 p_m_rx_gain = b_port->p_m_rx_gain;
655 p_m_pipeline = b_port->p_m_pipeline;
656 p_m_crypt_key = b_port->p_m_crypt_key;
657 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
658 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
663 /* port must be linked in order to allow activation */
665 FATAL("bchannel must be linked to a Port class\n");
668 if (p_m_remote_ref) {
669 /* export bchannel */
670 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);
671 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
672 add_trace("type", NULL, "assign");
673 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
675 state = B_STATE_EXPORTING;
676 mISDNport->b_remote_id[i] = p_m_remote_id;
677 mISDNport->b_remote_ref[i] = p_m_remote_ref;
679 /* create stack and send activation request */
680 if (_bchannel_create(mISDNport, i)) {
681 _bchannel_activate(mISDNport, i, 1, 0);
682 state = B_STATE_ACTIVATING;
683 timer = B_TIMER_ACTIVATING;
688 case B_STATE_ACTIVATING:
689 case B_STATE_EXPORTING:
690 /* do nothing, because it is already activating */
693 case B_STATE_DEACTIVATING:
694 case B_STATE_IMPORTING:
695 /* do nothing, because we must wait until we can reactivate */
699 /* problems that might ocurr:
700 * B_EVENT_USE is received when channel already in use.
701 * bchannel exported, but not freed by other port
703 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
707 case B_EVENT_EXPORTREQUEST:
708 /* special case where the bchannel is requested by remote */
709 if (!p_m_remote_ref) {
710 PERROR("export request without remote channel set, please correct.\n");
715 /* in case, the bchannel is exported right after seize_bchannel */
716 /* export bchannel */
717 /* p_m_remote_id is set, when this event happens. */
718 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);
719 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
720 add_trace("type", NULL, "assign");
721 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
723 state = B_STATE_EXPORTING;
724 mISDNport->b_remote_id[i] = p_m_remote_id;
725 mISDNport->b_remote_ref[i] = p_m_remote_ref;
728 case B_STATE_ACTIVATING:
729 case B_STATE_EXPORTING:
730 /* do nothing, because it is already activating */
733 case B_STATE_DEACTIVATING:
734 case B_STATE_IMPORTING:
735 /* do nothing, because we must wait until we can reactivate */
739 /* bchannel is active, so we deactivate */
740 _bchannel_activate(mISDNport, i, 0, 0);
741 state = B_STATE_DEACTIVATING;
742 timer = B_TIMER_DEACTIVATING;
746 /* problems that might ocurr:
747 * ... when channel already in use.
748 * bchannel exported, but not freed by other port
750 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
754 case B_EVENT_IMPORTREQUEST:
755 /* special case where the bchannel is released by remote */
756 if (p_m_remote_ref) {
757 PERROR("import request with remote channel set, please correct.\n");
763 /* bchannel is not exported */
766 case B_STATE_ACTIVATING:
767 case B_STATE_EXPORTING:
768 /* do nothing because we must wait until bchanenl is active before deactivating */
772 /* bchannel is exported, so we re-import */
773 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
774 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
775 add_trace("type", NULL, "remove");
776 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
778 state = B_STATE_IMPORTING;
781 case B_STATE_DEACTIVATING:
782 case B_STATE_IMPORTING:
783 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
787 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
791 case B_EVENT_ACTIVATED:
794 case B_STATE_ACTIVATING:
795 if (b_port && !p_m_remote_id) {
796 /* bchannel is active and used by Port class, so we configure bchannel */
797 _bchannel_configure(mISDNport, i);
798 state = B_STATE_ACTIVE;
799 b_port->p_m_load = 0;
801 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
802 _bchannel_activate(mISDNport, i, 0, 0);
803 state = B_STATE_DEACTIVATING;
804 timer = B_TIMER_DEACTIVATING;
809 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
813 case B_EVENT_EXPORTED:
815 case B_STATE_EXPORTING:
816 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
817 /* remote export done */
818 state = B_STATE_REMOTE;
820 /* bchannel is now exported, but we need bchannel back
821 * OR bchannel is not used anymore
822 * OR bchannel has been exported to an obsolete ref,
823 * so reimport, to later export to new remote */
824 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
825 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
826 add_trace("type", NULL, "remove");
827 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
829 state = B_STATE_IMPORTING;
834 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
840 FATAL("bchannel must be linked to a Port class\n");
843 /* bchannel is idle due to an error, so we do nothing */
846 case B_STATE_ACTIVATING:
847 case B_STATE_EXPORTING:
848 /* do nothing because we must wait until bchanenl is active before deactivating */
852 /* bchannel is active, so we deactivate */
853 _bchannel_activate(mISDNport, i, 0, 0);
854 state = B_STATE_DEACTIVATING;
855 timer = B_TIMER_DEACTIVATING;
859 /* bchannel is exported, so we re-import */
860 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
861 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
862 add_trace("type", NULL, "remove");
863 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
865 state = B_STATE_IMPORTING;
868 case B_STATE_DEACTIVATING:
869 case B_STATE_IMPORTING:
870 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
874 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
878 case B_EVENT_DEACTIVATED:
882 /* ignore due to deactivation confirm after unloading */
885 case B_STATE_DEACTIVATING:
886 _bchannel_destroy(mISDNport, i);
887 state = B_STATE_IDLE;
889 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
890 if (p_m_remote_ref) {
891 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);
892 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
893 add_trace("type", NULL, "assign");
894 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
896 state = B_STATE_EXPORTING;
897 mISDNport->b_remote_id[i] = p_m_remote_id;
898 mISDNport->b_remote_ref[i] = p_m_remote_ref;
900 if (_bchannel_create(mISDNport, i)) {
901 _bchannel_activate(mISDNport, i, 1, 0);
902 state = B_STATE_ACTIVATING;
903 timer = B_TIMER_ACTIVATING;
910 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
914 case B_EVENT_IMPORTED:
916 case B_STATE_IMPORTING:
917 state = B_STATE_IDLE;
918 mISDNport->b_remote_id[i] = 0;
919 mISDNport->b_remote_ref[i] = 0;
921 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
922 if (p_m_remote_ref) {
923 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);
924 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
925 add_trace("type", NULL, "assign");
926 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
928 state = B_STATE_EXPORTING;
929 mISDNport->b_remote_id[i] = p_m_remote_id;
930 mISDNport->b_remote_ref[i] = p_m_remote_ref;
932 if (_bchannel_create(mISDNport, i)) {
933 _bchannel_activate(mISDNport, i, 1, 0);
934 state = B_STATE_ACTIVATING;
935 timer = B_TIMER_ACTIVATING;
942 /* ignore, because not assigned */
947 case B_EVENT_TIMEOUT:
951 /* ignore due to deactivation confirm after unloading */
954 case B_STATE_ACTIVATING:
955 _bchannel_activate(mISDNport, i, 1, 1);
956 timer = B_TIMER_ACTIVATING;
959 case B_STATE_DEACTIVATING:
960 _bchannel_activate(mISDNport, i, 0, 1);
961 timer = B_TIMER_DEACTIVATING;
965 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
970 PERROR("Illegal event %d, please correct.\n", event);
973 mISDNport->b_state[i] = state;
975 unsched_timer(&mISDNport->b_timer[i]);
977 schedule_timer(&mISDNport->b_timer[i], timer, 0);
984 * check for available channel and reserve+set it.
985 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
987 * returns -(cause value) or x = channel x or 0 = no channel
988 * NOTE: no activation is done here
990 int PmISDN::seize_bchannel(int channel, int exclusive)
994 /* the channel is what we have */
995 if (p_m_b_channel == channel)
998 /* if channel already in use, release it */
1003 if (channel==CHANNEL_NO || channel==0)
1006 /* is channel in range ? */
1008 || (channel>p_m_mISDNport->b_num && channel<16)
1009 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1010 return(-6); /* channel unacceptable */
1012 /* request exclusive channel */
1013 if (exclusive && channel>0) {
1014 i = channel-1-(channel>16);
1015 if (p_m_mISDNport->b_port[i])
1016 return(-44); /* requested channel not available */
1020 /* ask for channel */
1022 i = channel-1-(channel>16);
1023 if (p_m_mISDNport->b_port[i] == NULL)
1027 /* search for channel */
1029 while(i < p_m_mISDNport->b_num) {
1030 if (!p_m_mISDNport->b_port[i]) {
1031 channel = i+1+(i>=15);
1036 return(-34); /* no free channel */
1039 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1041 /* link Port, set parameters */
1042 p_m_mISDNport->b_port[i] = this;
1044 p_m_b_channel = channel;
1045 p_m_b_exclusive = exclusive;
1046 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1048 /* reserve channel */
1049 if (!p_m_b_reserve) {
1051 p_m_mISDNport->b_reserved++;
1058 * drop reserved channel and unset it.
1059 * deactivation is also done
1061 void PmISDN::drop_bchannel(void)
1063 /* unreserve channel */
1065 p_m_mISDNport->b_reserved--;
1069 if (p_m_b_index < 0)
1074 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1076 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1077 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1078 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1079 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1082 p_m_b_exclusive = 0;
1085 /* process bchannel export/import message from join */
1086 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1088 class Endpoint *epoint;
1090 class PmISDN *isdnport;
1091 struct mISDNport *mISDNport;
1095 case BCHANNEL_REQUEST:
1096 /* find the port object for the join object ref */
1097 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1098 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1101 if (!epoint->ep_portlist) {
1102 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1105 if (epoint->ep_portlist->next) {
1106 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);
1108 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1109 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1112 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1113 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1115 isdnport = (class PmISDN *)port;
1118 if (isdnport->p_m_remote_id) {
1119 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1122 mISDNport = isdnport->p_m_mISDNport;
1123 i = isdnport->p_m_b_index;
1124 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1125 add_trace("type", NULL, "export request");
1127 isdnport->p_m_remote_ref = joinremote->j_remote_ref;
1128 isdnport->p_m_remote_id = joinremote->j_remote_id;
1129 if (mISDNport && i>=0) {
1130 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1134 case BCHANNEL_RELEASE:
1135 case BCHANNEL_ASSIGN_ACK:
1136 case BCHANNEL_REMOVE_ACK:
1137 /* find mISDNport for stack ID */
1138 mISDNport = mISDNport_first;
1141 ii = mISDNport->b_num;
1143 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1149 mISDNport = mISDNport->next;
1152 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1156 if (type!=BCHANNEL_RELEASE) {
1158 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1159 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1161 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1164 isdnport = mISDNport->b_port[i];
1165 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1166 add_trace("type", NULL, "import request");
1169 isdnport->p_m_remote_ref = 0;
1170 isdnport->p_m_remote_id = 0;
1172 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1176 PERROR("received wrong bchannel message type %d from remote\n", type);
1184 audio transmission procedure:
1185 -----------------------------
1188 three sources of audio transmission:
1189 - crypto-data high priority
1190 - tones high priority (also high)
1191 - remote-data low priority
1194 a variable that temporarily shows the number of samples elapsed since last transmission process.
1195 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1198 a variable that is increased whenever data is transmitted.
1199 it is decreased while time elapses. it stores the number of samples that
1200 are currently loaded to dsp module.
1201 since clock in dsp module is the same clock for user space process, these
1205 there are two levels:
1206 ISDN_LOAD will give the load that have to be kept in dsp.
1207 ISDN_MAXLOAD will give the maximum load before dropping.
1209 * procedure for low priority data
1210 see txfromup() for procedure
1211 in short: remote data is ignored during high priority tones
1213 * procedure for high priority data
1214 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1215 if no more data is available, load becomes empty again.
1218 0 ISDN_LOAD ISDN_MAXLOAD
1219 +--------------------+----------------------+
1221 +--------------------+----------------------+
1223 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1224 0 ISDN_LOAD ISDN_MAXLOAD
1225 +--------------------+----------------------+
1226 |TTTTTTTTTTTTTTTTTTTT| |
1227 +--------------------+----------------------+
1229 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1230 0 ISDN_LOAD ISDN_MAXLOAD
1231 +--------------------+----------------------+
1232 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1233 +--------------------+----------------------+
1236 void PmISDN::update_load(void)
1238 /* don't trigger load event if: */
1239 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1242 /* don't trigger load event if event already active */
1243 if (p_m_loadtimer.active)
1246 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1249 int load_timer(struct lcr_timer *timer, void *instance, int index)
1251 class PmISDN *isdnport = (class PmISDN *)instance;
1253 isdnport->load_tx();
1258 void PmISDN::load_tx(void)
1262 struct timeval current_time;
1265 gettimeofday(¤t_time, NULL);
1266 if (p_m_last_tv_sec) {
1267 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1268 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1270 /* set clock of last process! */
1271 p_m_last_tv_sec = current_time.tv_sec;
1272 p_m_last_tv_msec = current_time.tv_usec/1000;
1274 /* process only if we have samples and we are active */
1275 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1277 if (elapsed < p_m_load)
1278 p_m_load -= elapsed;
1282 /* to send data, tone must be on */
1283 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1284 && (p_m_load < ISDN_LOAD) /* not too much load? */
1285 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1286 int tosend = ISDN_LOAD - p_m_load, length;
1287 unsigned char buf[MISDN_HEADER_LEN+tosend];
1288 struct mISDNhead *frm = (struct mISDNhead *)buf;
1289 unsigned char *p = buf+MISDN_HEADER_LEN;
1291 /* copy inband signalling (e.g. used by ss5) */
1292 if (p_m_inband_send_on && tosend) {
1293 tosend -= inband_send(p, tosend);
1296 /* copy crypto loops */
1297 while (p_m_crypt_msg_loops && tosend) {
1298 /* how much do we have to send */
1299 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1302 if (length > tosend)
1305 /* copy message (part) to buffer */
1306 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1309 p_m_crypt_msg_current += length;
1310 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1312 p_m_crypt_msg_current = 0;
1313 p_m_crypt_msg_loops--;
1314 if (!p_m_crypt_msg_loops)
1316 // puts("eine loop weniger");
1324 if (p_tone_name[0] && tosend) {
1325 tosend -= read_audio(p, tosend);
1329 if (ISDN_LOAD - p_m_load - tosend > 0) {
1330 frm->prim = PH_DATA_REQ;
1332 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);
1334 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);
1335 p_m_load += ISDN_LOAD - p_m_load - tosend;
1340 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1341 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
1345 /* handle timeouts */
1346 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1348 class PmISDN *isdnport = (class PmISDN *)instance;
1349 struct lcr_msg *message;
1351 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);
1352 /* send timeout to endpoint */
1353 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1354 message->param.state = isdnport->p_state;
1355 message_put(message);
1362 * whenever we get audio data from bchannel, we process it here
1364 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1366 unsigned int cont = *((unsigned int *)data);
1367 unsigned char *data_temp;
1368 unsigned int length_temp;
1369 struct lcr_msg *message;
1373 if (hh->prim == PH_CONTROL_IND) {
1375 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1378 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1379 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1380 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1382 add_trace("info", NULL, "DTMF is disabled");
1386 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1387 message->param.dtmf = cont & DTMF_TONE_MASK;
1388 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1389 message_put(message);
1394 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1395 add_trace("DSP-CRYPT", NULL, "error");
1397 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1398 message->param.crypt.type = CC_ERROR_IND;
1399 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1400 message_put(message);
1404 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1405 add_trace("DSP-CRYPT", NULL, "ok");
1407 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1408 message->param.crypt.type = CC_ACTBF_CONF;
1409 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1410 message_put(message);
1414 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1415 add_trace("unknown", NULL, "0x%x", cont);
1420 if (hh->prim == PH_CONTROL_IND) {
1423 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1424 add_trace("unknown", NULL, "0x%x", hh->id);
1429 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1431 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1432 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1435 /* see below (same condition) */
1436 if (p_state!=PORT_STATE_CONNECT
1437 && !p_m_mISDNport->tones)
1439 // printf(".");fflush(stdout);return;
1441 record(data, len, 1); // from up
1444 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1445 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1449 /* inband is processed */
1450 if (p_m_inband_receive_on)
1451 inband_receive(data, len);
1453 /* calls will not process any audio data unless
1454 * the call is connected OR tones feature is enabled.
1456 #ifndef DEBUG_COREBRIDGE
1457 if (p_state!=PORT_STATE_CONNECT
1458 && !p_m_mISDNport->tones)
1463 /* the bearer capability must be audio in order to send and receive
1464 * audio prior or after connect.
1466 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1470 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1472 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1478 record(data, len, 0); // from down
1480 /* randomize and listen to crypt message if enabled */
1481 if (p_m_crypt_listen) {
1482 /* the noisy randomizer */
1486 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1488 cryptman_listen_bch(data, len);
1493 /* send data to epoint */
1494 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1497 while(length_temp) {
1498 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1499 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1500 memcpy(message->param.data.data, data_temp, message->param.data.len);
1501 message_put(message);
1502 if (length_temp <= sizeof(message->param.data.data))
1504 data_temp += sizeof(message->param.data.data);
1505 length_temp -= sizeof(message->param.data.data);
1514 void PmISDN::set_echotest(int echo)
1516 if (p_m_echo != echo) {
1518 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1520 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1521 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);
1528 void PmISDN::set_tone(const char *dir, const char *tone)
1533 /* if no directory is given (by extension), we use interface.conf or options.conf */
1534 if (!dir || !dir[0]) {
1535 if (p_m_mISDNport->ifport->tones_dir[0])
1536 dir = p_m_mISDNport->ifport->tones_dir;
1537 else if (options.tones_dir[0])
1538 dir = options.tones_dir;
1543 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1549 /* check for dsp tones */
1550 if (!strcmp(dir, "american"))
1552 if (!strcmp(dir, "german"))
1554 if (!strcmp(dir, "oldgerman"))
1555 dsp = DSP_OLDGERMAN;
1557 /* check if we NOT really have to use a dsp-tone */
1558 if (dsp == DSP_NONE) {
1561 if (p_m_b_index > -1)
1562 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) {
1563 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1564 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1567 Port::set_tone(dir, tone);
1571 /* now we USE dsp-tone, convert name */
1572 if (!strcmp(tone, "dialtone")) {
1574 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1575 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1576 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1578 } else if (!strcmp(tone, "dialpbx")) {
1580 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1581 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1582 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1584 } else if (!strcmp(tone, "ringing")) {
1586 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1587 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1588 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1590 } else if (!strcmp(tone, "ringpbx")) {
1592 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1593 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1594 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1596 } else if (!strcmp(tone, "busy")) {
1599 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1600 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1601 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1603 } else if (!strcmp(tone, "release")) {
1606 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1607 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1608 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1610 } else if (!strcmp(tone, "cause_10"))
1612 else if (!strcmp(tone, "cause_11"))
1614 else if (!strcmp(tone, "cause_22")) {
1616 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1617 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1618 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1620 } else if (!strncmp(tone, "cause_", 6))
1621 id = TONE_SPECIAL_INFO;
1625 /* if we have a tone that is not supported by dsp */
1626 if (id==TONE_OFF && tone[0])
1630 if (p_m_tone != id) {
1633 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1634 if (p_m_b_index > -1)
1635 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)
1636 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);
1638 /* turn user-space tones off in cases of no tone OR dsp tone */
1639 Port::set_tone("",NULL);
1643 /* MESSAGE_mISDNSIGNAL */
1644 //extern struct lcr_msg *dddebug;
1645 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1647 int oldconf, newconf;
1648 switch(param->mISDNsignal.message) {
1649 case mISDNSIGNAL_VOLUME:
1650 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1651 p_m_tx_gain = param->mISDNsignal.tx_gain;
1652 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1653 if (p_m_b_index > -1)
1654 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)
1655 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);
1657 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1658 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1659 p_m_rx_gain = param->mISDNsignal.rx_gain;
1660 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
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, DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1665 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1668 case mISDNSIGNAL_CONF:
1669 oldconf = p_m_mute?0:p_m_conf;
1670 p_m_conf = param->mISDNsignal.conf;
1671 newconf = p_m_mute?0:p_m_conf;
1672 set_conf(oldconf, newconf);
1675 case mISDNSIGNAL_JOINDATA:
1676 if (p_m_joindata != param->mISDNsignal.joindata) {
1677 p_m_joindata = param->mISDNsignal.joindata;
1678 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1681 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1684 case mISDNSIGNAL_DELAY:
1685 if (p_m_delay != param->mISDNsignal.delay) {
1686 p_m_delay = param->mISDNsignal.delay;
1687 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1688 if (p_m_b_index > -1)
1689 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)
1690 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);
1692 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1696 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1701 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1703 struct lcr_msg *message;
1705 switch(param->crypt.type) {
1706 case CC_ACTBF_REQ: /* activate blowfish */
1708 p_m_crypt_key_len = param->crypt.len;
1709 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1710 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1711 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1712 message->param.crypt.type = CC_ERROR_IND;
1713 message_put(message);
1716 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1718 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1719 if (p_m_b_index > -1)
1720 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)
1721 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);
1724 case CC_DACT_REQ: /* deactivate session encryption */
1729 case CR_LISTEN_REQ: /* start listening to messages */
1730 p_m_crypt_listen = 1;
1732 p_m_crypt_listen_state = 0;
1735 case CR_UNLISTEN_REQ: /* stop listening to messages */
1736 p_m_crypt_listen = 0;
1740 case CR_MESSAGE_REQ: /* send message */
1741 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1742 if (!p_m_crypt_msg_len) {
1743 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1746 p_m_crypt_msg_current = 0; /* reset */
1747 p_m_crypt_msg_loops = 6; /* enable */
1751 /* disable txmix, or we get corrupt data due to audio process */
1752 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1753 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1754 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1760 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1766 * endpoint sends messages to the port
1768 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1770 if (Port::message_epoint(epoint_id, message_id, param))
1773 switch(message_id) {
1774 case MESSAGE_DATA: /* tx-data from upper layer */
1775 txfromup(param->data.data, param->data.len);
1778 case MESSAGE_mISDNSIGNAL: /* user command */
1779 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1780 message_mISDNsignal(epoint_id, message_id, param);
1783 case MESSAGE_CRYPT: /* crypt control command */
1784 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1785 message_crypt(epoint_id, message_id, param);
1792 void PmISDN::update_rxoff(void)
1794 /* call bridges in user space OR crypto OR recording */
1795 if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1796 /* rx IS required */
1800 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1801 if (p_m_b_index > -1)
1802 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1803 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1806 /* rx NOT required */
1810 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1811 if (p_m_b_index > -1)
1812 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1813 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1818 /* txdata IS required */
1822 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1823 if (p_m_b_index > -1)
1824 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1825 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1828 /* txdata NOT required */
1832 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1833 if (p_m_b_index > -1)
1834 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1835 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1840 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1842 struct mISDNport *mISDNport;
1848 /* unset global semaphore */
1850 // with a very small incident, upqueue_avail may be set by mISDN thread and
1851 // another byte may be sent to the pipe, which causes a call to this function
1852 // again with nothing in the upqueue. this is no problem.
1853 ret = read(fd->fd, &byte, 1);
1855 /* process all ports */
1856 mISDNport = mISDNport_first;
1858 /* handle queued up-messages (d-channel) */
1859 if (!mISDNport->isloopback) {
1860 while ((mb = mdequeue(&mISDNport->upqueue))) {
1863 case MPH_ACTIVATE_IND:
1864 if (mISDNport->l1link != 1) {
1865 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1867 mISDNport->l1link = 1;
1871 case MPH_DEACTIVATE_IND:
1872 if (mISDNport->l1link != 0) {
1873 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1875 mISDNport->l1link = 0;
1879 case MPH_INFORMATION_IND:
1880 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1882 case L1_SIGNAL_LOS_ON:
1885 case L1_SIGNAL_LOS_OFF:
1888 case L1_SIGNAL_AIS_ON:
1891 case L1_SIGNAL_AIS_OFF:
1894 case L1_SIGNAL_RDI_ON:
1897 case L1_SIGNAL_RDI_OFF:
1900 case L1_SIGNAL_SLIP_TX:
1901 mISDNport->slip_tx++;
1903 case L1_SIGNAL_SLIP_RX:
1904 mISDNport->slip_rx++;
1909 case MT_L2ESTABLISH:
1910 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1911 add_trace("tei", NULL, "%d", l3m->pid);
1913 mISDNport->l2link = 1;
1915 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1916 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1917 if (mISDNport->l2establish.active) {
1918 unsched_timer(&mISDNport->l2establish);
1919 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1926 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1927 if (!mISDNport->l2establish.active) {
1928 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1929 add_trace("tei", NULL, "%d", l3m->pid);
1931 /* down if not nt-ptmp */
1932 if (!mISDNport->ntmode || mISDNport->ptp)
1933 mISDNport->l2link = 0;
1935 if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1936 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1937 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1938 schedule_timer(&mISDNport->l2establish, 5, 0);
1939 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1945 /* l3-data is sent to LCR */
1946 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1952 mISDNport = mISDNport->next;
1957 /* l2 establish timer fires */
1958 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1960 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1962 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1963 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1964 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1965 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1971 /* handle frames from bchannel */
1972 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1974 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1975 unsigned char buffer[2048+MISDN_HEADER_LEN];
1976 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1979 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1981 PERROR("read error frame, errno %d\n", errno);
1984 if (ret < (int)MISDN_HEADER_LEN) {
1985 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1989 /* we don't care about confirms, we use rx data to sync tx */
1993 /* we receive audio data, we respond to it AND we send tones */
1998 case PH_CONTROL_IND:
1999 if (mISDNport->b_port[i])
2000 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2002 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
2005 case PH_ACTIVATE_IND:
2006 case DL_ESTABLISH_IND:
2007 case PH_ACTIVATE_CNF:
2008 case DL_ESTABLISH_CNF:
2009 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
2010 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2013 case PH_DEACTIVATE_IND:
2014 case DL_RELEASE_IND:
2015 case PH_DEACTIVATE_CNF:
2016 case DL_RELEASE_CNF:
2017 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2018 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2022 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2028 /* process timer events for bchannel handling */
2029 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2031 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2034 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2040 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2044 * l3m must be queued, except for MT_ASSIGN
2047 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2050 #ifdef OLD_MT_ASSIGN
2051 /* special MT_ASSIGN handling:
2053 * if we request a PID from mlayer, we always do it while lcr is locked.
2054 * therefore we must check the MT_ASSIGN reply first before we lock.
2055 * this is because the MT_ASSIGN reply is received with the requesting
2056 * process, not by the mlayer thread!
2057 * this means, that the reply is sent during call of the request.
2058 * we must check if we get a reply and we know that we lcr is currently
2061 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2062 /* let's do some checking if someone changes stack behaviour */
2063 if (mt_assign_pid != 0)
2064 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2065 mt_assign_pid = pid;
2069 /* queue message, create, if required */
2071 l3m = alloc_l3_msg();
2073 FATAL("No memory for layer 3 message\n");
2075 mb = container_of(l3m, struct mbuffer, l3);
2078 mqueue_tail(&mISDNport->upqueue, mb);
2079 if (!upqueue_avail) {
2080 // multiple threads may cause multiple calls of this section, but this
2081 // results only in multiple processing of the upqueue read.
2082 // this is no problem.
2086 ret = write(upqueue_pipe[1], &byte, 1);
2091 int mISDN_getportbyname(int sock, int cnt, char *portname)
2093 struct mISDN_devinfo devinfo;
2097 while (port < cnt) {
2099 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2102 if (!strcasecmp(devinfo.name, portname))
2113 * global function to add a new card (port)
2115 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2118 struct mISDNport *mISDNport, **mISDNportp;
2119 int port = ifport->portnum;
2120 int ptp = ifport->ptp;
2121 int force_nt = ifport->nt;
2122 int l1hold = ifport->l1hold;
2123 int l2hold = ifport->l2hold;
2125 int ss5 = ifport->ss5;
2129 // struct mlayer3 *ml3;
2130 struct mISDN_devinfo devinfo;
2131 unsigned int protocol, prop;
2133 #if defined WITH_GSM_BS && defined WITH_GSM_MS
2134 loop = ifport->gsm_ms | ifport->gsm_bs;
2137 loop = ifport->gsm_bs;
2140 loop = ifport->gsm_ms;
2143 //printf("%s == %s\n", ifport->portname, options.loopback_int);
2144 if (!strcmp(ifport->portname, options.loopback_lcr))
2148 if (mISDNloop_open())
2152 /* check port counts */
2153 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2155 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2160 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2164 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2167 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
2169 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2172 // note: 'port' has still the port number
2174 if (port>cnt || port<0) {
2175 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2179 /* get port attributes */
2180 pri = bri = pots = nt = te = 0;
2182 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2184 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2187 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2191 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2195 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2199 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2204 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2210 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2215 if (force_nt && !nt) {
2216 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2220 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2223 if (pots && !bri && !pri) {
2224 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2228 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2232 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2235 /* set NT by turning off TE */
2238 /* if TE an NT is supported (and not forced to NT), turn off NT */
2242 /* check for double use of port */
2244 mISDNport = mISDNport_first;
2246 if (mISDNport->portnum == port)
2248 mISDNport = mISDNport->next;
2251 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2256 /* check for continous channelmap with no bchannel on slot 16 */
2257 if (test_channelmap(0, devinfo.channelmap)) {
2258 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2262 while(i < (int)devinfo.nrbchan + 1) {
2264 if (test_channelmap(i, devinfo.channelmap)) {
2265 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2269 if (!test_channelmap(i, devinfo.channelmap)) {
2270 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2277 /* add mISDNport structure */
2278 mISDNportp = &mISDNport_first;
2280 mISDNportp = &((*mISDNportp)->next);
2281 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2282 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2284 /* loop/ss5 link is always active */
2285 mISDNport->l1link = 1;
2286 mISDNport->l2link = 1;
2288 mISDNport->l1link = -1;
2289 mISDNport->l2link = -1;
2292 mISDNport->gsm_bs = ifport->gsm_bs;
2295 mISDNport->gsm_ms = ifport->gsm_ms;
2297 mISDNport->isloopback = loop;
2299 *mISDNportp = mISDNport;
2301 /* if pri, must set PTP */
2305 /* set ss5 params */
2307 /* try to keep interface enabled */
2327 /* allocate ressources of port */
2328 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2329 prop = (1 << MISDN_FLG_L2_CLEAN);
2330 if (ptp) // ptp forced
2331 prop |= (1 << MISDN_FLG_PTP);
2332 if (nt) // supports hold/retrieve on nt-mode
2333 prop |= (1 << MISDN_FLG_NET_HOLD);
2334 if (l1hold) // supports layer 1 hold
2335 prop |= (1 << MISDN_FLG_L1_HOLD);
2336 if (l2hold) // supports layer 2 hold
2337 prop |= (1 << MISDN_FLG_L2_HOLD);
2338 /* open layer 3 and init upqueue */
2340 unsigned long on = 1;
2341 struct sockaddr_mISDN addr;
2343 if (devinfo.nrbchan < 8) {
2344 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);
2345 // mISDNport_close(mISDNport);
2349 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
2350 PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
2351 mISDNport_close(mISDNport);
2354 /* set nonblocking io */
2355 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2356 PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
2357 mISDNport_close(mISDNport);
2360 /* bind socket to dchannel */
2361 memset(&addr, 0, sizeof(addr));
2362 addr.family = AF_ISDN;
2365 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2366 PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
2367 mISDNport_close(mISDNport);
2371 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2372 mqueue_init(&mISDNport->upqueue);
2373 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2374 if (!mISDNport->ml3) {
2375 mqueue_purge(&mISDNport->upqueue);
2376 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2384 "PORT (open failed)");
2386 mISDNport_close(mISDNport);
2391 SCPY(mISDNport->name, devinfo.name);
2392 mISDNport->b_num = devinfo.nrbchan;
2393 mISDNport->portnum = port;
2394 mISDNport->ntmode = nt;
2395 mISDNport->tespecial = ifport->tespecial;
2396 mISDNport->pri = pri;
2397 mISDNport->ptp = ptp;
2398 mISDNport->l1hold = l1hold;
2399 mISDNport->l2hold = l2hold;
2400 mISDNport->ss5 = ss5;
2401 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2403 while(i < mISDNport->b_num) {
2404 mISDNport->b_state[i] = B_STATE_IDLE;
2405 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2409 /* if ptp, pull up the link */
2410 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2411 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2412 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2413 add_trace("tei", NULL, "%d", 0);
2415 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2418 /* for nt-mode ptmp the link is always up */
2419 if (mISDNport->ntmode && !mISDNport->ptp)
2420 mISDNport->l2link = 1;
2422 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2424 start_trace(mISDNport->portnum,
2432 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2433 add_trace("channels", NULL, "%d", mISDNport->b_num);
2435 add_trace("ccitt#5", NULL, "enabled");
2443 * load static port instances, if required by mISDNport
2445 void mISDNport_static(struct mISDNport *mISDNport)
2450 while(i < mISDNport->b_num) {
2453 ss5_create_channel(mISDNport, i);
2461 * function to free ALL cards (ports)
2463 void mISDNport_close_all(void)
2465 /* free all ports */
2466 while(mISDNport_first)
2467 mISDNport_close(mISDNport_first);
2471 * free only one port
2473 void mISDNport_close(struct mISDNport *mISDNport)
2475 struct mISDNport **mISDNportp;
2477 class PmISDN *isdnport;
2480 /* remove all port instance that are linked to this mISDNport */
2484 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2485 isdnport = (class PmISDN *)port;
2486 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2487 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2495 /* only if we are already part of interface */
2496 if (mISDNport->ifport) {
2497 start_trace(mISDNport->portnum,
2498 mISDNport->ifport->interface,
2508 /* free bchannels */
2510 while(i < mISDNport->b_num) {
2511 if (mISDNport->b_sock[i].inuse) {
2512 _bchannel_destroy(mISDNport, i);
2513 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2515 if (mISDNport->b_timer[i].inuse) {
2516 del_timer(&mISDNport->b_timer[i]);
2520 del_timer(&mISDNport->l2establish);
2522 /* close layer 3, if open */
2523 if (!mISDNport->isloopback && mISDNport->ml3) {
2524 close_layer3(mISDNport->ml3);
2527 /* close gsm socket, if open */
2528 if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
2529 close(mISDNport->lcr_sock);
2533 if (!mISDNport->isloopback)
2534 mqueue_purge(&mISDNport->upqueue);
2536 /* remove from list */
2537 mISDNportp = &mISDNport_first;
2538 while(*mISDNportp) {
2539 if (*mISDNportp == mISDNport) {
2540 *mISDNportp = (*mISDNportp)->next;
2544 mISDNportp = &((*mISDNportp)->next);
2548 FATAL("mISDNport not in list\n");
2550 FREE(mISDNport, sizeof(struct mISDNport));
2557 * enque data from upper buffer
2559 void PmISDN::txfromup(unsigned char *data, int length)
2561 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2562 struct mISDNhead *hh = (struct mISDNhead *)buf;
2565 if (p_m_b_index < 0)
2567 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2570 /* check if high priority tones exist
2571 * ignore data in this case
2573 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2576 /* preload procedure
2577 * if transmit buffer in DSP module is empty,
2578 * preload it to DSP_LOAD to prevent jitter gaps.
2580 if (p_m_load == 0 && ISDN_LOAD > 0) {
2581 hh->prim = PH_DATA_REQ;
2583 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2584 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2586 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2587 p_m_load += ISDN_LOAD;
2588 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2591 /* drop if load would exceed ISDN_MAXLOAD
2592 * this keeps the delay not too high
2594 if (p_m_load+length > ISDN_MAXLOAD)
2597 /* make and send frame */
2598 hh->prim = PH_DATA_REQ;
2600 memcpy(buf+MISDN_HEADER_LEN, data, length);
2601 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2603 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2607 int PmISDN::inband_send(unsigned char *buffer, int len)
2609 PERROR("this function must be derived to function!\n");
2613 void PmISDN::inband_send_on(void)
2615 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2616 p_m_inband_send_on = 1;
2617 /* trigger inband transmit */
2621 void PmISDN::inband_send_off(void)
2623 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2624 p_m_inband_send_on = 0;
2627 void PmISDN::inband_receive(unsigned char *buffer, int len)
2630 // if (len >= SS5_DECODER_NPOINTS)
2631 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2632 PERROR("this function must be derived to function!\n");
2635 void PmISDN::inband_receive_on(void)
2637 /* this must work during constructor, see ss5.cpp */
2638 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2639 p_m_inband_receive_on = 1;
2643 void PmISDN::inband_receive_off(void)
2645 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2646 p_m_inband_receive_on = 0;
2650 void PmISDN::mute_on(void)
2654 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2656 set_conf(p_m_conf, 0);
2659 void PmISDN::mute_off(void)
2663 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2665 set_conf(0, p_m_conf);