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));
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;
1837 /* unset global semaphore */
1839 // with a very small incident, upqueue_avail may be set by mISDN thread and
1840 // another byte may be sent to the pipe, which causes a call to this function
1841 // again with nothing in the upqueue. this is no problem.
1842 ret = read(fd->fd, &byte, 1);
1844 /* process all ports */
1845 mISDNport = mISDNport_first;
1847 /* handle queued up-messages (d-channel) */
1848 if (!mISDNport->gsm) {
1849 while ((mb = mdequeue(&mISDNport->upqueue))) {
1852 case MPH_ACTIVATE_IND:
1853 if (mISDNport->l1link != 1) {
1854 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1856 mISDNport->l1link = 1;
1860 case MPH_DEACTIVATE_IND:
1861 if (mISDNport->l1link != 0) {
1862 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1864 mISDNport->l1link = 0;
1868 case MPH_INFORMATION_IND:
1869 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1871 case L1_SIGNAL_LOS_ON:
1874 case L1_SIGNAL_LOS_OFF:
1877 case L1_SIGNAL_AIS_ON:
1880 case L1_SIGNAL_AIS_OFF:
1883 case L1_SIGNAL_RDI_ON:
1886 case L1_SIGNAL_RDI_OFF:
1889 case L1_SIGNAL_SLIP_TX:
1890 mISDNport->slip_tx++;
1892 case L1_SIGNAL_SLIP_RX:
1893 mISDNport->slip_rx++;
1898 case MT_L2ESTABLISH:
1899 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1900 add_trace("tei", NULL, "%d", l3m->pid);
1902 mISDNport->l2link = 1;
1904 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1905 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1906 if (mISDNport->l2establish.active) {
1907 unsched_timer(&mISDNport->l2establish);
1908 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1915 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1916 if (!mISDNport->l2establish.active) {
1917 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1918 add_trace("tei", NULL, "%d", l3m->pid);
1920 /* down if not nt-ptmp */
1921 if (!mISDNport->ntmode || mISDNport->ptp)
1922 mISDNport->l2link = 0;
1924 if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1925 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1926 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1927 schedule_timer(&mISDNport->l2establish, 5, 0);
1928 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1934 /* l3-data is sent to LCR */
1935 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1941 mISDNport = mISDNport->next;
1946 /* l2 establish timer fires */
1947 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1949 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1951 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1952 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1953 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1954 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1960 /* handle frames from bchannel */
1961 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1963 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1964 unsigned char buffer[2048+MISDN_HEADER_LEN];
1965 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1968 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1970 PERROR("read error frame, errno %d\n", errno);
1973 if (ret < (int)MISDN_HEADER_LEN) {
1974 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1978 /* we don't care about confirms, we use rx data to sync tx */
1982 /* we receive audio data, we respond to it AND we send tones */
1987 case PH_CONTROL_IND:
1988 if (mISDNport->b_port[i])
1989 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1991 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1994 case PH_ACTIVATE_IND:
1995 case DL_ESTABLISH_IND:
1996 case PH_ACTIVATE_CNF:
1997 case DL_ESTABLISH_CNF:
1998 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1999 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
2002 case PH_DEACTIVATE_IND:
2003 case DL_RELEASE_IND:
2004 case PH_DEACTIVATE_CNF:
2005 case DL_RELEASE_CNF:
2006 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2007 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2011 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2017 /* process timer events for bchannel handling */
2018 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2020 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2023 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2029 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2033 * l3m must be queued, except for MT_ASSIGN
2036 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2039 /* special MT_ASSIGN handling:
2041 * if we request a PID from mlayer, we always do it while lcr is locked.
2042 * therefore we must check the MT_ASSIGN reply first before we lock.
2043 * this is because the MT_ASSIGN reply is received with the requesting
2044 * process, not by the mlayer thread!
2045 * this means, that the reply is sent during call of the request.
2046 * we must check if we get a reply and we know that we lcr is currently
2049 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2050 /* let's do some checking if someone changes stack behaviour */
2051 if (mt_assign_pid != 0)
2052 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2053 mt_assign_pid = pid;
2056 /* queue message, create, if required */
2058 l3m = alloc_l3_msg();
2060 FATAL("No memory for layer 3 message\n");
2062 mb = container_of(l3m, struct mbuffer, l3);
2065 mqueue_tail(&mISDNport->upqueue, mb);
2066 if (!upqueue_avail) {
2067 // multiple threads may cause multiple calls of this section, but this
2068 // results only in multiple processing of the upqueue read.
2069 // this is no problem.
2073 ret = write(upqueue_pipe[1], &byte, 1);
2078 int mISDN_getportbyname(int sock, int cnt, char *portname)
2080 struct mISDN_devinfo devinfo;
2084 while (port < cnt) {
2086 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2089 if (!strcasecmp(devinfo.name, portname))
2100 * global function to add a new card (port)
2102 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2105 struct mISDNport *mISDNport, **mISDNportp;
2106 int port = ifport->portnum;
2107 int ptp = ifport->ptp;
2108 int force_nt = ifport->nt;
2109 int l1hold = ifport->l1hold;
2110 int l2hold = ifport->l2hold;
2111 int gsm = ifport->gsm;
2112 int ss5 = ifport->ss5;
2116 // struct mlayer3 *ml3;
2117 struct mISDN_devinfo devinfo;
2118 unsigned int protocol, prop;
2120 /* check port counts */
2121 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2123 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2128 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2132 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2135 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
2137 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2140 // note: 'port' has still the port number
2142 if (port>cnt || port<0) {
2143 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2147 /* get port attributes */
2148 pri = bri = pots = nt = te = 0;
2150 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2152 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2155 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2159 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2163 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2167 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2172 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2178 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2183 if (force_nt && !nt) {
2184 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2188 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2191 if (pots && !bri && !pri) {
2192 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2196 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2200 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2203 /* set NT by turning off TE */
2206 /* if TE an NT is supported (and not forced to NT), turn off NT */
2210 /* check for double use of port */
2212 mISDNport = mISDNport_first;
2214 if (mISDNport->portnum == port)
2216 mISDNport = mISDNport->next;
2219 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2224 /* check for continous channelmap with no bchannel on slot 16 */
2225 if (test_channelmap(0, devinfo.channelmap)) {
2226 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2230 while(i < (int)devinfo.nrbchan + 1) {
2232 if (test_channelmap(i, devinfo.channelmap)) {
2233 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2237 if (!test_channelmap(i, devinfo.channelmap)) {
2238 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2245 /* add mISDNport structure */
2246 mISDNportp = &mISDNport_first;
2248 mISDNportp = &((*mISDNportp)->next);
2249 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2250 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2252 /* gsm/ss5 link is always active */
2253 mISDNport->l1link = 1;
2254 mISDNport->l2link = 1;
2256 mISDNport->l1link = -1;
2257 mISDNport->l2link = -1;
2259 mISDNport->gsm = gsm;
2261 *mISDNportp = mISDNport;
2263 /* if pri, must set PTP */
2267 /* set ss5 params */
2269 /* try to keep interface enabled */
2289 /* allocate ressources of port */
2290 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2291 prop = (1 << MISDN_FLG_L2_CLEAN);
2292 if (ptp) // ptp forced
2293 prop |= (1 << MISDN_FLG_PTP);
2294 if (nt) // supports hold/retrieve on nt-mode
2295 prop |= (1 << MISDN_FLG_NET_HOLD);
2296 if (l1hold) // supports layer 1 hold
2297 prop |= (1 << MISDN_FLG_L1_HOLD);
2298 if (l2hold) // supports layer 2 hold
2299 prop |= (1 << MISDN_FLG_L2_HOLD);
2300 /* open layer 3 and init upqueue */
2302 unsigned long on = 1;
2303 struct sockaddr_mISDN addr;
2305 if (devinfo.nrbchan < 8) {
2306 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2307 mISDNport_close(mISDNport);
2311 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2312 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2313 mISDNport_close(mISDNport);
2316 /* set nonblocking io */
2317 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2318 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2319 mISDNport_close(mISDNport);
2322 /* bind socket to dchannel */
2323 memset(&addr, 0, sizeof(addr));
2324 addr.family = AF_ISDN;
2327 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2328 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2329 mISDNport_close(mISDNport);
2333 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2334 mqueue_init(&mISDNport->upqueue);
2335 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2336 if (!mISDNport->ml3) {
2337 mqueue_purge(&mISDNport->upqueue);
2338 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2346 "PORT (open failed)");
2348 mISDNport_close(mISDNport);
2353 SCPY(mISDNport->name, devinfo.name);
2354 mISDNport->b_num = devinfo.nrbchan;
2355 mISDNport->portnum = port;
2356 mISDNport->ntmode = nt;
2357 mISDNport->tespecial = ifport->tespecial;
2358 mISDNport->pri = pri;
2359 mISDNport->ptp = ptp;
2360 mISDNport->l1hold = l1hold;
2361 mISDNport->l2hold = l2hold;
2362 mISDNport->ss5 = ss5;
2363 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2365 while(i < mISDNport->b_num) {
2366 mISDNport->b_state[i] = B_STATE_IDLE;
2367 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2371 /* if ptp, pull up the link */
2372 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2373 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2374 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2375 add_trace("tei", NULL, "%d", 0);
2377 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2380 /* for nt-mode ptmp the link is always up */
2381 if (mISDNport->ntmode && !mISDNport->ptp)
2382 mISDNport->l2link = 1;
2384 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2386 start_trace(mISDNport->portnum,
2394 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2395 add_trace("channels", NULL, "%d", mISDNport->b_num);
2397 add_trace("ccitt#5", NULL, "enabled");
2405 * load static port instances, if required by mISDNport
2407 void mISDNport_static(struct mISDNport *mISDNport)
2412 while(i < mISDNport->b_num) {
2415 ss5_create_channel(mISDNport, i);
2423 * function to free ALL cards (ports)
2425 void mISDNport_close_all(void)
2427 /* free all ports */
2428 while(mISDNport_first)
2429 mISDNport_close(mISDNport_first);
2433 * free only one port
2435 void mISDNport_close(struct mISDNport *mISDNport)
2437 struct mISDNport **mISDNportp;
2439 class PmISDN *isdnport;
2442 /* remove all port instance that are linked to this mISDNport */
2446 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2447 isdnport = (class PmISDN *)port;
2448 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2449 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2457 /* only if we are already part of interface */
2458 if (mISDNport->ifport) {
2459 start_trace(mISDNport->portnum,
2460 mISDNport->ifport->interface,
2470 /* free bchannels */
2472 while(i < mISDNport->b_num) {
2473 if (mISDNport->b_sock[i].inuse) {
2474 _bchannel_destroy(mISDNport, i);
2475 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2477 if (mISDNport->b_timer[i].inuse) {
2478 del_timer(&mISDNport->b_timer[i]);
2482 del_timer(&mISDNport->l2establish);
2484 /* close layer 3, if open */
2485 if (!mISDNport->gsm && mISDNport->ml3) {
2486 close_layer3(mISDNport->ml3);
2489 /* close gsm socket, if open */
2490 if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2491 close(mISDNport->lcr_sock);
2495 if (!mISDNport->gsm)
2496 mqueue_purge(&mISDNport->upqueue);
2498 /* remove from list */
2499 mISDNportp = &mISDNport_first;
2500 while(*mISDNportp) {
2501 if (*mISDNportp == mISDNport) {
2502 *mISDNportp = (*mISDNportp)->next;
2506 mISDNportp = &((*mISDNportp)->next);
2510 FATAL("mISDNport not in list\n");
2512 FREE(mISDNport, sizeof(struct mISDNport));
2519 * enque data from upper buffer
2521 void PmISDN::txfromup(unsigned char *data, int length)
2523 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2524 struct mISDNhead *hh = (struct mISDNhead *)buf;
2527 if (p_m_b_index < 0)
2529 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2532 /* check if high priority tones exist
2533 * ignore data in this case
2535 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2538 /* preload procedure
2539 * if transmit buffer in DSP module is empty,
2540 * preload it to DSP_LOAD to prevent jitter gaps.
2542 if (p_m_load == 0 && ISDN_LOAD > 0) {
2543 hh->prim = PH_DATA_REQ;
2545 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2546 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2548 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2549 p_m_load += ISDN_LOAD;
2550 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2553 /* drop if load would exceed ISDN_MAXLOAD
2554 * this keeps the delay not too high
2556 if (p_m_load+length > ISDN_MAXLOAD)
2559 /* make and send frame */
2560 hh->prim = PH_DATA_REQ;
2562 memcpy(buf+MISDN_HEADER_LEN, data, length);
2563 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2565 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2569 int PmISDN::inband_send(unsigned char *buffer, int len)
2571 PERROR("this function must be derived to function!\n");
2575 void PmISDN::inband_send_on(void)
2577 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2578 p_m_inband_send_on = 1;
2579 /* trigger inband transmit */
2583 void PmISDN::inband_send_off(void)
2585 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2586 p_m_inband_send_on = 0;
2589 void PmISDN::inband_receive(unsigned char *buffer, int len)
2592 // if (len >= SS5_DECODER_NPOINTS)
2593 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2594 PERROR("this function must be derived to function!\n");
2597 void PmISDN::inband_receive_on(void)
2599 /* this must work during constructor, see ss5.cpp */
2600 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2601 p_m_inband_receive_on = 1;
2605 void PmISDN::inband_receive_off(void)
2607 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2608 p_m_inband_receive_on = 0;
2612 void PmISDN::mute_on(void)
2616 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2618 set_conf(p_m_conf, 0);
2621 void PmISDN::mute_off(void)
2625 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2627 set_conf(0, p_m_conf);