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 */
1838 // with a very small incident, upqueue_avail may be set by mISDN thread and
1839 // another byte may be sent to the pipe, which causes a call to this function
1840 // again with nothing in the upqueue. this is no problem.
1841 read(fd->fd, &byte, 1);
1843 /* process all ports */
1844 mISDNport = mISDNport_first;
1846 /* handle queued up-messages (d-channel) */
1847 if (!mISDNport->gsm) {
1848 while ((mb = mdequeue(&mISDNport->upqueue))) {
1851 case MPH_ACTIVATE_IND:
1852 if (mISDNport->l1link != 1) {
1853 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1855 mISDNport->l1link = 1;
1859 case MPH_DEACTIVATE_IND:
1860 if (mISDNport->l1link != 0) {
1861 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1863 mISDNport->l1link = 0;
1867 case MPH_INFORMATION_IND:
1868 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1870 case L1_SIGNAL_LOS_ON:
1873 case L1_SIGNAL_LOS_OFF:
1876 case L1_SIGNAL_AIS_ON:
1879 case L1_SIGNAL_AIS_OFF:
1882 case L1_SIGNAL_RDI_ON:
1885 case L1_SIGNAL_RDI_OFF:
1888 case L1_SIGNAL_SLIP_TX:
1889 mISDNport->slip_tx++;
1891 case L1_SIGNAL_SLIP_RX:
1892 mISDNport->slip_rx++;
1897 case MT_L2ESTABLISH:
1898 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1899 add_trace("tei", NULL, "%d", l3m->pid);
1901 mISDNport->l2link = 1;
1903 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1904 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1905 if (mISDNport->l2establish.active) {
1906 unsched_timer(&mISDNport->l2establish);
1907 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1914 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1915 if (!mISDNport->l2establish.active) {
1916 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1917 add_trace("tei", NULL, "%d", l3m->pid);
1919 /* down if not nt-ptmp */
1920 if (!mISDNport->ntmode || mISDNport->ptp)
1921 mISDNport->l2link = 0;
1923 if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1924 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1925 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1926 schedule_timer(&mISDNport->l2establish, 5, 0);
1927 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1933 /* l3-data is sent to LCR */
1934 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1940 mISDNport = mISDNport->next;
1945 /* l2 establish timer fires */
1946 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1948 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1950 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1951 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1952 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1953 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1959 /* handle frames from bchannel */
1960 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1962 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1963 unsigned char buffer[2048+MISDN_HEADER_LEN];
1964 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1967 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1969 PERROR("read error frame, errno %d\n", errno);
1972 if (ret < (int)MISDN_HEADER_LEN) {
1973 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1977 /* we don't care about confirms, we use rx data to sync tx */
1981 /* we receive audio data, we respond to it AND we send tones */
1986 case PH_CONTROL_IND:
1987 if (mISDNport->b_port[i])
1988 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1990 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1993 case PH_ACTIVATE_IND:
1994 case DL_ESTABLISH_IND:
1995 case PH_ACTIVATE_CNF:
1996 case DL_ESTABLISH_CNF:
1997 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1998 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2001 case PH_DEACTIVATE_IND:
2002 case DL_RELEASE_IND:
2003 case PH_DEACTIVATE_CNF:
2004 case DL_RELEASE_CNF:
2005 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2006 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2010 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2016 /* process timer events for bchannel handling */
2017 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2019 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2022 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2028 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2032 * l3m must be queued, except for MT_ASSIGN
2035 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2038 /* special MT_ASSIGN handling:
2040 * if we request a PID from mlayer, we always do it while lcr is locked.
2041 * therefore we must check the MT_ASSIGN reply first before we lock.
2042 * this is because the MT_ASSIGN reply is received with the requesting
2043 * process, not by the mlayer thread!
2044 * this means, that the reply is sent during call of the request.
2045 * we must check if we get a reply and we know that we lcr is currently
2048 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2049 /* let's do some checking if someone changes stack behaviour */
2050 if (mt_assign_pid != 0)
2051 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2052 mt_assign_pid = pid;
2055 /* queue message, create, if required */
2057 l3m = alloc_l3_msg();
2059 FATAL("No memory for layer 3 message\n");
2061 mb = container_of(l3m, struct mbuffer, l3);
2064 mqueue_tail(&mISDNport->upqueue, mb);
2065 if (!upqueue_avail) {
2066 // multiple threads may cause multiple calls of this section, but this
2067 // results only in multiple processing of the upqueue read.
2068 // this is no problem.
2071 write(upqueue_pipe[1], &byte, 1);
2076 int mISDN_getportbyname(int sock, int cnt, char *portname)
2078 struct mISDN_devinfo devinfo;
2082 while (port < cnt) {
2084 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2087 if (!strcasecmp(devinfo.name, portname))
2098 * global function to add a new card (port)
2100 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2103 struct mISDNport *mISDNport, **mISDNportp;
2104 int port = ifport->portnum;
2105 int ptp = ifport->ptp;
2106 int force_nt = ifport->nt;
2107 int l1hold = ifport->l1hold;
2108 int l2hold = ifport->l2hold;
2109 int gsm = ifport->gsm;
2110 int ss5 = ifport->ss5;
2114 // struct mlayer3 *ml3;
2115 struct mISDN_devinfo devinfo;
2116 unsigned int protocol, prop;
2118 /* check port counts */
2119 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2121 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2126 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2130 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2133 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
2135 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2138 // note: 'port' has still the port number
2140 if (port>cnt || port<0) {
2141 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2145 /* get port attributes */
2146 pri = bri = pots = nt = te = 0;
2148 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2150 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2153 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2157 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2161 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2165 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2170 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2176 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2181 if (force_nt && !nt) {
2182 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2186 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2189 if (pots && !bri && !pri) {
2190 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2194 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2198 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2201 /* set NT by turning off TE */
2204 /* if TE an NT is supported (and not forced to NT), turn off NT */
2208 /* check for double use of port */
2210 mISDNport = mISDNport_first;
2212 if (mISDNport->portnum == port)
2214 mISDNport = mISDNport->next;
2217 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2222 /* check for continous channelmap with no bchannel on slot 16 */
2223 if (test_channelmap(0, devinfo.channelmap)) {
2224 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2228 while(i < (int)devinfo.nrbchan + 1) {
2230 if (test_channelmap(i, devinfo.channelmap)) {
2231 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2235 if (!test_channelmap(i, devinfo.channelmap)) {
2236 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2243 /* add mISDNport structure */
2244 mISDNportp = &mISDNport_first;
2246 mISDNportp = &((*mISDNportp)->next);
2247 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2248 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2250 /* gsm/ss5 link is always active */
2251 mISDNport->l1link = 1;
2252 mISDNport->l2link = 1;
2254 mISDNport->l1link = -1;
2255 mISDNport->l2link = -1;
2257 mISDNport->gsm = gsm;
2259 *mISDNportp = mISDNport;
2261 /* if pri, must set PTP */
2265 /* set ss5 params */
2267 /* try to keep interface enabled */
2287 /* allocate ressources of port */
2288 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2289 prop = (1 << MISDN_FLG_L2_CLEAN);
2290 if (ptp) // ptp forced
2291 prop |= (1 << MISDN_FLG_PTP);
2292 if (nt) // supports hold/retrieve on nt-mode
2293 prop |= (1 << MISDN_FLG_NET_HOLD);
2294 if (l1hold) // supports layer 1 hold
2295 prop |= (1 << MISDN_FLG_L1_HOLD);
2296 if (l2hold) // supports layer 2 hold
2297 prop |= (1 << MISDN_FLG_L2_HOLD);
2298 /* open layer 3 and init upqueue */
2300 unsigned long on = 1;
2301 struct sockaddr_mISDN addr;
2303 if (devinfo.nrbchan < 8) {
2304 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2305 mISDNport_close(mISDNport);
2309 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2310 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2311 mISDNport_close(mISDNport);
2314 /* set nonblocking io */
2315 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2316 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2317 mISDNport_close(mISDNport);
2320 /* bind socket to dchannel */
2321 memset(&addr, 0, sizeof(addr));
2322 addr.family = AF_ISDN;
2325 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2326 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2327 mISDNport_close(mISDNport);
2331 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2332 mqueue_init(&mISDNport->upqueue);
2333 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2334 if (!mISDNport->ml3) {
2335 mqueue_purge(&mISDNport->upqueue);
2336 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2344 "PORT (open failed)");
2346 mISDNport_close(mISDNport);
2351 SCPY(mISDNport->name, devinfo.name);
2352 mISDNport->b_num = devinfo.nrbchan;
2353 mISDNport->portnum = port;
2354 mISDNport->ntmode = nt;
2355 mISDNport->tespecial = ifport->tespecial;
2356 mISDNport->pri = pri;
2357 mISDNport->ptp = ptp;
2358 mISDNport->l1hold = l1hold;
2359 mISDNport->l2hold = l2hold;
2360 mISDNport->ss5 = ss5;
2361 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2363 while(i < mISDNport->b_num) {
2364 mISDNport->b_state[i] = B_STATE_IDLE;
2365 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2369 /* if ptp, pull up the link */
2370 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2371 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2372 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2373 add_trace("tei", NULL, "%d", 0);
2375 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2378 /* for nt-mode ptmp the link is always up */
2379 if (mISDNport->ntmode && !mISDNport->ptp)
2380 mISDNport->l2link = 1;
2382 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2384 start_trace(mISDNport->portnum,
2392 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2393 add_trace("channels", NULL, "%d", mISDNport->b_num);
2395 add_trace("ccitt#5", NULL, "enabled");
2403 * load static port instances, if required by mISDNport
2405 void mISDNport_static(struct mISDNport *mISDNport)
2410 while(i < mISDNport->b_num) {
2413 ss5_create_channel(mISDNport, i);
2421 * function to free ALL cards (ports)
2423 void mISDNport_close_all(void)
2425 /* free all ports */
2426 while(mISDNport_first)
2427 mISDNport_close(mISDNport_first);
2431 * free only one port
2433 void mISDNport_close(struct mISDNport *mISDNport)
2435 struct mISDNport **mISDNportp;
2437 class PmISDN *isdnport;
2440 /* remove all port instance that are linked to this mISDNport */
2444 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2445 isdnport = (class PmISDN *)port;
2446 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2447 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2455 /* only if we are already part of interface */
2456 if (mISDNport->ifport) {
2457 start_trace(mISDNport->portnum,
2458 mISDNport->ifport->interface,
2468 /* free bchannels */
2470 while(i < mISDNport->b_num) {
2471 if (mISDNport->b_sock[i].inuse) {
2472 _bchannel_destroy(mISDNport, i);
2473 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2475 if (mISDNport->b_timer[i].inuse) {
2476 del_timer(&mISDNport->b_timer[i]);
2480 del_timer(&mISDNport->l2establish);
2482 /* close layer 3, if open */
2483 if (!mISDNport->gsm && mISDNport->ml3) {
2484 close_layer3(mISDNport->ml3);
2487 /* close gsm socket, if open */
2488 if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2489 close(mISDNport->lcr_sock);
2493 if (!mISDNport->gsm)
2494 mqueue_purge(&mISDNport->upqueue);
2496 /* remove from list */
2497 mISDNportp = &mISDNport_first;
2498 while(*mISDNportp) {
2499 if (*mISDNportp == mISDNport) {
2500 *mISDNportp = (*mISDNportp)->next;
2504 mISDNportp = &((*mISDNportp)->next);
2508 FATAL("mISDNport not in list\n");
2510 FREE(mISDNport, sizeof(struct mISDNport));
2517 * enque data from upper buffer
2519 void PmISDN::txfromup(unsigned char *data, int length)
2521 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2522 struct mISDNhead *hh = (struct mISDNhead *)buf;
2525 if (p_m_b_index < 0)
2527 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2530 /* check if high priority tones exist
2531 * ignore data in this case
2533 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2536 /* preload procedure
2537 * if transmit buffer in DSP module is empty,
2538 * preload it to DSP_LOAD to prevent jitter gaps.
2540 if (p_m_load == 0 && ISDN_LOAD > 0) {
2541 hh->prim = PH_DATA_REQ;
2543 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2544 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2546 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2547 p_m_load += ISDN_LOAD;
2548 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2551 /* drop if load would exceed ISDN_MAXLOAD
2552 * this keeps the delay not too high
2554 if (p_m_load+length > ISDN_MAXLOAD)
2557 /* make and send frame */
2558 hh->prim = PH_DATA_REQ;
2560 memcpy(buf+MISDN_HEADER_LEN, data, length);
2561 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2563 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2567 int PmISDN::inband_send(unsigned char *buffer, int len)
2569 PERROR("this function must be derived to function!\n");
2573 void PmISDN::inband_send_on(void)
2575 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2576 p_m_inband_send_on = 1;
2577 /* trigger inband transmit */
2581 void PmISDN::inband_send_off(void)
2583 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2584 p_m_inband_send_on = 0;
2587 void PmISDN::inband_receive(unsigned char *buffer, int len)
2590 // if (len >= SS5_DECODER_NPOINTS)
2591 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2592 PERROR("this function must be derived to function!\n");
2595 void PmISDN::inband_receive_on(void)
2597 /* this must work during constructor, see ss5.cpp */
2598 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2599 p_m_inband_receive_on = 1;
2603 void PmISDN::inband_receive_off(void)
2605 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2606 p_m_inband_receive_on = 0;
2610 void PmISDN::mute_on(void)
2614 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2616 set_conf(p_m_conf, 0);
2619 void PmISDN::mute_off(void)
2623 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2625 set_conf(0, p_m_conf);