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;
40 unsigned int mt_assign_pid = ~0;
43 static int upqueue_pipe[2];
44 static struct lcr_fd upqueue_fd;
45 int upqueue_avail = 0;
47 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
48 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
50 static int my_mISDNlib_debug(const char *file, int line, const char *func, int level, const char *fmt, va_list va)
55 ret = vfprintf(debug_fp, fmt, va);
59 static struct mi_ext_fn_s myfn;
61 int mISDN_initialize(void)
66 /* try to open raw socket to check kernel */
67 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
68 if (mISDNsocket < 0) {
69 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
74 // set debug printout function
75 myfn.prt_debug = my_mISDNlib_debug;
77 ver = init_layer3(4, &myfn); // buffer of 4
79 /* open debug, if enabled and not only stack debugging */
81 SPRINT(filename, "%s/debug.log", LOG_DIR);
82 debug_fp = fopen(filename, "a");
85 if (options.deb & DEBUG_STACK)
86 mISDN_set_debug_level(0xfffffeff);
88 mISDN_set_debug_level(0);
90 if (pipe(upqueue_pipe) < 0)
91 FATAL("Failed to open pipe\n");
92 memset(&upqueue_fd, 0, sizeof(upqueue_fd));
93 upqueue_fd.fd = upqueue_pipe[0];
94 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
99 void mISDN_deinitialize(void)
107 if (mISDNsocket > -1)
110 if (upqueue_fd.inuse) {
111 unregister_fd(&upqueue_fd);
112 close(upqueue_pipe[0]);
113 close(upqueue_pipe[1]);
118 int load_timer(struct lcr_timer *timer, void *instance, int index);
123 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
125 p_m_mISDNport = mISDNport;
126 p_m_portnum = mISDNport->portnum;
133 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
134 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
143 p_m_inband_send_on = 0;
144 p_m_inband_receive_on = 0;
145 p_m_dtmf = !mISDNport->ifport->nodtmf;
146 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
147 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
148 p_m_remote_ref = 0; /* channel shall be exported to given remote */
149 p_m_remote_id = 0; /* remote admin socket */
150 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
153 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
154 add_timer(&p_m_loadtimer, load_timer, this, 0);
160 p_m_crypt_listen = 0;
161 p_m_crypt_msg_loops = 0;
162 p_m_crypt_msg_loops = 0;
163 p_m_crypt_msg_len = 0;
164 p_m_crypt_msg[0] = '\0';
165 p_m_crypt_msg_current = 0;
166 p_m_crypt_key_len = 0;
167 p_m_crypt_listen = 0;
168 p_m_crypt_listen_state = 0;
169 p_m_crypt_listen_len = 0;
170 p_m_crypt_listen_msg[0] = '\0';
171 p_m_crypt_listen_crc = 0;
172 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
173 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
174 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
178 /* if any channel requested by constructor */
179 if (channel == CHANNEL_ANY) {
180 /* reserve channel */
182 mISDNport->b_reserved++;
185 /* reserve channel */
186 if (channel > 0) // only if constructor was called with a channel resevation
187 seize_bchannel(channel, exclusive);
189 /* we increase the number of objects: */
191 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
192 //inband_receive_on();
201 struct lcr_msg *message;
203 del_timer(&p_m_timeout);
204 del_timer(&p_m_loadtimer);
206 /* remove bchannel relation */
210 while (p_epointlist) {
211 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
212 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
213 message->param.disconnectinfo.cause = 16;
214 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
215 message_put(message);
216 /* remove from list */
217 free_epointlist(p_epointlist);
220 /* we decrease the number of objects: */
221 p_m_mISDNport->use--;
222 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
229 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
231 /* init trace with given values */
232 start_trace(mISDNport?mISDNport->portnum:-1,
233 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
234 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
235 port?port->p_dialinginfo.id:NULL,
238 port?port->p_serial:0,
246 static struct isdn_message {
250 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
251 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
252 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
253 {"DL_RELEASE", L2_RELEASE_REQ},
254 {"UNKNOWN", L3_UNKNOWN_REQ},
255 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
256 {"MT_SETUP", L3_SETUP_REQ},
257 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
258 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
259 {"MT_ALERTING", L3_ALERTING_REQ},
260 {"MT_CONNECT", L3_CONNECT_REQ},
261 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
262 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
263 {"MT_RELEASE", L3_RELEASE_REQ},
264 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
265 {"MT_INFORMATION", L3_INFORMATION_REQ},
266 {"MT_PROGRESS", L3_PROGRESS_REQ},
267 {"MT_NOTIFY", L3_NOTIFY_REQ},
268 {"MT_SUSPEND", L3_SUSPEND_REQ},
269 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
270 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
271 {"MT_RESUME", L3_RESUME_REQ},
272 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
273 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
274 {"MT_HOLD", L3_HOLD_REQ},
275 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
276 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
277 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
278 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
279 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
280 {"MT_FACILITY", L3_FACILITY_REQ},
281 {"MT_STATUS", L3_STATUS_REQ},
282 {"MT_RESTART", L3_RESTART_REQ},
283 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
284 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
287 static const char *isdn_prim[4] = {
293 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
298 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
299 /* select message and primitive text */
301 while(isdn_message[i].name) {
302 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
303 if (isdn_message[i].value == (msg&0xffffff00)) {
304 SCPY(msgtext, isdn_message[i].name);
309 SCAT(msgtext, isdn_prim[msg&0x00000003]);
312 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
314 if (mISDNport->ntmode) {
315 if (direction == DIRECTION_OUT)
316 SCAT(msgtext, " N->U");
318 SCAT(msgtext, " N<-U");
320 if (direction == DIRECTION_OUT)
321 SCAT(msgtext, " U->N");
323 SCAT(msgtext, " U<-N");
328 /* init trace with given values */
329 start_trace(mISDNport?mISDNport->portnum:-1,
330 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
331 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
332 port?port->p_dialinginfo.id:NULL,
335 port?port->p_serial:0,
341 * send control information to the channel (dsp-module)
343 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
345 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
346 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
347 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
353 ctrl->prim = PH_CONTROL_REQ;
357 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
359 PERROR("Failed to send to socket %d\n", sock);
360 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
361 if (c1 == DSP_CONF_JOIN)
362 add_trace(trace_name, NULL, "0x%08x", trace_value);
364 add_trace(trace_name, NULL, "%d", trace_value);
368 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)
370 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
371 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
372 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
378 ctrl->prim = PH_CONTROL_REQ;
381 memcpy(d, c2, c2_len);
382 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
384 PERROR("Failed to send to socket %d\n", sock);
385 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
386 add_trace(trace_name, NULL, "%d", trace_value);
390 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
393 * subfunction for bchannel_event
396 static int _bchannel_create(struct mISDNport *mISDNport, int i)
399 struct sockaddr_mISDN addr;
401 if (mISDNport->b_sock[i].inuse) {
402 PERROR("Error: Socket already created for index %d\n", i);
407 //#warning testing without DSP
408 // 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);
409 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);
410 if (mISDNport->b_sock[i].fd < 0) {
411 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
415 /* register callback for read */
416 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
418 /* bind socket to bchannel */
419 addr.family = AF_ISDN;
420 addr.dev = mISDNport->portnum;
421 addr.channel = i+1+(i>=15);
422 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
424 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);
425 close(mISDNport->b_sock[i].fd);
426 unregister_fd(&mISDNport->b_sock[i]);
430 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
431 add_trace("channel", NULL, "%d", i+1+(i>=15));
432 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
440 * subfunction for bchannel_event
441 * activate / deactivate request
443 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
445 struct mISDNhead act;
448 if (!mISDNport->b_sock[i].inuse)
450 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
452 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
454 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
457 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
458 add_trace("channel", NULL, "%d", i+1+(i>=15));
460 add_trace("event", NULL, "timeout recovery");
466 * subfunction for bchannel_event
469 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
474 if (!mISDNport->b_sock[i].inuse)
476 handle = mISDNport->b_sock[i].fd;
477 port = mISDNport->b_port[i];
478 mode = mISDNport->b_mode[i];
480 PERROR("bchannel index i=%d not associated with a port object\n", i);
484 /* set dsp features */
485 if (port->p_m_txdata)
486 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
487 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
488 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
489 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
490 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
491 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
492 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
493 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
494 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
495 if (port->p_m_conf && !port->p_m_mute)
496 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
498 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
499 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
500 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
502 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
503 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
504 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
505 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
506 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
507 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
508 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);
512 void PmISDN::set_conf(int oldconf, int newconf)
514 if (oldconf != newconf) {
515 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
516 if (p_m_b_index > -1)
517 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
518 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);
520 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
525 * subfunction for bchannel_event
528 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
530 if (!mISDNport->b_sock[i].inuse)
532 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
533 add_trace("channel", NULL, "%d", i+1+(i>=15));
534 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
536 close(mISDNport->b_sock[i].fd);
537 unregister_fd(&mISDNport->b_sock[i]);
545 A bchannel goes through the following states in this order:
548 No one is using the bchannel.
549 It is available and not linked to Port class, nor reserved.
552 The bchannel stack is created and an activation request is sent.
553 It MAY be linked to Port class, but already unlinked due to Port class removal.
556 The bchannel is active and cofigured to the Port class needs.
557 Also it is linked to a Port class, otherwhise it would be deactivated.
559 - B_STATE_DEACTIVATING
560 The bchannel is in deactivating state, due to deactivation request.
561 It may be linked to a Port class, that likes to reactivate it.
565 After deactivating bchannel, and if not used, the bchannel becomes idle again.
567 Also the bchannel may be exported, but only if the state is or becomes idle:
570 The bchannel assignment has been sent to the remove application.
573 The bchannel assignment is acknowledged by the remote application.
576 The bchannel is re-imported by mISDN port object.
580 After re-importing bchannel, and if not used, the bchannel becomes idle again.
583 A bchannel can have the following events:
586 A bchannel is required by a Port class.
589 The bchannel beomes active.
592 The bchannel is not required by Port class anymore
594 - B_EVENT_DEACTIVATED
595 The bchannel becomes inactive.
598 The bchannel is now used by remote application.
601 The bchannel is not used by remote application.
603 - B_EVENT_EXPORTREQUEST
604 The bchannel shall be exported to the remote application.
606 - B_EVENT_IMPORTREQUEST
607 The bchannel is released from the remote application.
609 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
611 if an export request is receive by remote application, p_m_remote_* is set.
612 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.)
613 - set on export request from remote application (if port is assigned)
614 - set on channel use, if requested by remote application (p_m_remote_*)
615 - cleared on drop request
617 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
618 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
619 the bchannel import/export is acknowledged with stack given.
621 if exporting, b_remote_*[index] is set to the remote socket id.
622 if importing has been acknowledged. b_remote_*[index] is cleared.
627 * process bchannel events
628 * - mISDNport is a pointer to the port's structure
629 * - i is the index of the bchannel
630 * - event is the B_EVENT_* value
631 * - port is the PmISDN class pointer
633 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
635 class PmISDN *b_port = mISDNport->b_port[i];
636 int state = mISDNport->b_state[i];
637 int timer = -1; // no change
638 unsigned int p_m_remote_ref = 0;
639 unsigned int p_m_remote_id = 0;
642 char *p_m_pipeline = NULL;
643 unsigned char *p_m_crypt_key = NULL;
644 int p_m_crypt_key_len = 0;
645 int p_m_crypt_key_type = 0;
646 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
649 p_m_remote_id = b_port->p_m_remote_id;
650 p_m_remote_ref = b_port->p_m_remote_ref;
651 p_m_tx_gain = b_port->p_m_tx_gain;
652 p_m_rx_gain = b_port->p_m_rx_gain;
653 p_m_pipeline = b_port->p_m_pipeline;
654 p_m_crypt_key = b_port->p_m_crypt_key;
655 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
656 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
661 /* port must be linked in order to allow activation */
663 FATAL("bchannel must be linked to a Port class\n");
666 if (p_m_remote_ref) {
667 /* export bchannel */
668 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);
669 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
670 add_trace("type", NULL, "assign");
671 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
673 state = B_STATE_EXPORTING;
674 mISDNport->b_remote_id[i] = p_m_remote_id;
675 mISDNport->b_remote_ref[i] = p_m_remote_ref;
677 /* create stack and send activation request */
678 if (_bchannel_create(mISDNport, i)) {
679 _bchannel_activate(mISDNport, i, 1, 0);
680 state = B_STATE_ACTIVATING;
681 timer = B_TIMER_ACTIVATING;
686 case B_STATE_ACTIVATING:
687 case B_STATE_EXPORTING:
688 /* do nothing, because it is already activating */
691 case B_STATE_DEACTIVATING:
692 case B_STATE_IMPORTING:
693 /* do nothing, because we must wait until we can reactivate */
697 /* problems that might ocurr:
698 * B_EVENT_USE is received when channel already in use.
699 * bchannel exported, but not freed by other port
701 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
705 case B_EVENT_EXPORTREQUEST:
706 /* special case where the bchannel is requested by remote */
707 if (!p_m_remote_ref) {
708 PERROR("export request without remote channel set, please correct.\n");
713 /* in case, the bchannel is exported right after seize_bchannel */
714 /* export bchannel */
715 /* p_m_remote_id is set, when this event happens. */
716 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);
717 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
718 add_trace("type", NULL, "assign");
719 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
721 state = B_STATE_EXPORTING;
722 mISDNport->b_remote_id[i] = p_m_remote_id;
723 mISDNport->b_remote_ref[i] = p_m_remote_ref;
726 case B_STATE_ACTIVATING:
727 case B_STATE_EXPORTING:
728 /* do nothing, because it is already activating */
731 case B_STATE_DEACTIVATING:
732 case B_STATE_IMPORTING:
733 /* do nothing, because we must wait until we can reactivate */
737 /* bchannel is active, so we deactivate */
738 _bchannel_activate(mISDNport, i, 0, 0);
739 state = B_STATE_DEACTIVATING;
740 timer = B_TIMER_DEACTIVATING;
744 /* problems that might ocurr:
745 * ... when channel already in use.
746 * bchannel exported, but not freed by other port
748 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
752 case B_EVENT_IMPORTREQUEST:
753 /* special case where the bchannel is released by remote */
754 if (p_m_remote_ref) {
755 PERROR("import request with remote channel set, please correct.\n");
761 /* bchannel is not exported */
764 case B_STATE_ACTIVATING:
765 case B_STATE_EXPORTING:
766 /* do nothing because we must wait until bchanenl is active before deactivating */
770 /* bchannel is exported, so we re-import */
771 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
772 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
773 add_trace("type", NULL, "remove");
774 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
776 state = B_STATE_IMPORTING;
779 case B_STATE_DEACTIVATING:
780 case B_STATE_IMPORTING:
781 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
785 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
789 case B_EVENT_ACTIVATED:
792 case B_STATE_ACTIVATING:
793 if (b_port && !p_m_remote_id) {
794 /* bchannel is active and used by Port class, so we configure bchannel */
795 _bchannel_configure(mISDNport, i);
796 state = B_STATE_ACTIVE;
797 b_port->p_m_load = 0;
799 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
800 _bchannel_activate(mISDNport, i, 0, 0);
801 state = B_STATE_DEACTIVATING;
802 timer = B_TIMER_DEACTIVATING;
807 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
811 case B_EVENT_EXPORTED:
813 case B_STATE_EXPORTING:
814 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
815 /* remote export done */
816 state = B_STATE_REMOTE;
818 /* bchannel is now exported, but we need bchannel back
819 * OR bchannel is not used anymore
820 * OR bchannel has been exported to an obsolete ref,
821 * so reimport, to later export to new remote */
822 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
823 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
824 add_trace("type", NULL, "remove");
825 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
827 state = B_STATE_IMPORTING;
832 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
838 FATAL("bchannel must be linked to a Port class\n");
841 /* bchannel is idle due to an error, so we do nothing */
844 case B_STATE_ACTIVATING:
845 case B_STATE_EXPORTING:
846 /* do nothing because we must wait until bchanenl is active before deactivating */
850 /* bchannel is active, so we deactivate */
851 _bchannel_activate(mISDNport, i, 0, 0);
852 state = B_STATE_DEACTIVATING;
853 timer = B_TIMER_DEACTIVATING;
857 /* bchannel is exported, so we re-import */
858 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0, 0);
859 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
860 add_trace("type", NULL, "remove");
861 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
863 state = B_STATE_IMPORTING;
866 case B_STATE_DEACTIVATING:
867 case B_STATE_IMPORTING:
868 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
872 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
876 case B_EVENT_DEACTIVATED:
880 /* ignore due to deactivation confirm after unloading */
883 case B_STATE_DEACTIVATING:
884 _bchannel_destroy(mISDNport, i);
885 state = B_STATE_IDLE;
887 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
888 if (p_m_remote_ref) {
889 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);
890 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
891 add_trace("type", NULL, "assign");
892 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
894 state = B_STATE_EXPORTING;
895 mISDNport->b_remote_id[i] = p_m_remote_id;
896 mISDNport->b_remote_ref[i] = p_m_remote_ref;
898 if (_bchannel_create(mISDNport, i)) {
899 _bchannel_activate(mISDNport, i, 1, 0);
900 state = B_STATE_ACTIVATING;
901 timer = B_TIMER_ACTIVATING;
908 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
912 case B_EVENT_IMPORTED:
914 case B_STATE_IMPORTING:
915 state = B_STATE_IDLE;
916 mISDNport->b_remote_id[i] = 0;
917 mISDNport->b_remote_ref[i] = 0;
919 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
920 if (p_m_remote_ref) {
921 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);
922 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
923 add_trace("type", NULL, "assign");
924 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
926 state = B_STATE_EXPORTING;
927 mISDNport->b_remote_id[i] = p_m_remote_id;
928 mISDNport->b_remote_ref[i] = p_m_remote_ref;
930 if (_bchannel_create(mISDNport, i)) {
931 _bchannel_activate(mISDNport, i, 1, 0);
932 state = B_STATE_ACTIVATING;
933 timer = B_TIMER_ACTIVATING;
940 /* ignore, because not assigned */
945 case B_EVENT_TIMEOUT:
949 /* ignore due to deactivation confirm after unloading */
952 case B_STATE_ACTIVATING:
953 _bchannel_activate(mISDNport, i, 1, 1);
954 timer = B_TIMER_ACTIVATING;
957 case B_STATE_DEACTIVATING:
958 _bchannel_activate(mISDNport, i, 0, 1);
959 timer = B_TIMER_DEACTIVATING;
963 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
968 PERROR("Illegal event %d, please correct.\n", event);
971 mISDNport->b_state[i] = state;
973 unsched_timer(&mISDNport->b_timer[i]);
975 schedule_timer(&mISDNport->b_timer[i], timer, 0);
982 * check for available channel and reserve+set it.
983 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
985 * returns -(cause value) or x = channel x or 0 = no channel
986 * NOTE: no activation is done here
988 int PmISDN::seize_bchannel(int channel, int exclusive)
992 /* the channel is what we have */
993 if (p_m_b_channel == channel)
996 /* if channel already in use, release it */
1001 if (channel==CHANNEL_NO || channel==0)
1004 /* is channel in range ? */
1006 || (channel>p_m_mISDNport->b_num && channel<16)
1007 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1008 return(-6); /* channel unacceptable */
1010 /* request exclusive channel */
1011 if (exclusive && channel>0) {
1012 i = channel-1-(channel>16);
1013 if (p_m_mISDNport->b_port[i])
1014 return(-44); /* requested channel not available */
1018 /* ask for channel */
1020 i = channel-1-(channel>16);
1021 if (p_m_mISDNport->b_port[i] == NULL)
1025 /* search for channel */
1027 while(i < p_m_mISDNport->b_num) {
1028 if (!p_m_mISDNport->b_port[i]) {
1029 channel = i+1+(i>=15);
1034 return(-34); /* no free channel */
1037 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1039 /* link Port, set parameters */
1040 p_m_mISDNport->b_port[i] = this;
1042 p_m_b_channel = channel;
1043 p_m_b_exclusive = exclusive;
1044 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1046 /* reserve channel */
1047 if (!p_m_b_reserve) {
1049 p_m_mISDNport->b_reserved++;
1056 * drop reserved channel and unset it.
1057 * deactivation is also done
1059 void PmISDN::drop_bchannel(void)
1061 /* unreserve channel */
1063 p_m_mISDNport->b_reserved--;
1067 if (p_m_b_index < 0)
1072 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1074 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1075 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1076 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1077 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1080 p_m_b_exclusive = 0;
1083 /* process bchannel export/import message from join */
1084 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1086 class Endpoint *epoint;
1088 class PmISDN *isdnport;
1089 struct mISDNport *mISDNport;
1093 case BCHANNEL_REQUEST:
1094 /* find the port object for the join object ref */
1095 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1096 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1099 if (!epoint->ep_portlist) {
1100 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1103 if (epoint->ep_portlist->next) {
1104 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);
1106 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1107 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1110 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1111 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1113 isdnport = (class PmISDN *)port;
1116 if (isdnport->p_m_remote_id) {
1117 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1120 mISDNport = isdnport->p_m_mISDNport;
1121 i = isdnport->p_m_b_index;
1122 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1123 add_trace("type", NULL, "export request");
1125 isdnport->p_m_remote_ref = joinremote->j_remote_ref;
1126 isdnport->p_m_remote_id = joinremote->j_remote_id;
1127 if (mISDNport && i>=0) {
1128 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1132 case BCHANNEL_RELEASE:
1133 case BCHANNEL_ASSIGN_ACK:
1134 case BCHANNEL_REMOVE_ACK:
1135 /* find mISDNport for stack ID */
1136 mISDNport = mISDNport_first;
1139 ii = mISDNport->b_num;
1141 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1147 mISDNport = mISDNport->next;
1150 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1154 if (type!=BCHANNEL_RELEASE) {
1156 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1157 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1159 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1162 isdnport = mISDNport->b_port[i];
1163 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1164 add_trace("type", NULL, "import request");
1167 isdnport->p_m_remote_ref = 0;
1168 isdnport->p_m_remote_id = 0;
1170 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1174 PERROR("received wrong bchannel message type %d from remote\n", type);
1182 audio transmission procedure:
1183 -----------------------------
1186 three sources of audio transmission:
1187 - crypto-data high priority
1188 - tones high priority (also high)
1189 - remote-data low priority
1192 a variable that temporarily shows the number of samples elapsed since last transmission process.
1193 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1196 a variable that is increased whenever data is transmitted.
1197 it is decreased while time elapses. it stores the number of samples that
1198 are currently loaded to dsp module.
1199 since clock in dsp module is the same clock for user space process, these
1203 there are two levels:
1204 ISDN_LOAD will give the load that have to be kept in dsp.
1205 ISDN_MAXLOAD will give the maximum load before dropping.
1207 * procedure for low priority data
1208 see txfromup() for procedure
1209 in short: remote data is ignored during high priority tones
1211 * procedure for high priority data
1212 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1213 if no more data is available, load becomes empty again.
1216 0 ISDN_LOAD ISDN_MAXLOAD
1217 +--------------------+----------------------+
1219 +--------------------+----------------------+
1221 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1222 0 ISDN_LOAD ISDN_MAXLOAD
1223 +--------------------+----------------------+
1224 |TTTTTTTTTTTTTTTTTTTT| |
1225 +--------------------+----------------------+
1227 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1228 0 ISDN_LOAD ISDN_MAXLOAD
1229 +--------------------+----------------------+
1230 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1231 +--------------------+----------------------+
1234 void PmISDN::update_load(void)
1236 /* don't trigger load event if: */
1237 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1240 /* don't trigger load event if event already active */
1241 if (p_m_loadtimer.active)
1244 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1247 int load_timer(struct lcr_timer *timer, void *instance, int index)
1249 class PmISDN *isdnport = (class PmISDN *)instance;
1251 isdnport->load_tx();
1256 void PmISDN::load_tx(void)
1260 struct timeval current_time;
1263 gettimeofday(¤t_time, NULL);
1264 if (p_m_last_tv_sec) {
1265 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1266 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1268 /* set clock of last process! */
1269 p_m_last_tv_sec = current_time.tv_sec;
1270 p_m_last_tv_msec = current_time.tv_usec/1000;
1272 /* process only if we have samples and we are active */
1273 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1275 if (elapsed < p_m_load)
1276 p_m_load -= elapsed;
1280 /* to send data, tone must be on */
1281 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1282 && (p_m_load < ISDN_LOAD) /* not too much load? */
1283 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1284 int tosend = ISDN_LOAD - p_m_load, length;
1285 unsigned char buf[MISDN_HEADER_LEN+tosend];
1286 struct mISDNhead *frm = (struct mISDNhead *)buf;
1287 unsigned char *p = buf+MISDN_HEADER_LEN;
1289 /* copy inband signalling (e.g. used by ss5) */
1290 if (p_m_inband_send_on && tosend) {
1291 tosend -= inband_send(p, tosend);
1294 /* copy crypto loops */
1295 while (p_m_crypt_msg_loops && tosend) {
1296 /* how much do we have to send */
1297 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1300 if (length > tosend)
1303 /* copy message (part) to buffer */
1304 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1307 p_m_crypt_msg_current += length;
1308 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1310 p_m_crypt_msg_current = 0;
1311 p_m_crypt_msg_loops--;
1312 if (!p_m_crypt_msg_loops)
1314 // puts("eine loop weniger");
1322 if (p_tone_name[0] && tosend) {
1323 tosend -= read_audio(p, tosend);
1327 if (ISDN_LOAD - p_m_load - tosend > 0) {
1328 frm->prim = PH_DATA_REQ;
1330 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);
1332 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);
1333 p_m_load += ISDN_LOAD - p_m_load - tosend;
1338 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1339 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
1343 /* handle timeouts */
1344 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1346 class PmISDN *isdnport = (class PmISDN *)instance;
1347 struct lcr_msg *message;
1349 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);
1350 /* send timeout to endpoint */
1351 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1352 message->param.state = isdnport->p_state;
1353 message_put(message);
1360 * whenever we get audio data from bchannel, we process it here
1362 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1364 unsigned int cont = *((unsigned int *)data);
1365 unsigned char *data_temp;
1366 unsigned int length_temp;
1367 struct lcr_msg *message;
1371 if (hh->prim == PH_CONTROL_IND) {
1373 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1376 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1377 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1378 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1380 add_trace("info", NULL, "DTMF is disabled");
1384 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1385 message->param.dtmf = cont & DTMF_TONE_MASK;
1386 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1387 message_put(message);
1392 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1393 add_trace("DSP-CRYPT", NULL, "error");
1395 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1396 message->param.crypt.type = CC_ERROR_IND;
1397 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1398 message_put(message);
1402 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1403 add_trace("DSP-CRYPT", NULL, "ok");
1405 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1406 message->param.crypt.type = CC_ACTBF_CONF;
1407 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1408 message_put(message);
1412 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1413 add_trace("unknown", NULL, "0x%x", cont);
1418 if (hh->prim == PH_CONTROL_IND) {
1421 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1422 add_trace("unknown", NULL, "0x%x", hh->id);
1427 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1429 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1430 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1433 /* see below (same condition) */
1434 if (p_state!=PORT_STATE_CONNECT
1435 && !p_m_mISDNport->tones)
1437 // printf(".");fflush(stdout);return;
1439 record(data, len, 1); // from up
1442 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1443 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1447 /* inband is processed */
1448 if (p_m_inband_receive_on)
1449 inband_receive(data, len);
1451 /* calls will not process any audio data unless
1452 * the call is connected OR tones feature is enabled.
1454 #ifndef DEBUG_COREBRIDGE
1455 if (p_state!=PORT_STATE_CONNECT
1456 && !p_m_mISDNport->tones)
1461 /* the bearer capability must be audio in order to send and receive
1462 * audio prior or after connect.
1464 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1468 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1470 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1476 record(data, len, 0); // from down
1478 /* randomize and listen to crypt message if enabled */
1479 if (p_m_crypt_listen) {
1480 /* the noisy randomizer */
1484 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1486 cryptman_listen_bch(data, len);
1491 /* send data to epoint */
1492 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1495 while(length_temp) {
1496 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1497 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1498 memcpy(message->param.data.data, data_temp, message->param.data.len);
1499 message_put(message);
1500 if (length_temp <= sizeof(message->param.data.data))
1502 data_temp += sizeof(message->param.data.data);
1503 length_temp -= sizeof(message->param.data.data);
1512 void PmISDN::set_echotest(int echo)
1514 if (p_m_echo != echo) {
1516 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1518 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1519 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);
1526 void PmISDN::set_tone(const char *dir, const char *tone)
1531 /* if no directory is given (by extension), we use interface.conf or options.conf */
1532 if (!dir || !dir[0]) {
1533 if (p_m_mISDNport->ifport->tones_dir[0])
1534 dir = p_m_mISDNport->ifport->tones_dir;
1535 else if (options.tones_dir[0])
1536 dir = options.tones_dir;
1541 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1547 /* check for dsp tones */
1548 if (!strcmp(dir, "american"))
1550 if (!strcmp(dir, "german"))
1552 if (!strcmp(dir, "oldgerman"))
1553 dsp = DSP_OLDGERMAN;
1555 /* check if we NOT really have to use a dsp-tone */
1556 if (dsp == DSP_NONE) {
1559 if (p_m_b_index > -1)
1560 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) {
1561 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1562 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1565 Port::set_tone(dir, tone);
1569 /* now we USE dsp-tone, convert name */
1570 if (!strcmp(tone, "dialtone")) {
1572 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1573 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1574 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1576 } else if (!strcmp(tone, "dialpbx")) {
1578 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1579 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1580 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1582 } else if (!strcmp(tone, "ringing")) {
1584 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1585 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1586 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1588 } else if (!strcmp(tone, "ringpbx")) {
1590 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1591 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1592 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1594 } else if (!strcmp(tone, "busy")) {
1597 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1598 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1599 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1601 } else if (!strcmp(tone, "release")) {
1604 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1605 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1606 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1608 } else if (!strcmp(tone, "cause_10"))
1610 else if (!strcmp(tone, "cause_11"))
1612 else if (!strcmp(tone, "cause_22")) {
1614 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1615 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1616 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1618 } else if (!strncmp(tone, "cause_", 6))
1619 id = TONE_SPECIAL_INFO;
1623 /* if we have a tone that is not supported by dsp */
1624 if (id==TONE_OFF && tone[0])
1628 if (p_m_tone != id) {
1631 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1632 if (p_m_b_index > -1)
1633 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)
1634 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);
1636 /* turn user-space tones off in cases of no tone OR dsp tone */
1637 Port::set_tone("",NULL);
1641 /* MESSAGE_mISDNSIGNAL */
1642 //extern struct lcr_msg *dddebug;
1643 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1645 int oldconf, newconf;
1646 switch(param->mISDNsignal.message) {
1647 case mISDNSIGNAL_VOLUME:
1648 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1649 p_m_tx_gain = param->mISDNsignal.tx_gain;
1650 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1651 if (p_m_b_index > -1)
1652 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)
1653 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);
1655 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1656 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1657 p_m_rx_gain = param->mISDNsignal.rx_gain;
1658 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1659 if (p_m_b_index > -1)
1660 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)
1661 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);
1663 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1666 case mISDNSIGNAL_CONF:
1667 oldconf = p_m_mute?0:p_m_conf;
1668 p_m_conf = param->mISDNsignal.conf;
1669 newconf = p_m_mute?0:p_m_conf;
1670 set_conf(oldconf, newconf);
1673 case mISDNSIGNAL_JOINDATA:
1674 if (p_m_joindata != param->mISDNsignal.joindata) {
1675 p_m_joindata = param->mISDNsignal.joindata;
1676 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1679 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1682 case mISDNSIGNAL_DELAY:
1683 if (p_m_delay != param->mISDNsignal.delay) {
1684 p_m_delay = param->mISDNsignal.delay;
1685 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1686 if (p_m_b_index > -1)
1687 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)
1688 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);
1690 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1694 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1699 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1701 struct lcr_msg *message;
1703 switch(param->crypt.type) {
1704 case CC_ACTBF_REQ: /* activate blowfish */
1706 p_m_crypt_key_len = param->crypt.len;
1707 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1708 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1709 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1710 message->param.crypt.type = CC_ERROR_IND;
1711 message_put(message);
1714 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1716 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1717 if (p_m_b_index > -1)
1718 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)
1719 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);
1722 case CC_DACT_REQ: /* deactivate session encryption */
1727 case CR_LISTEN_REQ: /* start listening to messages */
1728 p_m_crypt_listen = 1;
1730 p_m_crypt_listen_state = 0;
1733 case CR_UNLISTEN_REQ: /* stop listening to messages */
1734 p_m_crypt_listen = 0;
1738 case CR_MESSAGE_REQ: /* send message */
1739 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1740 if (!p_m_crypt_msg_len) {
1741 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1744 p_m_crypt_msg_current = 0; /* reset */
1745 p_m_crypt_msg_loops = 6; /* enable */
1749 /* disable txmix, or we get corrupt data due to audio process */
1750 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1751 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1752 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1758 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1764 * endpoint sends messages to the port
1766 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1768 if (Port::message_epoint(epoint_id, message_id, param))
1771 switch(message_id) {
1772 case MESSAGE_DATA: /* tx-data from upper layer */
1773 txfromup(param->data.data, param->data.len);
1776 case MESSAGE_mISDNSIGNAL: /* user command */
1777 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1778 message_mISDNsignal(epoint_id, message_id, param);
1781 case MESSAGE_CRYPT: /* crypt control command */
1782 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1783 message_crypt(epoint_id, message_id, param);
1790 void PmISDN::update_rxoff(void)
1792 /* call bridges in user space OR crypto OR recording */
1793 if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1794 /* rx IS required */
1798 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1799 if (p_m_b_index > -1)
1800 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1801 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1804 /* rx NOT required */
1808 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1809 if (p_m_b_index > -1)
1810 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1811 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1816 /* txdata IS required */
1820 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1821 if (p_m_b_index > -1)
1822 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1823 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1826 /* txdata NOT required */
1830 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1831 if (p_m_b_index > -1)
1832 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1833 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1838 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1840 struct mISDNport *mISDNport;
1846 /* unset global semaphore */
1848 // with a very small incident, upqueue_avail may be set by mISDN thread and
1849 // another byte may be sent to the pipe, which causes a call to this function
1850 // again with nothing in the upqueue. this is no problem.
1851 ret = read(fd->fd, &byte, 1);
1853 /* process all ports */
1854 mISDNport = mISDNport_first;
1856 /* handle queued up-messages (d-channel) */
1857 if (!mISDNport->isloopback) {
1858 while ((mb = mdequeue(&mISDNport->upqueue))) {
1861 case MPH_ACTIVATE_IND:
1862 if (mISDNport->l1link != 1) {
1863 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1865 mISDNport->l1link = 1;
1869 case MPH_DEACTIVATE_IND:
1870 if (mISDNport->l1link != 0) {
1871 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1873 mISDNport->l1link = 0;
1877 case MPH_INFORMATION_IND:
1878 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1880 case L1_SIGNAL_LOS_ON:
1883 case L1_SIGNAL_LOS_OFF:
1886 case L1_SIGNAL_AIS_ON:
1889 case L1_SIGNAL_AIS_OFF:
1892 case L1_SIGNAL_RDI_ON:
1895 case L1_SIGNAL_RDI_OFF:
1898 case L1_SIGNAL_SLIP_TX:
1899 mISDNport->slip_tx++;
1901 case L1_SIGNAL_SLIP_RX:
1902 mISDNport->slip_rx++;
1907 case MT_L2ESTABLISH:
1908 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1909 add_trace("tei", NULL, "%d", l3m->pid);
1911 mISDNport->l2link = 1;
1913 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1914 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1915 if (mISDNport->l2establish.active) {
1916 unsched_timer(&mISDNport->l2establish);
1917 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1924 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1925 if (!mISDNport->l2establish.active) {
1926 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1927 add_trace("tei", NULL, "%d", l3m->pid);
1929 /* down if not nt-ptmp */
1930 if (!mISDNport->ntmode || mISDNport->ptp)
1931 mISDNport->l2link = 0;
1933 if (!mISDNport->isloopback && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1934 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1935 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1936 schedule_timer(&mISDNport->l2establish, 5, 0);
1937 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1943 /* l3-data is sent to LCR */
1944 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1950 mISDNport = mISDNport->next;
1955 /* l2 establish timer fires */
1956 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1958 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1960 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1961 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1962 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1963 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1969 /* handle frames from bchannel */
1970 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1972 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1973 unsigned char buffer[2048+MISDN_HEADER_LEN];
1974 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1977 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1979 PERROR("read error frame, errno %d\n", errno);
1982 if (ret < (int)MISDN_HEADER_LEN) {
1983 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1987 /* we don't care about confirms, we use rx data to sync tx */
1991 /* we receive audio data, we respond to it AND we send tones */
1996 case PH_CONTROL_IND:
1997 if (mISDNport->b_port[i])
1998 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
2000 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
2003 case PH_ACTIVATE_IND:
2004 case DL_ESTABLISH_IND:
2005 case PH_ACTIVATE_CNF:
2006 case DL_ESTABLISH_CNF:
2007 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
2008 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2011 case PH_DEACTIVATE_IND:
2012 case DL_RELEASE_IND:
2013 case PH_DEACTIVATE_CNF:
2014 case DL_RELEASE_CNF:
2015 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2016 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2020 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2026 /* process timer events for bchannel handling */
2027 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2029 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2032 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2038 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2042 * l3m must be queued, except for MT_ASSIGN
2045 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2048 /* special MT_ASSIGN handling:
2050 * if we request a PID from mlayer, we always do it while lcr is locked.
2051 * therefore we must check the MT_ASSIGN reply first before we lock.
2052 * this is because the MT_ASSIGN reply is received with the requesting
2053 * process, not by the mlayer thread!
2054 * this means, that the reply is sent during call of the request.
2055 * we must check if we get a reply and we know that we lcr is currently
2058 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2059 /* let's do some checking if someone changes stack behaviour */
2060 if (mt_assign_pid != 0)
2061 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2062 mt_assign_pid = pid;
2065 /* queue message, create, if required */
2067 l3m = alloc_l3_msg();
2069 FATAL("No memory for layer 3 message\n");
2071 mb = container_of(l3m, struct mbuffer, l3);
2074 mqueue_tail(&mISDNport->upqueue, mb);
2075 if (!upqueue_avail) {
2076 // multiple threads may cause multiple calls of this section, but this
2077 // results only in multiple processing of the upqueue read.
2078 // this is no problem.
2082 ret = write(upqueue_pipe[1], &byte, 1);
2087 int mISDN_getportbyname(int sock, int cnt, char *portname)
2089 struct mISDN_devinfo devinfo;
2093 while (port < cnt) {
2095 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2098 if (!strcasecmp(devinfo.name, portname))
2109 * global function to add a new card (port)
2111 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2114 struct mISDNport *mISDNport, **mISDNportp;
2115 int port = ifport->portnum;
2116 int ptp = ifport->ptp;
2117 int force_nt = ifport->nt;
2118 int l1hold = ifport->l1hold;
2119 int l2hold = ifport->l2hold;
2121 int ss5 = ifport->ss5;
2125 // struct mlayer3 *ml3;
2126 struct mISDN_devinfo devinfo;
2127 unsigned int protocol, prop;
2129 #if defined WITH_GSM_BS && defined WITH_GSM_MS
2130 loop = ifport->gsm_ms | ifport->gsm_bs;
2133 loop = ifport->gsm_bs;
2136 loop = ifport->gsm_ms;
2139 //printf("%s == %s\n", ifport->portname, options.loopback_int);
2140 if (!strcmp(ifport->portname, options.loopback_lcr))
2144 if (mISDNloop_open())
2148 /* check port counts */
2149 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2151 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2156 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2160 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2163 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface?.\n", ifport->portname);
2165 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2168 // note: 'port' has still the port number
2170 if (port>cnt || port<0) {
2171 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2175 /* get port attributes */
2176 pri = bri = pots = nt = te = 0;
2178 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2180 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2183 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2187 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2191 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2195 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2200 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2206 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2211 if (force_nt && !nt) {
2212 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2216 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2219 if (pots && !bri && !pri) {
2220 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2224 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2228 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2231 /* set NT by turning off TE */
2234 /* if TE an NT is supported (and not forced to NT), turn off NT */
2238 /* check for double use of port */
2240 mISDNport = mISDNport_first;
2242 if (mISDNport->portnum == port)
2244 mISDNport = mISDNport->next;
2247 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2252 /* check for continous channelmap with no bchannel on slot 16 */
2253 if (test_channelmap(0, devinfo.channelmap)) {
2254 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2258 while(i < (int)devinfo.nrbchan + 1) {
2260 if (test_channelmap(i, devinfo.channelmap)) {
2261 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2265 if (!test_channelmap(i, devinfo.channelmap)) {
2266 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2273 /* add mISDNport structure */
2274 mISDNportp = &mISDNport_first;
2276 mISDNportp = &((*mISDNportp)->next);
2277 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2278 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2280 /* loop/ss5 link is always active */
2281 mISDNport->l1link = 1;
2282 mISDNport->l2link = 1;
2284 mISDNport->l1link = -1;
2285 mISDNport->l2link = -1;
2288 mISDNport->gsm_bs = ifport->gsm_bs;
2291 mISDNport->gsm_ms = ifport->gsm_ms;
2293 mISDNport->isloopback = loop;
2295 *mISDNportp = mISDNport;
2297 /* if pri, must set PTP */
2301 /* set ss5 params */
2303 /* try to keep interface enabled */
2323 /* allocate ressources of port */
2324 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2325 prop = (1 << MISDN_FLG_L2_CLEAN);
2326 if (ptp) // ptp forced
2327 prop |= (1 << MISDN_FLG_PTP);
2328 if (nt) // supports hold/retrieve on nt-mode
2329 prop |= (1 << MISDN_FLG_NET_HOLD);
2330 if (l1hold) // supports layer 1 hold
2331 prop |= (1 << MISDN_FLG_L1_HOLD);
2332 if (l2hold) // supports layer 2 hold
2333 prop |= (1 << MISDN_FLG_L2_HOLD);
2334 /* open layer 3 and init upqueue */
2336 unsigned long on = 1;
2337 struct sockaddr_mISDN addr;
2339 if (devinfo.nrbchan < 8) {
2340 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);
2341 // mISDNport_close(mISDNport);
2345 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, (bri) ? ISDN_P_TE_S0 : ISDN_P_TE_E1)) < 0) {
2346 PERROR_RUNTIME("loop port %d failed to open socket.\n", port);
2347 mISDNport_close(mISDNport);
2350 /* set nonblocking io */
2351 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2352 PERROR_RUNTIME("loop port %d failed to set socket into nonblocking io.\n", port);
2353 mISDNport_close(mISDNport);
2356 /* bind socket to dchannel */
2357 memset(&addr, 0, sizeof(addr));
2358 addr.family = AF_ISDN;
2361 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2362 PERROR_RUNTIME("loop port %d failed to bind socket. (errno %d)\n", port, errno);
2363 mISDNport_close(mISDNport);
2367 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2368 mqueue_init(&mISDNport->upqueue);
2369 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2370 if (!mISDNport->ml3) {
2371 mqueue_purge(&mISDNport->upqueue);
2372 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2380 "PORT (open failed)");
2382 mISDNport_close(mISDNport);
2387 SCPY(mISDNport->name, devinfo.name);
2388 mISDNport->b_num = devinfo.nrbchan;
2389 mISDNport->portnum = port;
2390 mISDNport->ntmode = nt;
2391 mISDNport->tespecial = ifport->tespecial;
2392 mISDNport->pri = pri;
2393 mISDNport->ptp = ptp;
2394 mISDNport->l1hold = l1hold;
2395 mISDNport->l2hold = l2hold;
2396 mISDNport->ss5 = ss5;
2397 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2399 while(i < mISDNport->b_num) {
2400 mISDNport->b_state[i] = B_STATE_IDLE;
2401 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2405 /* if ptp, pull up the link */
2406 if (!mISDNport->isloopback && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2407 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2408 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2409 add_trace("tei", NULL, "%d", 0);
2411 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2414 /* for nt-mode ptmp the link is always up */
2415 if (mISDNport->ntmode && !mISDNport->ptp)
2416 mISDNport->l2link = 1;
2418 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2420 start_trace(mISDNport->portnum,
2428 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2429 add_trace("channels", NULL, "%d", mISDNport->b_num);
2431 add_trace("ccitt#5", NULL, "enabled");
2439 * load static port instances, if required by mISDNport
2441 void mISDNport_static(struct mISDNport *mISDNport)
2446 while(i < mISDNport->b_num) {
2449 ss5_create_channel(mISDNport, i);
2457 * function to free ALL cards (ports)
2459 void mISDNport_close_all(void)
2461 /* free all ports */
2462 while(mISDNport_first)
2463 mISDNport_close(mISDNport_first);
2467 * free only one port
2469 void mISDNport_close(struct mISDNport *mISDNport)
2471 struct mISDNport **mISDNportp;
2473 class PmISDN *isdnport;
2476 /* remove all port instance that are linked to this mISDNport */
2480 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2481 isdnport = (class PmISDN *)port;
2482 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2483 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2491 /* only if we are already part of interface */
2492 if (mISDNport->ifport) {
2493 start_trace(mISDNport->portnum,
2494 mISDNport->ifport->interface,
2504 /* free bchannels */
2506 while(i < mISDNport->b_num) {
2507 if (mISDNport->b_sock[i].inuse) {
2508 _bchannel_destroy(mISDNport, i);
2509 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2511 if (mISDNport->b_timer[i].inuse) {
2512 del_timer(&mISDNport->b_timer[i]);
2516 del_timer(&mISDNport->l2establish);
2518 /* close layer 3, if open */
2519 if (!mISDNport->isloopback && mISDNport->ml3) {
2520 close_layer3(mISDNport->ml3);
2523 /* close gsm socket, if open */
2524 if (mISDNport->isloopback && mISDNport->lcr_sock > -1) {
2525 close(mISDNport->lcr_sock);
2529 if (!mISDNport->isloopback)
2530 mqueue_purge(&mISDNport->upqueue);
2532 /* remove from list */
2533 mISDNportp = &mISDNport_first;
2534 while(*mISDNportp) {
2535 if (*mISDNportp == mISDNport) {
2536 *mISDNportp = (*mISDNportp)->next;
2540 mISDNportp = &((*mISDNportp)->next);
2544 FATAL("mISDNport not in list\n");
2546 FREE(mISDNport, sizeof(struct mISDNport));
2553 * enque data from upper buffer
2555 void PmISDN::txfromup(unsigned char *data, int length)
2557 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2558 struct mISDNhead *hh = (struct mISDNhead *)buf;
2561 if (p_m_b_index < 0)
2563 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2566 /* check if high priority tones exist
2567 * ignore data in this case
2569 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2572 /* preload procedure
2573 * if transmit buffer in DSP module is empty,
2574 * preload it to DSP_LOAD to prevent jitter gaps.
2576 if (p_m_load == 0 && ISDN_LOAD > 0) {
2577 hh->prim = PH_DATA_REQ;
2579 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2580 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2582 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2583 p_m_load += ISDN_LOAD;
2584 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2587 /* drop if load would exceed ISDN_MAXLOAD
2588 * this keeps the delay not too high
2590 if (p_m_load+length > ISDN_MAXLOAD)
2593 /* make and send frame */
2594 hh->prim = PH_DATA_REQ;
2596 memcpy(buf+MISDN_HEADER_LEN, data, length);
2597 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2599 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2603 int PmISDN::inband_send(unsigned char *buffer, int len)
2605 PERROR("this function must be derived to function!\n");
2609 void PmISDN::inband_send_on(void)
2611 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2612 p_m_inband_send_on = 1;
2613 /* trigger inband transmit */
2617 void PmISDN::inband_send_off(void)
2619 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2620 p_m_inband_send_on = 0;
2623 void PmISDN::inband_receive(unsigned char *buffer, int len)
2626 // if (len >= SS5_DECODER_NPOINTS)
2627 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2628 PERROR("this function must be derived to function!\n");
2631 void PmISDN::inband_receive_on(void)
2633 /* this must work during constructor, see ss5.cpp */
2634 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2635 p_m_inband_receive_on = 1;
2639 void PmISDN::inband_receive_off(void)
2641 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2642 p_m_inband_receive_on = 0;
2646 void PmISDN::mute_on(void)
2650 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2652 set_conf(p_m_conf, 0);
2655 void PmISDN::mute_off(void)
2659 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2661 set_conf(0, p_m_conf);