1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
16 #define MISDN_OLD_AF_COMPATIBILITY 1
17 #include <compat_af_isdn.h>
22 #ifdef __compiler_offsetof
23 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
25 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
29 #define container_of(ptr, type, member) ({ \
30 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
31 (type *)( (char *)__mptr - offsetof(type,member) );})
34 // timeouts if activating/deactivating response from mISDN got lost
35 #define B_TIMER_ACTIVATING 1 // seconds
36 #define B_TIMER_DEACTIVATING 1 // seconds
38 /* list of mISDN ports */
39 struct mISDNport *mISDNport_first;
41 /* noise randomizer */
42 unsigned char mISDN_rand[256];
43 int mISDN_rand_count = 0;
45 unsigned int mt_assign_pid = ~0;
48 static int upqueue_pipe[2];
49 static struct lcr_fd upqueue_fd;
50 int upqueue_avail = 0;
52 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
53 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
55 int mISDN_initialize(void)
61 /* try to open raw socket to check kernel */
62 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
63 if (mISDNsocket < 0) {
64 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
69 init_layer3(4); // buffer of 4
71 /* open debug, if enabled and not only stack debugging */
73 SPRINT(filename, "%s/debug.log", LOG_DIR);
74 debug_fp = fopen(filename, "a");
77 if (options.deb & DEBUG_STACK) {
78 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
79 mISDN_debug_init(0xfffffeff, filename, filename, filename);
81 mISDN_debug_init(0, NULL, NULL, NULL);
83 if (pipe(upqueue_pipe) < 0)
84 FATAL("Failed to open pipe\n");
85 memset(&upqueue_fd, 0, sizeof(upqueue_fd.fd));
86 upqueue_fd.fd = upqueue_pipe[0];
87 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
92 void mISDN_deinitialize(void)
102 if (mISDNsocket > -1)
105 if (upqueue_fd.inuse) {
106 unregister_fd(&upqueue_fd);
107 close(upqueue_pipe[0]);
108 close(upqueue_pipe[1]);
113 int load_timer(struct lcr_timer *timer, void *instance, int index);
118 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
120 p_m_mISDNport = mISDNport;
121 p_m_portnum = mISDNport->portnum;
128 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
129 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
138 p_m_inband_send_on = 0;
139 p_m_inband_receive_on = 0;
140 p_m_dtmf = !mISDNport->ifport->nodtmf;
141 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
142 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
143 p_m_remote_ref = 0; /* channel shall be exported to given remote */
144 p_m_remote_id = 0; /* remote admin socket */
145 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
148 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
149 add_timer(&p_m_loadtimer, load_timer, this, 0);
155 p_m_crypt_listen = 0;
156 p_m_crypt_msg_loops = 0;
157 p_m_crypt_msg_loops = 0;
158 p_m_crypt_msg_len = 0;
159 p_m_crypt_msg[0] = '\0';
160 p_m_crypt_msg_current = 0;
161 p_m_crypt_key_len = 0;
162 p_m_crypt_listen = 0;
163 p_m_crypt_listen_state = 0;
164 p_m_crypt_listen_len = 0;
165 p_m_crypt_listen_msg[0] = '\0';
166 p_m_crypt_listen_crc = 0;
167 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
168 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
169 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
173 /* if any channel requested by constructor */
174 if (channel == CHANNEL_ANY) {
175 /* reserve channel */
177 mISDNport->b_reserved++;
180 /* reserve channel */
181 if (channel > 0) // only if constructor was called with a channel resevation
182 seize_bchannel(channel, exclusive);
184 /* we increase the number of objects: */
186 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
187 //inband_receive_on();
196 struct lcr_msg *message;
198 del_timer(&p_m_timeout);
199 del_timer(&p_m_loadtimer);
201 /* remove bchannel relation */
205 while (p_epointlist) {
206 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
207 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
208 message->param.disconnectinfo.cause = 16;
209 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
210 message_put(message);
211 /* remove from list */
212 free_epointlist(p_epointlist);
215 /* we decrease the number of objects: */
216 p_m_mISDNport->use--;
217 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
224 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
226 /* init trace with given values */
227 start_trace(mISDNport?mISDNport->portnum:-1,
228 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
229 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
230 port?port->p_dialinginfo.id:NULL,
233 port?port->p_serial:0,
241 static struct isdn_message {
245 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
246 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
247 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
248 {"DL_RELEASE", L2_RELEASE_REQ},
249 {"UNKNOWN", L3_UNKNOWN_REQ},
250 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
251 {"MT_SETUP", L3_SETUP_REQ},
252 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
253 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
254 {"MT_ALERTING", L3_ALERTING_REQ},
255 {"MT_CONNECT", L3_CONNECT_REQ},
256 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
257 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
258 {"MT_RELEASE", L3_RELEASE_REQ},
259 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
260 {"MT_INFORMATION", L3_INFORMATION_REQ},
261 {"MT_PROGRESS", L3_PROGRESS_REQ},
262 {"MT_NOTIFY", L3_NOTIFY_REQ},
263 {"MT_SUSPEND", L3_SUSPEND_REQ},
264 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
265 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
266 {"MT_RESUME", L3_RESUME_REQ},
267 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
268 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
269 {"MT_HOLD", L3_HOLD_REQ},
270 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
271 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
272 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
273 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
274 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
275 {"MT_FACILITY", L3_FACILITY_REQ},
276 {"MT_STATUS", L3_STATUS_REQ},
277 {"MT_RESTART", L3_RESTART_REQ},
278 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
279 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
282 static const char *isdn_prim[4] = {
288 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
293 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
294 /* select message and primitive text */
296 while(isdn_message[i].name) {
297 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
298 if (isdn_message[i].value == (msg&0xffffff00)) {
299 SCPY(msgtext, isdn_message[i].name);
304 SCAT(msgtext, isdn_prim[msg&0x00000003]);
307 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
309 if (mISDNport->ntmode) {
310 if (direction == DIRECTION_OUT)
311 SCAT(msgtext, " N->U");
313 SCAT(msgtext, " N<-U");
315 if (direction == DIRECTION_OUT)
316 SCAT(msgtext, " U->N");
318 SCAT(msgtext, " U<-N");
323 /* init trace with given values */
324 start_trace(mISDNport?mISDNport->portnum:-1,
325 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
326 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
327 port?port->p_dialinginfo.id:NULL,
330 port?port->p_serial:0,
336 * send control information to the channel (dsp-module)
338 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
340 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
341 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
342 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
348 ctrl->prim = PH_CONTROL_REQ;
352 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
354 PERROR("Failed to send to socket %d\n", sock);
355 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
356 if (c1 == DSP_CONF_JOIN)
357 add_trace(trace_name, NULL, "0x%08x", trace_value);
359 add_trace(trace_name, NULL, "%d", trace_value);
363 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)
365 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
366 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
367 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
373 ctrl->prim = PH_CONTROL_REQ;
376 memcpy(d, c2, c2_len);
377 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
379 PERROR("Failed to send to socket %d\n", sock);
380 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
381 add_trace(trace_name, NULL, "%d", trace_value);
385 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
388 * subfunction for bchannel_event
391 static int _bchannel_create(struct mISDNport *mISDNport, int i)
394 struct sockaddr_mISDN addr;
396 if (mISDNport->b_sock[i].inuse) {
397 PERROR("Error: Socket already created for index %d\n", i);
402 //#warning testing without DSP
403 // 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);
404 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);
405 if (mISDNport->b_sock[i].fd < 0) {
406 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
410 /* register callback for read */
411 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
413 /* bind socket to bchannel */
414 addr.family = AF_ISDN;
415 addr.dev = mISDNport->portnum;
416 addr.channel = i+1+(i>=15);
417 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
419 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);
420 close(mISDNport->b_sock[i].fd);
421 unregister_fd(&mISDNport->b_sock[i]);
425 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
426 add_trace("channel", NULL, "%d", i+1+(i>=15));
427 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
435 * subfunction for bchannel_event
436 * activate / deactivate request
438 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
440 struct mISDNhead act;
443 if (!mISDNport->b_sock[i].inuse)
445 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
447 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
449 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
452 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
453 add_trace("channel", NULL, "%d", i+1+(i>=15));
455 add_trace("event", NULL, "timeout recovery");
461 * subfunction for bchannel_event
464 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
469 if (!mISDNport->b_sock[i].inuse)
471 handle = mISDNport->b_sock[i].fd;
472 port = mISDNport->b_port[i];
473 mode = mISDNport->b_mode[i];
475 PERROR("bchannel index i=%d not associated with a port object\n", i);
479 /* set dsp features */
480 if (port->p_m_txdata)
481 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
482 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
483 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
484 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
485 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
486 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
487 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
488 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
489 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
490 if (port->p_m_conf && !port->p_m_mute)
491 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
493 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
494 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
495 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
497 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
498 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
499 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
500 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
501 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
502 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
503 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);
507 void PmISDN::set_conf(int oldconf, int newconf)
509 if (oldconf != newconf) {
510 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
511 if (p_m_b_index > -1)
512 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
513 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);
515 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
520 * subfunction for bchannel_event
523 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
525 if (!mISDNport->b_sock[i].inuse)
527 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
528 add_trace("channel", NULL, "%d", i+1+(i>=15));
529 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
531 close(mISDNport->b_sock[i].fd);
532 unregister_fd(&mISDNport->b_sock[i]);
540 A bchannel goes through the following states in this order:
543 No one is using the bchannel.
544 It is available and not linked to Port class, nor reserved.
547 The bchannel stack is created and an activation request is sent.
548 It MAY be linked to Port class, but already unlinked due to Port class removal.
551 The bchannel is active and cofigured to the Port class needs.
552 Also it is linked to a Port class, otherwhise it would be deactivated.
554 - B_STATE_DEACTIVATING
555 The bchannel is in deactivating state, due to deactivation request.
556 It may be linked to a Port class, that likes to reactivate it.
560 After deactivating bchannel, and if not used, the bchannel becomes idle again.
562 Also the bchannel may be exported, but only if the state is or becomes idle:
565 The bchannel assignment has been sent to the remove application.
568 The bchannel assignment is acknowledged by the remote application.
571 The bchannel is re-imported by mISDN port object.
575 After re-importing bchannel, and if not used, the bchannel becomes idle again.
578 A bchannel can have the following events:
581 A bchannel is required by a Port class.
584 The bchannel beomes active.
587 The bchannel is not required by Port class anymore
589 - B_EVENT_DEACTIVATED
590 The bchannel becomes inactive.
593 The bchannel is now used by remote application.
596 The bchannel is not used by remote application.
598 - B_EVENT_EXPORTREQUEST
599 The bchannel shall be exported to the remote application.
601 - B_EVENT_IMPORTREQUEST
602 The bchannel is released from the remote application.
604 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
606 if an export request is receive by remote application, p_m_remote_* is set.
607 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.)
608 - set on export request from remote application (if port is assigned)
609 - set on channel use, if requested by remote application (p_m_remote_*)
610 - cleared on drop request
612 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
613 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
614 the bchannel import/export is acknowledged with stack given.
616 if exporting, b_remote_*[index] is set to the remote socket id.
617 if importing has been acknowledged. b_remote_*[index] is cleared.
622 * process bchannel events
623 * - mISDNport is a pointer to the port's structure
624 * - i is the index of the bchannel
625 * - event is the B_EVENT_* value
626 * - port is the PmISDN class pointer
628 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
630 class PmISDN *b_port = mISDNport->b_port[i];
631 int state = mISDNport->b_state[i];
632 int timer = -1; // no change
633 unsigned int p_m_remote_ref = 0;
634 unsigned int p_m_remote_id = 0;
637 char *p_m_pipeline = NULL;
638 unsigned char *p_m_crypt_key = NULL;
639 int p_m_crypt_key_len = 0;
640 int p_m_crypt_key_type = 0;
641 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
644 p_m_remote_id = b_port->p_m_remote_id;
645 p_m_remote_ref = b_port->p_m_remote_ref;
646 p_m_tx_gain = b_port->p_m_tx_gain;
647 p_m_rx_gain = b_port->p_m_rx_gain;
648 p_m_pipeline = b_port->p_m_pipeline;
649 p_m_crypt_key = b_port->p_m_crypt_key;
650 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
651 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
656 /* port must be linked in order to allow activation */
658 FATAL("bchannel must be linked to a Port class\n");
661 if (p_m_remote_ref) {
662 /* export bchannel */
663 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);
664 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
665 add_trace("type", NULL, "assign");
666 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
668 state = B_STATE_EXPORTING;
669 mISDNport->b_remote_id[i] = p_m_remote_id;
670 mISDNport->b_remote_ref[i] = p_m_remote_ref;
672 /* create stack and send activation request */
673 if (_bchannel_create(mISDNport, i)) {
674 _bchannel_activate(mISDNport, i, 1, 0);
675 state = B_STATE_ACTIVATING;
676 timer = B_TIMER_ACTIVATING;
681 case B_STATE_ACTIVATING:
682 case B_STATE_EXPORTING:
683 /* do nothing, because it is already activating */
686 case B_STATE_DEACTIVATING:
687 case B_STATE_IMPORTING:
688 /* do nothing, because we must wait until we can reactivate */
692 /* problems that might ocurr:
693 * B_EVENT_USE is received when channel already in use.
694 * bchannel exported, but not freed by other port
696 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
700 case B_EVENT_EXPORTREQUEST:
701 /* special case where the bchannel is requested by remote */
702 if (!p_m_remote_ref) {
703 PERROR("export request without remote channel set, please correct.\n");
708 /* in case, the bchannel is exported right after seize_bchannel */
709 /* export bchannel */
710 /* p_m_remote_id is set, when this event happens. */
711 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);
712 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
713 add_trace("type", NULL, "assign");
714 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
716 state = B_STATE_EXPORTING;
717 mISDNport->b_remote_id[i] = p_m_remote_id;
718 mISDNport->b_remote_ref[i] = p_m_remote_ref;
721 case B_STATE_ACTIVATING:
722 case B_STATE_EXPORTING:
723 /* do nothing, because it is already activating */
726 case B_STATE_DEACTIVATING:
727 case B_STATE_IMPORTING:
728 /* do nothing, because we must wait until we can reactivate */
732 /* bchannel is active, so we deactivate */
733 _bchannel_activate(mISDNport, i, 0, 0);
734 state = B_STATE_DEACTIVATING;
735 timer = B_TIMER_DEACTIVATING;
739 /* problems that might ocurr:
740 * ... when channel already in use.
741 * bchannel exported, but not freed by other port
743 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
747 case B_EVENT_IMPORTREQUEST:
748 /* special case where the bchannel is released by remote */
749 if (p_m_remote_ref) {
750 PERROR("import request with remote channel set, please correct.\n");
756 /* bchannel is not exported */
759 case B_STATE_ACTIVATING:
760 case B_STATE_EXPORTING:
761 /* do nothing because we must wait until bchanenl is active before deactivating */
765 /* bchannel is exported, so we re-import */
766 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
767 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
768 add_trace("type", NULL, "remove");
769 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
771 state = B_STATE_IMPORTING;
774 case B_STATE_DEACTIVATING:
775 case B_STATE_IMPORTING:
776 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
780 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
784 case B_EVENT_ACTIVATED:
787 case B_STATE_ACTIVATING:
788 if (b_port && !p_m_remote_id) {
789 /* bchannel is active and used by Port class, so we configure bchannel */
790 _bchannel_configure(mISDNport, i);
791 state = B_STATE_ACTIVE;
792 b_port->p_m_load = 0;
794 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
795 _bchannel_activate(mISDNport, i, 0, 0);
796 state = B_STATE_DEACTIVATING;
797 timer = B_TIMER_DEACTIVATING;
802 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
806 case B_EVENT_EXPORTED:
808 case B_STATE_EXPORTING:
809 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
810 /* remote export done */
811 state = B_STATE_REMOTE;
813 /* bchannel is now exported, but we need bchannel back
814 * OR bchannel is not used anymore
815 * OR bchannel has been exported to an obsolete ref,
816 * so reimport, to later export to new remote */
817 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
818 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
819 add_trace("type", NULL, "remove");
820 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
822 state = B_STATE_IMPORTING;
827 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
833 FATAL("bchannel must be linked to a Port class\n");
836 /* bchannel is idle due to an error, so we do nothing */
839 case B_STATE_ACTIVATING:
840 case B_STATE_EXPORTING:
841 /* do nothing because we must wait until bchanenl is active before deactivating */
845 /* bchannel is active, so we deactivate */
846 _bchannel_activate(mISDNport, i, 0, 0);
847 state = B_STATE_DEACTIVATING;
848 timer = B_TIMER_DEACTIVATING;
852 /* bchannel is exported, so we re-import */
853 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
854 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
855 add_trace("type", NULL, "remove");
856 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
858 state = B_STATE_IMPORTING;
861 case B_STATE_DEACTIVATING:
862 case B_STATE_IMPORTING:
863 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
867 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
871 case B_EVENT_DEACTIVATED:
875 /* ignore due to deactivation confirm after unloading */
878 case B_STATE_DEACTIVATING:
879 _bchannel_destroy(mISDNport, i);
880 state = B_STATE_IDLE;
882 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
883 if (p_m_remote_ref) {
884 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);
885 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
886 add_trace("type", NULL, "assign");
887 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
889 state = B_STATE_EXPORTING;
890 mISDNport->b_remote_id[i] = p_m_remote_id;
891 mISDNport->b_remote_ref[i] = p_m_remote_ref;
893 if (_bchannel_create(mISDNport, i)) {
894 _bchannel_activate(mISDNport, i, 1, 0);
895 state = B_STATE_ACTIVATING;
896 timer = B_TIMER_ACTIVATING;
903 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
907 case B_EVENT_IMPORTED:
909 case B_STATE_IMPORTING:
910 state = B_STATE_IDLE;
911 mISDNport->b_remote_id[i] = 0;
912 mISDNport->b_remote_ref[i] = 0;
914 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
915 if (p_m_remote_ref) {
916 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);
917 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
918 add_trace("type", NULL, "assign");
919 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
921 state = B_STATE_EXPORTING;
922 mISDNport->b_remote_id[i] = p_m_remote_id;
923 mISDNport->b_remote_ref[i] = p_m_remote_ref;
925 if (_bchannel_create(mISDNport, i)) {
926 _bchannel_activate(mISDNport, i, 1, 0);
927 state = B_STATE_ACTIVATING;
928 timer = B_TIMER_ACTIVATING;
935 /* ignore, because not assigned */
940 case B_EVENT_TIMEOUT:
944 /* ignore due to deactivation confirm after unloading */
947 case B_STATE_ACTIVATING:
948 _bchannel_activate(mISDNport, i, 1, 1);
949 timer = B_TIMER_ACTIVATING;
952 case B_STATE_DEACTIVATING:
953 _bchannel_activate(mISDNport, i, 0, 1);
954 timer = B_TIMER_DEACTIVATING;
958 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
963 PERROR("Illegal event %d, please correct.\n", event);
966 mISDNport->b_state[i] = state;
968 unsched_timer(&mISDNport->b_timer[i]);
970 schedule_timer(&mISDNport->b_timer[i], timer, 0);
977 * check for available channel and reserve+set it.
978 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
980 * returns -(cause value) or x = channel x or 0 = no channel
981 * NOTE: no activation is done here
983 int PmISDN::seize_bchannel(int channel, int exclusive)
987 /* the channel is what we have */
988 if (p_m_b_channel == channel)
991 /* if channel already in use, release it */
996 if (channel==CHANNEL_NO || channel==0)
999 /* is channel in range ? */
1001 || (channel>p_m_mISDNport->b_num && channel<16)
1002 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1003 return(-6); /* channel unacceptable */
1005 /* request exclusive channel */
1006 if (exclusive && channel>0) {
1007 i = channel-1-(channel>16);
1008 if (p_m_mISDNport->b_port[i])
1009 return(-44); /* requested channel not available */
1013 /* ask for channel */
1015 i = channel-1-(channel>16);
1016 if (p_m_mISDNport->b_port[i] == NULL)
1020 /* search for channel */
1022 while(i < p_m_mISDNport->b_num) {
1023 if (!p_m_mISDNport->b_port[i]) {
1024 channel = i+1+(i>=15);
1029 return(-34); /* no free channel */
1032 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1034 /* link Port, set parameters */
1035 p_m_mISDNport->b_port[i] = this;
1037 p_m_b_channel = channel;
1038 p_m_b_exclusive = exclusive;
1039 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1041 /* reserve channel */
1042 if (!p_m_b_reserve) {
1044 p_m_mISDNport->b_reserved++;
1051 * drop reserved channel and unset it.
1052 * deactivation is also done
1054 void PmISDN::drop_bchannel(void)
1056 /* unreserve channel */
1058 p_m_mISDNport->b_reserved--;
1062 if (p_m_b_index < 0)
1067 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1069 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1070 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1071 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1072 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1075 p_m_b_exclusive = 0;
1078 /* process bchannel export/import message from join */
1079 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1081 class Endpoint *epoint;
1083 class PmISDN *isdnport;
1084 struct mISDNport *mISDNport;
1088 case BCHANNEL_REQUEST:
1089 /* find the port object for the join object ref */
1090 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1091 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1094 if (!epoint->ep_portlist) {
1095 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1098 if (epoint->ep_portlist->next) {
1099 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);
1101 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1102 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1105 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1106 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1108 isdnport = (class PmISDN *)port;
1111 if (isdnport->p_m_remote_id) {
1112 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1115 mISDNport = isdnport->p_m_mISDNport;
1116 i = isdnport->p_m_b_index;
1117 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1118 add_trace("type", NULL, "export request");
1120 isdnport->p_m_remote_ref = joinremote->j_serial;
1121 isdnport->p_m_remote_id = joinremote->j_remote_id;
1122 if (mISDNport && i>=0) {
1123 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1127 case BCHANNEL_RELEASE:
1128 case BCHANNEL_ASSIGN_ACK:
1129 case BCHANNEL_REMOVE_ACK:
1130 /* find mISDNport for stack ID */
1131 mISDNport = mISDNport_first;
1134 ii = mISDNport->b_num;
1136 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1142 mISDNport = mISDNport->next;
1145 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1149 if (type!=BCHANNEL_RELEASE) {
1151 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1152 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1154 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1157 isdnport = mISDNport->b_port[i];
1158 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1159 add_trace("type", NULL, "import request");
1162 isdnport->p_m_remote_ref = 0;
1163 isdnport->p_m_remote_id = 0;
1165 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1169 PERROR("received wrong bchannel message type %d from remote\n", type);
1177 audio transmission procedure:
1178 -----------------------------
1181 three sources of audio transmission:
1182 - crypto-data high priority
1183 - tones high priority (also high)
1184 - remote-data low priority
1187 a variable that temporarily shows the number of samples elapsed since last transmission process.
1188 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1191 a variable that is increased whenever data is transmitted.
1192 it is decreased while time elapses. it stores the number of samples that
1193 are currently loaded to dsp module.
1194 since clock in dsp module is the same clock for user space process, these
1198 there are two levels:
1199 ISDN_LOAD will give the load that have to be kept in dsp.
1200 ISDN_MAXLOAD will give the maximum load before dropping.
1202 * procedure for low priority data
1203 see txfromup() for procedure
1204 in short: remote data is ignored during high priority tones
1206 * procedure for high priority data
1207 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1208 if no more data is available, load becomes empty again.
1211 0 ISDN_LOAD ISDN_MAXLOAD
1212 +--------------------+----------------------+
1214 +--------------------+----------------------+
1216 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1217 0 ISDN_LOAD ISDN_MAXLOAD
1218 +--------------------+----------------------+
1219 |TTTTTTTTTTTTTTTTTTTT| |
1220 +--------------------+----------------------+
1222 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1223 0 ISDN_LOAD ISDN_MAXLOAD
1224 +--------------------+----------------------+
1225 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1226 +--------------------+----------------------+
1229 void PmISDN::update_load(void)
1231 /* don't trigger load event if: */
1232 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1235 /* don't trigger load event if event already active */
1236 if (p_m_loadtimer.active)
1239 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1242 int load_timer(struct lcr_timer *timer, void *instance, int index)
1244 class PmISDN *isdnport = (class PmISDN *)instance;
1246 isdnport->load_tx();
1251 void PmISDN::load_tx(void)
1255 struct timeval current_time;
1258 gettimeofday(¤t_time, NULL);
1259 if (p_m_last_tv_sec) {
1260 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1261 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1263 /* set clock of last process! */
1264 p_m_last_tv_sec = current_time.tv_sec;
1265 p_m_last_tv_msec = current_time.tv_usec/1000;
1267 /* process only if we have samples and we are active */
1268 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1270 if (elapsed < p_m_load)
1271 p_m_load -= elapsed;
1275 /* to send data, tone must be on */
1276 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1277 && (p_m_load < ISDN_LOAD) /* not too much load? */
1278 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1279 int tosend = ISDN_LOAD - p_m_load, length;
1280 unsigned char buf[MISDN_HEADER_LEN+tosend];
1281 struct mISDNhead *frm = (struct mISDNhead *)buf;
1282 unsigned char *p = buf+MISDN_HEADER_LEN;
1284 /* copy inband signalling (e.g. used by ss5) */
1285 if (p_m_inband_send_on && tosend) {
1286 tosend -= inband_send(p, tosend);
1289 /* copy crypto loops */
1290 while (p_m_crypt_msg_loops && tosend) {
1291 /* how much do we have to send */
1292 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1295 if (length > tosend)
1298 /* copy message (part) to buffer */
1299 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1302 p_m_crypt_msg_current += length;
1303 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1305 p_m_crypt_msg_current = 0;
1306 p_m_crypt_msg_loops--;
1307 if (!p_m_crypt_msg_loops)
1309 // puts("eine loop weniger");
1317 if (p_tone_name[0] && tosend) {
1318 tosend -= read_audio(p, tosend);
1322 if (ISDN_LOAD - p_m_load - tosend > 0) {
1323 frm->prim = PH_DATA_REQ;
1325 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);
1327 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);
1328 p_m_load += ISDN_LOAD - p_m_load - tosend;
1333 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1334 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
1338 /* handle timeouts */
1339 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1341 class PmISDN *isdnport = (class PmISDN *)instance;
1342 struct lcr_msg *message;
1344 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);
1345 /* send timeout to endpoint */
1346 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1347 message->param.state = isdnport->p_state;
1348 message_put(message);
1355 * whenever we get audio data from bchannel, we process it here
1357 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1359 unsigned int cont = *((unsigned int *)data);
1360 unsigned char *data_temp;
1361 unsigned int length_temp;
1362 struct lcr_msg *message;
1366 if (hh->prim == PH_CONTROL_IND) {
1368 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1371 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1372 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1373 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1375 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1376 message->param.dtmf = cont & DTMF_TONE_MASK;
1377 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1378 message_put(message);
1383 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1384 add_trace("DSP-CRYPT", NULL, "error");
1386 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1387 message->param.crypt.type = CC_ERROR_IND;
1388 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1389 message_put(message);
1393 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1394 add_trace("DSP-CRYPT", NULL, "ok");
1396 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1397 message->param.crypt.type = CC_ACTBF_CONF;
1398 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1399 message_put(message);
1403 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1404 add_trace("unknown", NULL, "0x%x", cont);
1409 if (hh->prim == PH_CONTROL_IND) {
1412 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1413 add_trace("unknown", NULL, "0x%x", hh->id);
1418 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1420 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1421 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1424 /* see below (same condition) */
1425 if (p_state!=PORT_STATE_CONNECT
1426 && !p_m_mISDNport->tones)
1428 // printf(".");fflush(stdout);return;
1430 record(data, len, 1); // from up
1433 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1434 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1438 /* inband is processed */
1439 if (p_m_inband_receive_on)
1440 inband_receive(data, len);
1442 /* calls will not process any audio data unless
1443 * the call is connected OR tones feature is enabled.
1445 #ifndef DEBUG_COREBRIDGE
1446 if (p_state!=PORT_STATE_CONNECT
1447 && !p_m_mISDNport->tones)
1452 /* the bearer capability must be audio in order to send and receive
1453 * audio prior or after connect.
1455 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1459 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1461 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1467 record(data, len, 0); // from down
1469 /* randomize and listen to crypt message if enabled */
1470 if (p_m_crypt_listen) {
1471 /* the noisy randomizer */
1475 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1477 cryptman_listen_bch(data, len);
1482 /* send data to epoint */
1483 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1486 while(length_temp) {
1487 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1488 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1489 memcpy(message->param.data.data, data_temp, message->param.data.len);
1490 message_put(message);
1491 if (length_temp <= sizeof(message->param.data.data))
1493 data_temp += sizeof(message->param.data.data);
1494 length_temp -= sizeof(message->param.data.data);
1503 void PmISDN::set_echotest(int echo)
1505 if (p_m_echo != echo) {
1507 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1509 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1510 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1517 void PmISDN::set_tone(const char *dir, const char *tone)
1522 /* if no directory is given (by extension), we use interface.conf or options.conf */
1523 if (!dir || !dir[0]) {
1524 if (p_m_mISDNport->ifport->tones_dir[0])
1525 dir = p_m_mISDNport->ifport->tones_dir;
1526 else if (options.tones_dir[0])
1527 dir = options.tones_dir;
1532 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1538 /* check for dsp tones */
1539 if (!strcmp(dir, "american"))
1541 if (!strcmp(dir, "german"))
1543 if (!strcmp(dir, "oldgerman"))
1544 dsp = DSP_OLDGERMAN;
1546 /* check if we NOT really have to use a dsp-tone */
1547 if (dsp == DSP_NONE) {
1550 if (p_m_b_index > -1)
1551 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1552 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1553 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1556 Port::set_tone(dir, tone);
1560 /* now we USE dsp-tone, convert name */
1561 if (!strcmp(tone, "dialtone")) {
1563 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1564 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1565 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1567 } else if (!strcmp(tone, "dialpbx")) {
1569 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1570 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1571 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1573 } else if (!strcmp(tone, "ringing")) {
1575 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1576 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1577 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1579 } else if (!strcmp(tone, "ringpbx")) {
1581 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1582 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1583 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1585 } else if (!strcmp(tone, "busy")) {
1588 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1589 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1590 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1592 } else if (!strcmp(tone, "release")) {
1595 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1596 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1597 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1599 } else if (!strcmp(tone, "cause_10"))
1601 else if (!strcmp(tone, "cause_11"))
1603 else if (!strcmp(tone, "cause_22")) {
1605 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1606 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1607 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1609 } else if (!strncmp(tone, "cause_", 6))
1610 id = TONE_SPECIAL_INFO;
1614 /* if we have a tone that is not supported by dsp */
1615 if (id==TONE_OFF && tone[0])
1619 if (p_m_tone != id) {
1622 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1623 if (p_m_b_index > -1)
1624 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1625 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1627 /* turn user-space tones off in cases of no tone OR dsp tone */
1628 Port::set_tone("",NULL);
1632 /* MESSAGE_mISDNSIGNAL */
1633 //extern struct lcr_msg *dddebug;
1634 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1636 int oldconf, newconf;
1637 switch(param->mISDNsignal.message) {
1638 case mISDNSIGNAL_VOLUME:
1639 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1640 p_m_tx_gain = param->mISDNsignal.tx_gain;
1641 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1642 if (p_m_b_index > -1)
1643 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1644 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1646 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1647 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1648 p_m_rx_gain = param->mISDNsignal.rx_gain;
1649 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1650 if (p_m_b_index > -1)
1651 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1652 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1654 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1657 case mISDNSIGNAL_CONF:
1658 oldconf = p_m_mute?0:p_m_conf;
1659 p_m_conf = param->mISDNsignal.conf;
1660 newconf = p_m_mute?0:p_m_conf;
1661 set_conf(oldconf, newconf);
1664 case mISDNSIGNAL_JOINDATA:
1665 if (p_m_joindata != param->mISDNsignal.joindata) {
1666 p_m_joindata = param->mISDNsignal.joindata;
1667 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1670 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1673 case mISDNSIGNAL_DELAY:
1674 if (p_m_delay != param->mISDNsignal.delay) {
1675 p_m_delay = param->mISDNsignal.delay;
1676 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1677 if (p_m_b_index > -1)
1678 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1679 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1681 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1685 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1690 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1692 struct lcr_msg *message;
1694 switch(param->crypt.type) {
1695 case CC_ACTBF_REQ: /* activate blowfish */
1697 p_m_crypt_key_len = param->crypt.len;
1698 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1699 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1700 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1701 message->param.crypt.type = CC_ERROR_IND;
1702 message_put(message);
1705 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1707 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1708 if (p_m_b_index > -1)
1709 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1710 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, p_m_crypt?DSP_BF_ENABLE_KEY:DSP_BF_DISABLE, p_m_crypt_key, p_m_crypt_key_len, "DSP-CRYPT", p_m_crypt_key_len);
1713 case CC_DACT_REQ: /* deactivate session encryption */
1718 case CR_LISTEN_REQ: /* start listening to messages */
1719 p_m_crypt_listen = 1;
1721 p_m_crypt_listen_state = 0;
1724 case CR_UNLISTEN_REQ: /* stop listening to messages */
1725 p_m_crypt_listen = 0;
1729 case CR_MESSAGE_REQ: /* send message */
1730 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1731 if (!p_m_crypt_msg_len) {
1732 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1735 p_m_crypt_msg_current = 0; /* reset */
1736 p_m_crypt_msg_loops = 6; /* enable */
1740 /* disable txmix, or we get corrupt data due to audio process */
1741 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1742 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1743 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1749 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1755 * endpoint sends messages to the port
1757 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1759 if (Port::message_epoint(epoint_id, message_id, param))
1762 switch(message_id) {
1763 case MESSAGE_DATA: /* tx-data from upper layer */
1764 txfromup(param->data.data, param->data.len);
1767 case MESSAGE_mISDNSIGNAL: /* user command */
1768 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1769 message_mISDNsignal(epoint_id, message_id, param);
1772 case MESSAGE_CRYPT: /* crypt control command */
1773 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1774 message_crypt(epoint_id, message_id, param);
1781 void PmISDN::update_rxoff(void)
1783 /* call bridges in user space OR crypto OR recording */
1784 if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1785 /* rx IS required */
1789 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1790 if (p_m_b_index > -1)
1791 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1792 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1795 /* rx NOT required */
1799 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1800 if (p_m_b_index > -1)
1801 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1802 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1807 /* txdata IS required */
1811 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1812 if (p_m_b_index > -1)
1813 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1814 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1817 /* txdata NOT required */
1821 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1822 if (p_m_b_index > -1)
1823 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1824 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1829 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1831 struct mISDNport *mISDNport;
1836 /* unset global semaphore */
1837 read(fd->fd, &byte, 1);
1840 /* process all ports */
1841 mISDNport = mISDNport_first;
1843 /* handle queued up-messages (d-channel) */
1844 if (!mISDNport->gsm) {
1845 while ((mb = mdequeue(&mISDNport->upqueue))) {
1848 case MPH_ACTIVATE_IND:
1849 if (mISDNport->l1link != 1) {
1850 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1852 mISDNport->l1link = 1;
1856 case MPH_DEACTIVATE_IND:
1857 if (mISDNport->l1link != 0) {
1858 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1860 mISDNport->l1link = 0;
1864 case MPH_INFORMATION_IND:
1865 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1867 case L1_SIGNAL_LOS_ON:
1870 case L1_SIGNAL_LOS_OFF:
1873 case L1_SIGNAL_AIS_ON:
1876 case L1_SIGNAL_AIS_OFF:
1879 case L1_SIGNAL_RDI_ON:
1882 case L1_SIGNAL_RDI_OFF:
1885 case L1_SIGNAL_SLIP_TX:
1886 mISDNport->slip_tx++;
1888 case L1_SIGNAL_SLIP_RX:
1889 mISDNport->slip_rx++;
1894 case MT_L2ESTABLISH:
1895 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1896 add_trace("tei", NULL, "%d", l3m->pid);
1898 mISDNport->l2link = 1;
1900 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1901 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1902 if (mISDNport->l2establish.active) {
1903 unsched_timer(&mISDNport->l2establish);
1904 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1911 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1912 if (!mISDNport->l2establish.active) {
1913 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1914 add_trace("tei", NULL, "%d", l3m->pid);
1916 /* down if not nt-ptmp */
1917 if (!mISDNport->ntmode || mISDNport->ptp)
1918 mISDNport->l2link = 0;
1920 if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1921 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1922 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1923 schedule_timer(&mISDNport->l2establish, 5, 0);
1924 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1930 /* l3-data is sent to LCR */
1931 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1937 mISDNport = mISDNport->next;
1942 /* l2 establish timer fires */
1943 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1945 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1947 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1948 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1949 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1950 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1956 /* handle frames from bchannel */
1957 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1959 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1960 unsigned char buffer[2048+MISDN_HEADER_LEN];
1961 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1964 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1966 PERROR("read error frame, errno %d\n", errno);
1969 if (ret < (int)MISDN_HEADER_LEN) {
1970 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1974 /* we don't care about confirms, we use rx data to sync tx */
1978 /* we receive audio data, we respond to it AND we send tones */
1983 case PH_CONTROL_IND:
1984 if (mISDNport->b_port[i])
1985 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1987 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1990 case PH_ACTIVATE_IND:
1991 case DL_ESTABLISH_IND:
1992 case PH_ACTIVATE_CNF:
1993 case DL_ESTABLISH_CNF:
1994 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1995 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1998 case PH_DEACTIVATE_IND:
1999 case DL_RELEASE_IND:
2000 case PH_DEACTIVATE_CNF:
2001 case DL_RELEASE_CNF:
2002 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2003 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2007 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2013 /* process timer events for bchannel handling */
2014 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2016 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2019 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2025 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2029 * l3m must be queued, except for MT_ASSIGN
2032 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2035 /* special MT_ASSIGN handling:
2037 * if we request a PID from mlayer, we always do it while lcr is locked.
2038 * therefore we must check the MT_ASSIGN reply first before we lock.
2039 * this is because the MT_ASSIGN reply is received with the requesting
2040 * process, not by the mlayer thread!
2041 * this means, that the reply is sent during call of the request.
2042 * we must check if we get a reply and we know that we lcr is currently
2045 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2046 /* let's do some checking if someone changes stack behaviour */
2047 if (mt_assign_pid != 0)
2048 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2049 mt_assign_pid = pid;
2052 /* queue message, create, if required */
2054 l3m = alloc_l3_msg();
2056 FATAL("No memory for layer 3 message\n");
2058 mb = container_of(l3m, struct mbuffer, l3);
2061 mqueue_tail(&mISDNport->upqueue, mb);
2062 if (!upqueue_avail) {
2065 write(upqueue_pipe[1], &byte, 1);
2070 int mISDN_getportbyname(int sock, int cnt, char *portname)
2072 struct mISDN_devinfo devinfo;
2076 while (port < cnt) {
2078 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2081 if (!strcasecmp(devinfo.name, portname))
2092 * global function to add a new card (port)
2094 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2097 struct mISDNport *mISDNport, **mISDNportp;
2098 int port = ifport->portnum;
2099 int ptp = ifport->ptp;
2100 int force_nt = ifport->nt;
2101 int l1hold = ifport->l1hold;
2102 int l2hold = ifport->l2hold;
2103 int gsm = ifport->gsm;
2104 int ss5 = ifport->ss5;
2108 // struct mlayer3 *ml3;
2109 struct mISDN_devinfo devinfo;
2110 unsigned int protocol, prop;
2112 /* check port counts */
2113 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2115 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2120 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2124 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2127 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
2129 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2132 // note: 'port' has still the port number
2134 if (port>cnt || port<0) {
2135 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2139 /* get port attributes */
2140 pri = bri = pots = nt = te = 0;
2142 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2144 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2147 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2151 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2155 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2159 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2164 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2170 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2175 if (force_nt && !nt) {
2176 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2180 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2183 if (pots && !bri && !pri) {
2184 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2188 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2192 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2195 /* set NT by turning off TE */
2198 /* if TE an NT is supported (and not forced to NT), turn off NT */
2202 /* check for double use of port */
2204 mISDNport = mISDNport_first;
2206 if (mISDNport->portnum == port)
2208 mISDNport = mISDNport->next;
2211 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2216 /* check for continous channelmap with no bchannel on slot 16 */
2217 if (test_channelmap(0, devinfo.channelmap)) {
2218 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2222 while(i < (int)devinfo.nrbchan + 1) {
2224 if (test_channelmap(i, devinfo.channelmap)) {
2225 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2229 if (!test_channelmap(i, devinfo.channelmap)) {
2230 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2237 /* add mISDNport structure */
2238 mISDNportp = &mISDNport_first;
2240 mISDNportp = &((*mISDNportp)->next);
2241 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2242 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2244 /* gsm/ss5 link is always active */
2245 mISDNport->l1link = 1;
2246 mISDNport->l2link = 1;
2248 mISDNport->l1link = -1;
2249 mISDNport->l2link = -1;
2251 mISDNport->gsm = gsm;
2253 *mISDNportp = mISDNport;
2255 /* if pri, must set PTP */
2259 /* set ss5 params */
2261 /* try to keep interface enabled */
2281 /* allocate ressources of port */
2282 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2283 prop = (1 << MISDN_FLG_L2_CLEAN);
2284 if (ptp) // ptp forced
2285 prop |= (1 << MISDN_FLG_PTP);
2286 if (nt) // supports hold/retrieve on nt-mode
2287 prop |= (1 << MISDN_FLG_NET_HOLD);
2288 if (l1hold) // supports layer 1 hold
2289 prop |= (1 << MISDN_FLG_L1_HOLD);
2290 if (l2hold) // supports layer 2 hold
2291 prop |= (1 << MISDN_FLG_L2_HOLD);
2292 /* open layer 3 and init upqueue */
2294 unsigned long on = 1;
2295 struct sockaddr_mISDN addr;
2297 if (devinfo.nrbchan < 8) {
2298 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2299 mISDNport_close(mISDNport);
2303 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2304 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2305 mISDNport_close(mISDNport);
2308 /* set nonblocking io */
2309 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2310 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2311 mISDNport_close(mISDNport);
2314 /* bind socket to dchannel */
2315 memset(&addr, 0, sizeof(addr));
2316 addr.family = AF_ISDN;
2319 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2320 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2321 mISDNport_close(mISDNport);
2325 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2326 mqueue_init(&mISDNport->upqueue);
2327 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2328 if (!mISDNport->ml3) {
2329 mqueue_purge(&mISDNport->upqueue);
2330 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2338 "PORT (open failed)");
2340 mISDNport_close(mISDNport);
2345 SCPY(mISDNport->name, devinfo.name);
2346 mISDNport->b_num = devinfo.nrbchan;
2347 mISDNport->portnum = port;
2348 mISDNport->ntmode = nt;
2349 mISDNport->tespecial = ifport->tespecial;
2350 mISDNport->pri = pri;
2351 mISDNport->ptp = ptp;
2352 mISDNport->l1hold = l1hold;
2353 mISDNport->l2hold = l2hold;
2354 mISDNport->ss5 = ss5;
2355 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2357 while(i < mISDNport->b_num) {
2358 mISDNport->b_state[i] = B_STATE_IDLE;
2359 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2363 /* if ptp, pull up the link */
2364 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2365 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2366 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2367 add_trace("tei", NULL, "%d", 0);
2369 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2372 /* for nt-mode ptmp the link is always up */
2373 if (mISDNport->ntmode && !mISDNport->ptp)
2374 mISDNport->l2link = 1;
2376 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2378 start_trace(mISDNport->portnum,
2386 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2387 add_trace("channels", NULL, "%d", mISDNport->b_num);
2389 add_trace("ccitt#5", NULL, "enabled");
2397 * load static port instances, if required by mISDNport
2399 void mISDNport_static(struct mISDNport *mISDNport)
2404 while(i < mISDNport->b_num) {
2407 ss5_create_channel(mISDNport, i);
2415 * function to free ALL cards (ports)
2417 void mISDNport_close_all(void)
2419 /* free all ports */
2420 while(mISDNport_first)
2421 mISDNport_close(mISDNport_first);
2425 * free only one port
2427 void mISDNport_close(struct mISDNport *mISDNport)
2429 struct mISDNport **mISDNportp;
2431 class PmISDN *isdnport;
2434 /* remove all port instance that are linked to this mISDNport */
2438 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2439 isdnport = (class PmISDN *)port;
2440 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2441 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2449 /* only if we are already part of interface */
2450 if (mISDNport->ifport) {
2451 start_trace(mISDNport->portnum,
2452 mISDNport->ifport->interface,
2462 /* free bchannels */
2464 while(i < mISDNport->b_num) {
2465 if (mISDNport->b_sock[i].inuse) {
2466 _bchannel_destroy(mISDNport, i);
2467 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2469 if (mISDNport->b_timer[i].inuse) {
2470 del_timer(&mISDNport->b_timer[i]);
2474 del_timer(&mISDNport->l2establish);
2476 /* close layer 3, if open */
2477 if (!mISDNport->gsm && mISDNport->ml3) {
2478 close_layer3(mISDNport->ml3);
2481 /* close gsm socket, if open */
2482 if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2483 close(mISDNport->lcr_sock);
2487 if (!mISDNport->gsm)
2488 mqueue_purge(&mISDNport->upqueue);
2490 /* remove from list */
2491 mISDNportp = &mISDNport_first;
2492 while(*mISDNportp) {
2493 if (*mISDNportp == mISDNport) {
2494 *mISDNportp = (*mISDNportp)->next;
2498 mISDNportp = &((*mISDNportp)->next);
2502 FATAL("mISDNport not in list\n");
2504 FREE(mISDNport, sizeof(struct mISDNport));
2511 * enque data from upper buffer
2513 void PmISDN::txfromup(unsigned char *data, int length)
2515 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2516 struct mISDNhead *hh = (struct mISDNhead *)buf;
2519 if (p_m_b_index < 0)
2521 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2524 /* check if high priority tones exist
2525 * ignore data in this case
2527 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2530 /* preload procedure
2531 * if transmit buffer in DSP module is empty,
2532 * preload it to DSP_LOAD to prevent jitter gaps.
2534 if (p_m_load == 0 && ISDN_LOAD > 0) {
2535 hh->prim = PH_DATA_REQ;
2537 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2538 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2540 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2541 p_m_load += ISDN_LOAD;
2542 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2545 /* drop if load would exceed ISDN_MAXLOAD
2546 * this keeps the delay not too high
2548 if (p_m_load+length > ISDN_MAXLOAD)
2551 /* make and send frame */
2552 hh->prim = PH_DATA_REQ;
2554 memcpy(buf+MISDN_HEADER_LEN, data, length);
2555 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2557 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2561 int PmISDN::inband_send(unsigned char *buffer, int len)
2563 PERROR("this function must be derived to function!\n");
2567 void PmISDN::inband_send_on(void)
2569 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2570 p_m_inband_send_on = 1;
2571 /* trigger inband transmit */
2575 void PmISDN::inband_send_off(void)
2577 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2578 p_m_inband_send_on = 0;
2581 void PmISDN::inband_receive(unsigned char *buffer, int len)
2584 // if (len >= SS5_DECODER_NPOINTS)
2585 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2586 PERROR("this function must be derived to function!\n");
2589 void PmISDN::inband_receive_on(void)
2591 /* this must work during constructor, see ss5.cpp */
2592 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2593 p_m_inband_receive_on = 1;
2597 void PmISDN::inband_receive_off(void)
2599 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2600 p_m_inband_receive_on = 0;
2604 void PmISDN::mute_on(void)
2608 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2610 set_conf(p_m_conf, 0);
2613 void PmISDN::mute_off(void)
2617 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2619 set_conf(0, p_m_conf);