1 /*****************************************************************************\
3 ** Linux Call Router **
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** mISDN port abstraction for dss1 **
10 \*****************************************************************************/
15 #include <mISDN/mISDNcompat.h>
16 int __af_isdn = MISDN_AF_ISDN;
17 #include <mISDN/q931.h>
20 #ifdef __compiler_offsetof
21 #define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
23 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
27 #define container_of(ptr, type, member) ({ \
28 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
29 (type *)( (char *)__mptr - offsetof(type,member) );})
32 // timeouts if activating/deactivating response from mISDN got lost
33 #define B_TIMER_ACTIVATING 1 // seconds
34 #define B_TIMER_DEACTIVATING 1 // seconds
36 /* list of mISDN ports */
37 struct mISDNport *mISDNport_first;
39 /* noise randomizer */
40 unsigned char mISDN_rand[256];
41 int mISDN_rand_count = 0;
43 unsigned int mt_assign_pid = ~0;
46 static int upqueue_pipe[2];
47 static struct lcr_fd upqueue_fd;
48 int upqueue_avail = 0;
50 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i);
51 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i);
53 int mISDN_initialize(void)
57 /* try to open raw socket to check kernel */
58 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
59 if (mISDNsocket < 0) {
60 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN? Protocol family is %d.)\n", strerror(errno), PF_ISDN);
65 init_layer3(4); // buffer of 4
67 /* open debug, if enabled and not only stack debugging */
69 SPRINT(filename, "%s/debug.log", LOG_DIR);
70 debug_fp = fopen(filename, "a");
73 if (options.deb & DEBUG_STACK) {
74 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
75 mISDN_debug_init(0xfffffeff, filename, filename, filename);
77 mISDN_debug_init(0, NULL, NULL, NULL);
79 if (pipe(upqueue_pipe) < 0)
80 FATAL("Failed to open pipe\n");
81 memset(&upqueue_fd, 0, sizeof(upqueue_fd));
82 upqueue_fd.fd = upqueue_pipe[0];
83 register_fd(&upqueue_fd, LCR_FD_READ, mISDN_upqueue, NULL, 0);
88 void mISDN_deinitialize(void)
101 if (upqueue_fd.inuse) {
102 unregister_fd(&upqueue_fd);
103 close(upqueue_pipe[0]);
104 close(upqueue_pipe[1]);
109 int load_timer(struct lcr_timer *timer, void *instance, int index);
114 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
116 p_m_mISDNport = mISDNport;
117 p_m_portnum = mISDNport->portnum;
124 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
125 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
134 p_m_inband_send_on = 0;
135 p_m_inband_receive_on = 0;
136 p_m_dtmf = !mISDNport->ifport->nodtmf;
137 memset(&p_m_timeout, 0, sizeof(p_m_timeout));
138 add_timer(&p_m_timeout, mISDN_timeout, this, 0);
139 p_m_remote_ref = 0; /* channel shall be exported to given remote */
140 p_m_remote_id = 0; /* remote admin socket */
141 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
144 memset(&p_m_loadtimer, 0, sizeof(p_m_loadtimer));
145 add_timer(&p_m_loadtimer, load_timer, this, 0);
151 p_m_crypt_listen = 0;
152 p_m_crypt_msg_loops = 0;
153 p_m_crypt_msg_loops = 0;
154 p_m_crypt_msg_len = 0;
155 p_m_crypt_msg[0] = '\0';
156 p_m_crypt_msg_current = 0;
157 p_m_crypt_key_len = 0;
158 p_m_crypt_listen = 0;
159 p_m_crypt_listen_state = 0;
160 p_m_crypt_listen_len = 0;
161 p_m_crypt_listen_msg[0] = '\0';
162 p_m_crypt_listen_crc = 0;
163 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
164 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
165 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
169 /* if any channel requested by constructor */
170 if (channel == CHANNEL_ANY) {
171 /* reserve channel */
173 mISDNport->b_reserved++;
176 /* reserve channel */
177 if (channel > 0) // only if constructor was called with a channel resevation
178 seize_bchannel(channel, exclusive);
180 /* we increase the number of objects: */
182 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
183 //inband_receive_on();
192 struct lcr_msg *message;
194 del_timer(&p_m_timeout);
195 del_timer(&p_m_loadtimer);
197 /* remove bchannel relation */
201 while (p_epointlist) {
202 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
203 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
204 message->param.disconnectinfo.cause = 16;
205 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
206 message_put(message);
207 /* remove from list */
208 free_epointlist(p_epointlist);
211 /* we decrease the number of objects: */
212 p_m_mISDNport->use--;
213 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
220 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
222 /* init trace with given values */
223 start_trace(mISDNport?mISDNport->portnum:-1,
224 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
225 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
226 port?port->p_dialinginfo.id:NULL,
229 port?port->p_serial:0,
237 static struct isdn_message {
241 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
242 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
243 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
244 {"DL_RELEASE", L2_RELEASE_REQ},
245 {"UNKNOWN", L3_UNKNOWN_REQ},
246 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
247 {"MT_SETUP", L3_SETUP_REQ},
248 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
249 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
250 {"MT_ALERTING", L3_ALERTING_REQ},
251 {"MT_CONNECT", L3_CONNECT_REQ},
252 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
253 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
254 {"MT_RELEASE", L3_RELEASE_REQ},
255 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
256 {"MT_INFORMATION", L3_INFORMATION_REQ},
257 {"MT_PROGRESS", L3_PROGRESS_REQ},
258 {"MT_NOTIFY", L3_NOTIFY_REQ},
259 {"MT_SUSPEND", L3_SUSPEND_REQ},
260 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
261 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
262 {"MT_RESUME", L3_RESUME_REQ},
263 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
264 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
265 {"MT_HOLD", L3_HOLD_REQ},
266 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
267 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
268 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
269 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
270 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
271 {"MT_FACILITY", L3_FACILITY_REQ},
272 {"MT_STATUS", L3_STATUS_REQ},
273 {"MT_RESTART", L3_RESTART_REQ},
274 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
275 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
278 static const char *isdn_prim[4] = {
284 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
289 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
290 /* select message and primitive text */
292 while(isdn_message[i].name) {
293 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
294 if (isdn_message[i].value == (msg&0xffffff00)) {
295 SCPY(msgtext, isdn_message[i].name);
300 SCAT(msgtext, isdn_prim[msg&0x00000003]);
303 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
305 if (mISDNport->ntmode) {
306 if (direction == DIRECTION_OUT)
307 SCAT(msgtext, " N->U");
309 SCAT(msgtext, " N<-U");
311 if (direction == DIRECTION_OUT)
312 SCAT(msgtext, " U->N");
314 SCAT(msgtext, " U<-N");
319 /* init trace with given values */
320 start_trace(mISDNport?mISDNport->portnum:-1,
321 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
322 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
323 port?port->p_dialinginfo.id:NULL,
326 port?port->p_serial:0,
332 * send control information to the channel (dsp-module)
334 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
336 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
337 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
338 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
344 ctrl->prim = PH_CONTROL_REQ;
348 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
350 PERROR("Failed to send to socket %d\n", sock);
351 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
352 if (c1 == DSP_CONF_JOIN)
353 add_trace(trace_name, NULL, "0x%08x", trace_value);
355 add_trace(trace_name, NULL, "%d", trace_value);
359 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)
361 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
362 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
363 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
369 ctrl->prim = PH_CONTROL_REQ;
372 memcpy(d, c2, c2_len);
373 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
375 PERROR("Failed to send to socket %d\n", sock);
376 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
377 add_trace(trace_name, NULL, "%d", trace_value);
381 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i);
384 * subfunction for bchannel_event
387 static int _bchannel_create(struct mISDNport *mISDNport, int i)
390 struct sockaddr_mISDN addr;
392 if (mISDNport->b_sock[i].inuse) {
393 PERROR("Error: Socket already created for index %d\n", i);
398 //#warning testing without DSP
399 // 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);
400 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);
401 if (mISDNport->b_sock[i].fd < 0) {
402 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
406 /* register callback for read */
407 register_fd(&mISDNport->b_sock[i], LCR_FD_READ, b_sock_callback, mISDNport, i);
409 /* bind socket to bchannel */
410 addr.family = AF_ISDN;
411 addr.dev = mISDNport->portnum;
412 addr.channel = i+1+(i>=15);
413 ret = bind(mISDNport->b_sock[i].fd, (struct sockaddr *)&addr, sizeof(addr));
415 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);
416 close(mISDNport->b_sock[i].fd);
417 unregister_fd(&mISDNport->b_sock[i]);
421 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
422 add_trace("channel", NULL, "%d", i+1+(i>=15));
423 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
431 * subfunction for bchannel_event
432 * activate / deactivate request
434 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate, int timeout)
436 struct mISDNhead act;
439 if (!mISDNport->b_sock[i].inuse)
441 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
443 ret = sendto(mISDNport->b_sock[i].fd, &act, MISDN_HEADER_LEN, 0, NULL, 0);
445 PERROR("Failed to send to socket %d\n", mISDNport->b_sock[i].fd);
448 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
449 add_trace("channel", NULL, "%d", i+1+(i>=15));
451 add_trace("event", NULL, "timeout recovery");
457 * subfunction for bchannel_event
460 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
465 if (!mISDNport->b_sock[i].inuse)
467 handle = mISDNport->b_sock[i].fd;
468 port = mISDNport->b_port[i];
469 mode = mISDNport->b_mode[i];
471 PERROR("bchannel index i=%d not associated with a port object\n", i);
475 /* set dsp features */
476 if (port->p_m_txdata)
477 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
478 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
479 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
480 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
481 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
482 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
483 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
484 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
485 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
486 if (port->p_m_conf && !port->p_m_mute)
487 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
489 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
490 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
491 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
493 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
494 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
495 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
496 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
497 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
498 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
499 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);
503 void PmISDN::set_conf(int oldconf, int newconf)
505 if (oldconf != newconf) {
506 PDEBUG(DEBUG_BCHANNEL, "we change conference from conf=%d to conf=%d.\n", oldconf, newconf);
507 if (p_m_b_index > -1)
508 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
509 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);
511 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", newconf);
516 * subfunction for bchannel_event
519 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
521 if (!mISDNport->b_sock[i].inuse)
523 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
524 add_trace("channel", NULL, "%d", i+1+(i>=15));
525 add_trace("socket", NULL, "%d", mISDNport->b_sock[i].fd);
527 close(mISDNport->b_sock[i].fd);
528 unregister_fd(&mISDNport->b_sock[i]);
536 A bchannel goes through the following states in this order:
539 No one is using the bchannel.
540 It is available and not linked to Port class, nor reserved.
543 The bchannel stack is created and an activation request is sent.
544 It MAY be linked to Port class, but already unlinked due to Port class removal.
547 The bchannel is active and cofigured to the Port class needs.
548 Also it is linked to a Port class, otherwhise it would be deactivated.
550 - B_STATE_DEACTIVATING
551 The bchannel is in deactivating state, due to deactivation request.
552 It may be linked to a Port class, that likes to reactivate it.
556 After deactivating bchannel, and if not used, the bchannel becomes idle again.
558 Also the bchannel may be exported, but only if the state is or becomes idle:
561 The bchannel assignment has been sent to the remove application.
564 The bchannel assignment is acknowledged by the remote application.
567 The bchannel is re-imported by mISDN port object.
571 After re-importing bchannel, and if not used, the bchannel becomes idle again.
574 A bchannel can have the following events:
577 A bchannel is required by a Port class.
580 The bchannel beomes active.
583 The bchannel is not required by Port class anymore
585 - B_EVENT_DEACTIVATED
586 The bchannel becomes inactive.
589 The bchannel is now used by remote application.
592 The bchannel is not used by remote application.
594 - B_EVENT_EXPORTREQUEST
595 The bchannel shall be exported to the remote application.
597 - B_EVENT_IMPORTREQUEST
598 The bchannel is released from the remote application.
600 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
602 if an export request is receive by remote application, p_m_remote_* is set.
603 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.)
604 - set on export request from remote application (if port is assigned)
605 - set on channel use, if requested by remote application (p_m_remote_*)
606 - cleared on drop request
608 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
609 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
610 the bchannel import/export is acknowledged with stack given.
612 if exporting, b_remote_*[index] is set to the remote socket id.
613 if importing has been acknowledged. b_remote_*[index] is cleared.
618 * process bchannel events
619 * - mISDNport is a pointer to the port's structure
620 * - i is the index of the bchannel
621 * - event is the B_EVENT_* value
622 * - port is the PmISDN class pointer
624 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
626 class PmISDN *b_port = mISDNport->b_port[i];
627 int state = mISDNport->b_state[i];
628 int timer = -1; // no change
629 unsigned int p_m_remote_ref = 0;
630 unsigned int p_m_remote_id = 0;
633 char *p_m_pipeline = NULL;
634 unsigned char *p_m_crypt_key = NULL;
635 int p_m_crypt_key_len = 0;
636 int p_m_crypt_key_type = 0;
637 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
640 p_m_remote_id = b_port->p_m_remote_id;
641 p_m_remote_ref = b_port->p_m_remote_ref;
642 p_m_tx_gain = b_port->p_m_tx_gain;
643 p_m_rx_gain = b_port->p_m_rx_gain;
644 p_m_pipeline = b_port->p_m_pipeline;
645 p_m_crypt_key = b_port->p_m_crypt_key;
646 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
647 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
652 /* port must be linked in order to allow activation */
654 FATAL("bchannel must be linked to a Port class\n");
657 if (p_m_remote_ref) {
658 /* export bchannel */
659 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);
660 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
661 add_trace("type", NULL, "assign");
662 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
664 state = B_STATE_EXPORTING;
665 mISDNport->b_remote_id[i] = p_m_remote_id;
666 mISDNport->b_remote_ref[i] = p_m_remote_ref;
668 /* create stack and send activation request */
669 if (_bchannel_create(mISDNport, i)) {
670 _bchannel_activate(mISDNport, i, 1, 0);
671 state = B_STATE_ACTIVATING;
672 timer = B_TIMER_ACTIVATING;
677 case B_STATE_ACTIVATING:
678 case B_STATE_EXPORTING:
679 /* do nothing, because it is already activating */
682 case B_STATE_DEACTIVATING:
683 case B_STATE_IMPORTING:
684 /* do nothing, because we must wait until we can reactivate */
688 /* problems that might ocurr:
689 * B_EVENT_USE is received when channel already in use.
690 * bchannel exported, but not freed by other port
692 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
696 case B_EVENT_EXPORTREQUEST:
697 /* special case where the bchannel is requested by remote */
698 if (!p_m_remote_ref) {
699 PERROR("export request without remote channel set, please correct.\n");
704 /* in case, the bchannel is exported right after seize_bchannel */
705 /* export bchannel */
706 /* p_m_remote_id is set, when this event happens. */
707 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);
708 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
709 add_trace("type", NULL, "assign");
710 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
712 state = B_STATE_EXPORTING;
713 mISDNport->b_remote_id[i] = p_m_remote_id;
714 mISDNport->b_remote_ref[i] = p_m_remote_ref;
717 case B_STATE_ACTIVATING:
718 case B_STATE_EXPORTING:
719 /* do nothing, because it is already activating */
722 case B_STATE_DEACTIVATING:
723 case B_STATE_IMPORTING:
724 /* do nothing, because we must wait until we can reactivate */
728 /* bchannel is active, so we deactivate */
729 _bchannel_activate(mISDNport, i, 0, 0);
730 state = B_STATE_DEACTIVATING;
731 timer = B_TIMER_DEACTIVATING;
735 /* problems that might ocurr:
736 * ... when channel already in use.
737 * bchannel exported, but not freed by other port
739 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
743 case B_EVENT_IMPORTREQUEST:
744 /* special case where the bchannel is released by remote */
745 if (p_m_remote_ref) {
746 PERROR("import request with remote channel set, please correct.\n");
752 /* bchannel is not exported */
755 case B_STATE_ACTIVATING:
756 case B_STATE_EXPORTING:
757 /* do nothing because we must wait until bchanenl is active before deactivating */
761 /* bchannel is exported, so we re-import */
762 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
763 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
764 add_trace("type", NULL, "remove");
765 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
767 state = B_STATE_IMPORTING;
770 case B_STATE_DEACTIVATING:
771 case B_STATE_IMPORTING:
772 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
776 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
780 case B_EVENT_ACTIVATED:
783 case B_STATE_ACTIVATING:
784 if (b_port && !p_m_remote_id) {
785 /* bchannel is active and used by Port class, so we configure bchannel */
786 _bchannel_configure(mISDNport, i);
787 state = B_STATE_ACTIVE;
788 b_port->p_m_load = 0;
790 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
791 _bchannel_activate(mISDNport, i, 0, 0);
792 state = B_STATE_DEACTIVATING;
793 timer = B_TIMER_DEACTIVATING;
798 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
802 case B_EVENT_EXPORTED:
804 case B_STATE_EXPORTING:
805 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
806 /* remote export done */
807 state = B_STATE_REMOTE;
809 /* bchannel is now exported, but we need bchannel back
810 * OR bchannel is not used anymore
811 * OR bchannel has been exported to an obsolete ref,
812 * so reimport, to later export to new remote */
813 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
814 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
815 add_trace("type", NULL, "remove");
816 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
818 state = B_STATE_IMPORTING;
823 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
829 FATAL("bchannel must be linked to a Port class\n");
832 /* bchannel is idle due to an error, so we do nothing */
835 case B_STATE_ACTIVATING:
836 case B_STATE_EXPORTING:
837 /* do nothing because we must wait until bchanenl is active before deactivating */
841 /* bchannel is active, so we deactivate */
842 _bchannel_activate(mISDNport, i, 0, 0);
843 state = B_STATE_DEACTIVATING;
844 timer = B_TIMER_DEACTIVATING;
848 /* bchannel is exported, so we re-import */
849 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
850 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
851 add_trace("type", NULL, "remove");
852 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
854 state = B_STATE_IMPORTING;
857 case B_STATE_DEACTIVATING:
858 case B_STATE_IMPORTING:
859 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
863 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
867 case B_EVENT_DEACTIVATED:
871 /* ignore due to deactivation confirm after unloading */
874 case B_STATE_DEACTIVATING:
875 _bchannel_destroy(mISDNport, i);
876 state = B_STATE_IDLE;
878 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
879 if (p_m_remote_ref) {
880 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);
881 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
882 add_trace("type", NULL, "assign");
883 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
885 state = B_STATE_EXPORTING;
886 mISDNport->b_remote_id[i] = p_m_remote_id;
887 mISDNport->b_remote_ref[i] = p_m_remote_ref;
889 if (_bchannel_create(mISDNport, i)) {
890 _bchannel_activate(mISDNport, i, 1, 0);
891 state = B_STATE_ACTIVATING;
892 timer = B_TIMER_ACTIVATING;
899 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
903 case B_EVENT_IMPORTED:
905 case B_STATE_IMPORTING:
906 state = B_STATE_IDLE;
907 mISDNport->b_remote_id[i] = 0;
908 mISDNport->b_remote_ref[i] = 0;
910 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
911 if (p_m_remote_ref) {
912 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);
913 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
914 add_trace("type", NULL, "assign");
915 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
917 state = B_STATE_EXPORTING;
918 mISDNport->b_remote_id[i] = p_m_remote_id;
919 mISDNport->b_remote_ref[i] = p_m_remote_ref;
921 if (_bchannel_create(mISDNport, i)) {
922 _bchannel_activate(mISDNport, i, 1, 0);
923 state = B_STATE_ACTIVATING;
924 timer = B_TIMER_ACTIVATING;
931 /* ignore, because not assigned */
936 case B_EVENT_TIMEOUT:
940 /* ignore due to deactivation confirm after unloading */
943 case B_STATE_ACTIVATING:
944 _bchannel_activate(mISDNport, i, 1, 1);
945 timer = B_TIMER_ACTIVATING;
948 case B_STATE_DEACTIVATING:
949 _bchannel_activate(mISDNport, i, 0, 1);
950 timer = B_TIMER_DEACTIVATING;
954 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
959 PERROR("Illegal event %d, please correct.\n", event);
962 mISDNport->b_state[i] = state;
964 unsched_timer(&mISDNport->b_timer[i]);
966 schedule_timer(&mISDNport->b_timer[i], timer, 0);
973 * check for available channel and reserve+set it.
974 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
976 * returns -(cause value) or x = channel x or 0 = no channel
977 * NOTE: no activation is done here
979 int PmISDN::seize_bchannel(int channel, int exclusive)
983 /* the channel is what we have */
984 if (p_m_b_channel == channel)
987 /* if channel already in use, release it */
992 if (channel==CHANNEL_NO || channel==0)
995 /* is channel in range ? */
997 || (channel>p_m_mISDNport->b_num && channel<16)
998 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
999 return(-6); /* channel unacceptable */
1001 /* request exclusive channel */
1002 if (exclusive && channel>0) {
1003 i = channel-1-(channel>16);
1004 if (p_m_mISDNport->b_port[i])
1005 return(-44); /* requested channel not available */
1009 /* ask for channel */
1011 i = channel-1-(channel>16);
1012 if (p_m_mISDNport->b_port[i] == NULL)
1016 /* search for channel */
1018 while(i < p_m_mISDNport->b_num) {
1019 if (!p_m_mISDNport->b_port[i]) {
1020 channel = i+1+(i>=15);
1025 return(-34); /* no free channel */
1028 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1030 /* link Port, set parameters */
1031 p_m_mISDNport->b_port[i] = this;
1033 p_m_b_channel = channel;
1034 p_m_b_exclusive = exclusive;
1035 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1037 /* reserve channel */
1038 if (!p_m_b_reserve) {
1040 p_m_mISDNport->b_reserved++;
1047 * drop reserved channel and unset it.
1048 * deactivation is also done
1050 void PmISDN::drop_bchannel(void)
1052 /* unreserve channel */
1054 p_m_mISDNport->b_reserved--;
1058 if (p_m_b_index < 0)
1063 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1065 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1066 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1067 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1068 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1071 p_m_b_exclusive = 0;
1074 /* process bchannel export/import message from join */
1075 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1077 class Endpoint *epoint;
1079 class PmISDN *isdnport;
1080 struct mISDNport *mISDNport;
1084 case BCHANNEL_REQUEST:
1085 /* find the port object for the join object ref */
1086 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1087 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1090 if (!epoint->ep_portlist) {
1091 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1094 if (epoint->ep_portlist->next) {
1095 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);
1097 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1098 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1101 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1102 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1104 isdnport = (class PmISDN *)port;
1107 if (isdnport->p_m_remote_id) {
1108 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1111 mISDNport = isdnport->p_m_mISDNport;
1112 i = isdnport->p_m_b_index;
1113 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1114 add_trace("type", NULL, "export request");
1116 isdnport->p_m_remote_ref = joinremote->j_serial;
1117 isdnport->p_m_remote_id = joinremote->j_remote_id;
1118 if (mISDNport && i>=0) {
1119 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1123 case BCHANNEL_RELEASE:
1124 case BCHANNEL_ASSIGN_ACK:
1125 case BCHANNEL_REMOVE_ACK:
1126 /* find mISDNport for stack ID */
1127 mISDNport = mISDNport_first;
1130 ii = mISDNport->b_num;
1132 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1138 mISDNport = mISDNport->next;
1141 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1145 if (type!=BCHANNEL_RELEASE) {
1147 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1148 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1150 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1153 isdnport = mISDNport->b_port[i];
1154 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1155 add_trace("type", NULL, "import request");
1158 isdnport->p_m_remote_ref = 0;
1159 isdnport->p_m_remote_id = 0;
1161 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1165 PERROR("received wrong bchannel message type %d from remote\n", type);
1173 audio transmission procedure:
1174 -----------------------------
1177 three sources of audio transmission:
1178 - crypto-data high priority
1179 - tones high priority (also high)
1180 - remote-data low priority
1183 a variable that temporarily shows the number of samples elapsed since last transmission process.
1184 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1187 a variable that is increased whenever data is transmitted.
1188 it is decreased while time elapses. it stores the number of samples that
1189 are currently loaded to dsp module.
1190 since clock in dsp module is the same clock for user space process, these
1194 there are two levels:
1195 ISDN_LOAD will give the load that have to be kept in dsp.
1196 ISDN_MAXLOAD will give the maximum load before dropping.
1198 * procedure for low priority data
1199 see txfromup() for procedure
1200 in short: remote data is ignored during high priority tones
1202 * procedure for high priority data
1203 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1204 if no more data is available, load becomes empty again.
1207 0 ISDN_LOAD ISDN_MAXLOAD
1208 +--------------------+----------------------+
1210 +--------------------+----------------------+
1212 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1213 0 ISDN_LOAD ISDN_MAXLOAD
1214 +--------------------+----------------------+
1215 |TTTTTTTTTTTTTTTTTTTT| |
1216 +--------------------+----------------------+
1218 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1219 0 ISDN_LOAD ISDN_MAXLOAD
1220 +--------------------+----------------------+
1221 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1222 +--------------------+----------------------+
1225 void PmISDN::update_load(void)
1227 /* don't trigger load event if: */
1228 if (!p_tone_name[0] && !p_m_crypt_msg_loops && !p_m_inband_send_on)
1231 /* don't trigger load event if event already active */
1232 if (p_m_loadtimer.active)
1235 schedule_timer(&p_m_loadtimer, 0, 0); /* no delay the first time */
1238 int load_timer(struct lcr_timer *timer, void *instance, int index)
1240 class PmISDN *isdnport = (class PmISDN *)instance;
1242 isdnport->load_tx();
1247 void PmISDN::load_tx(void)
1251 struct timeval current_time;
1254 gettimeofday(¤t_time, NULL);
1255 if (p_m_last_tv_sec) {
1256 elapsed = 8000 * (current_time.tv_sec - p_m_last_tv_sec)
1257 + 8 * (current_time.tv_usec/1000 - p_m_last_tv_msec);
1259 /* set clock of last process! */
1260 p_m_last_tv_sec = current_time.tv_sec;
1261 p_m_last_tv_msec = current_time.tv_usec/1000;
1263 /* process only if we have samples and we are active */
1264 if (elapsed && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1266 if (elapsed < p_m_load)
1267 p_m_load -= elapsed;
1271 /* to send data, tone must be on */
1272 if ((p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on) /* what tones? */
1273 && (p_m_load < ISDN_LOAD) /* not too much load? */
1274 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones || p_m_inband_send_on)) { /* connected or inband-tones? */
1275 int tosend = ISDN_LOAD - p_m_load, length;
1276 unsigned char buf[MISDN_HEADER_LEN+tosend];
1277 struct mISDNhead *frm = (struct mISDNhead *)buf;
1278 unsigned char *p = buf+MISDN_HEADER_LEN;
1280 /* copy inband signalling (e.g. used by ss5) */
1281 if (p_m_inband_send_on && tosend) {
1282 tosend -= inband_send(p, tosend);
1285 /* copy crypto loops */
1286 while (p_m_crypt_msg_loops && tosend) {
1287 /* how much do we have to send */
1288 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1291 if (length > tosend)
1294 /* copy message (part) to buffer */
1295 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1298 p_m_crypt_msg_current += length;
1299 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1301 p_m_crypt_msg_current = 0;
1302 p_m_crypt_msg_loops--;
1303 if (!p_m_crypt_msg_loops)
1305 // puts("eine loop weniger");
1313 if (p_tone_name[0] && tosend) {
1314 tosend -= read_audio(p, tosend);
1318 if (ISDN_LOAD - p_m_load - tosend > 0) {
1319 frm->prim = PH_DATA_REQ;
1321 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);
1323 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);
1324 p_m_load += ISDN_LOAD - p_m_load - tosend;
1329 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on || p_m_load) {
1330 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
1334 /* handle timeouts */
1335 static int mISDN_timeout(struct lcr_timer *timer, void *instance, int i)
1337 class PmISDN *isdnport = (class PmISDN *)instance;
1338 struct lcr_msg *message;
1340 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);
1341 /* send timeout to endpoint */
1342 message = message_create(isdnport->p_serial, ACTIVE_EPOINT(isdnport->p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1343 message->param.state = isdnport->p_state;
1344 message_put(message);
1351 * whenever we get audio data from bchannel, we process it here
1353 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1355 unsigned int cont = *((unsigned int *)data);
1356 unsigned char *data_temp;
1357 unsigned int length_temp;
1358 struct lcr_msg *message;
1362 if (hh->prim == PH_CONTROL_IND) {
1364 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1367 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1368 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1369 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1371 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1372 message->param.dtmf = cont & DTMF_TONE_MASK;
1373 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1374 message_put(message);
1379 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1380 add_trace("DSP-CRYPT", NULL, "error");
1382 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1383 message->param.crypt.type = CC_ERROR_IND;
1384 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1385 message_put(message);
1389 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1390 add_trace("DSP-CRYPT", NULL, "ok");
1392 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1393 message->param.crypt.type = CC_ACTBF_CONF;
1394 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1395 message_put(message);
1399 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1400 add_trace("unknown", NULL, "0x%x", cont);
1405 if (hh->prim == PH_CONTROL_IND) {
1408 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1409 add_trace("unknown", NULL, "0x%x", hh->id);
1414 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1416 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1417 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1420 /* see below (same condition) */
1421 if (p_state!=PORT_STATE_CONNECT
1422 && !p_m_mISDNport->tones)
1424 // printf(".");fflush(stdout);return;
1426 record(data, len, 1); // from up
1429 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1430 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1434 /* inband is processed */
1435 if (p_m_inband_receive_on)
1436 inband_receive(data, len);
1438 /* calls will not process any audio data unless
1439 * the call is connected OR tones feature is enabled.
1441 #ifndef DEBUG_COREBRIDGE
1442 if (p_state!=PORT_STATE_CONNECT
1443 && !p_m_mISDNport->tones)
1448 /* the bearer capability must be audio in order to send and receive
1449 * audio prior or after connect.
1451 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1455 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1457 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1463 record(data, len, 0); // from down
1465 /* randomize and listen to crypt message if enabled */
1466 if (p_m_crypt_listen) {
1467 /* the noisy randomizer */
1471 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1473 cryptman_listen_bch(data, len);
1478 /* send data to epoint */
1479 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1482 while(length_temp) {
1483 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1484 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1485 memcpy(message->param.data.data, data_temp, message->param.data.len);
1486 message_put(message);
1487 if (length_temp <= sizeof(message->param.data.data))
1489 data_temp += sizeof(message->param.data.data);
1490 length_temp -= sizeof(message->param.data.data);
1499 void PmISDN::set_echotest(int echo)
1501 if (p_m_echo != echo) {
1503 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1505 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1506 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);
1513 void PmISDN::set_tone(const char *dir, const char *tone)
1518 /* if no directory is given (by extension), we use interface.conf or options.conf */
1519 if (!dir || !dir[0]) {
1520 if (p_m_mISDNport->ifport->tones_dir[0])
1521 dir = p_m_mISDNport->ifport->tones_dir;
1522 else if (options.tones_dir[0])
1523 dir = options.tones_dir;
1528 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1534 /* check for dsp tones */
1535 if (!strcmp(dir, "american"))
1537 if (!strcmp(dir, "german"))
1539 if (!strcmp(dir, "oldgerman"))
1540 dsp = DSP_OLDGERMAN;
1542 /* check if we NOT really have to use a dsp-tone */
1543 if (dsp == DSP_NONE) {
1546 if (p_m_b_index > -1)
1547 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) {
1548 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1549 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1552 Port::set_tone(dir, tone);
1556 /* now we USE dsp-tone, convert name */
1557 if (!strcmp(tone, "dialtone")) {
1559 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1560 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1561 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1563 } else if (!strcmp(tone, "dialpbx")) {
1565 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1566 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1567 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1569 } else if (!strcmp(tone, "ringing")) {
1571 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1572 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1573 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1575 } else if (!strcmp(tone, "ringpbx")) {
1577 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1578 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1579 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1581 } else if (!strcmp(tone, "busy")) {
1584 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1585 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1586 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1588 } else if (!strcmp(tone, "release")) {
1591 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1592 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1593 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1595 } else if (!strcmp(tone, "cause_10"))
1597 else if (!strcmp(tone, "cause_11"))
1599 else if (!strcmp(tone, "cause_22")) {
1601 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1602 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1603 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1605 } else if (!strncmp(tone, "cause_", 6))
1606 id = TONE_SPECIAL_INFO;
1610 /* if we have a tone that is not supported by dsp */
1611 if (id==TONE_OFF && tone[0])
1615 if (p_m_tone != id) {
1618 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1619 if (p_m_b_index > -1)
1620 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)
1621 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);
1623 /* turn user-space tones off in cases of no tone OR dsp tone */
1624 Port::set_tone("",NULL);
1628 /* MESSAGE_mISDNSIGNAL */
1629 //extern struct lcr_msg *dddebug;
1630 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1632 int oldconf, newconf;
1633 switch(param->mISDNsignal.message) {
1634 case mISDNSIGNAL_VOLUME:
1635 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1636 p_m_tx_gain = param->mISDNsignal.tx_gain;
1637 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1638 if (p_m_b_index > -1)
1639 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)
1640 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);
1642 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1643 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1644 p_m_rx_gain = param->mISDNsignal.rx_gain;
1645 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1646 if (p_m_b_index > -1)
1647 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)
1648 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);
1650 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1653 case mISDNSIGNAL_CONF:
1654 oldconf = p_m_mute?0:p_m_conf;
1655 p_m_conf = param->mISDNsignal.conf;
1656 newconf = p_m_mute?0:p_m_conf;
1657 set_conf(oldconf, newconf);
1660 case mISDNSIGNAL_JOINDATA:
1661 if (p_m_joindata != param->mISDNsignal.joindata) {
1662 p_m_joindata = param->mISDNsignal.joindata;
1663 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1666 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1669 case mISDNSIGNAL_DELAY:
1670 if (p_m_delay != param->mISDNsignal.delay) {
1671 p_m_delay = param->mISDNsignal.delay;
1672 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1673 if (p_m_b_index > -1)
1674 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)
1675 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);
1677 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1681 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1686 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1688 struct lcr_msg *message;
1690 switch(param->crypt.type) {
1691 case CC_ACTBF_REQ: /* activate blowfish */
1693 p_m_crypt_key_len = param->crypt.len;
1694 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1695 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1696 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1697 message->param.crypt.type = CC_ERROR_IND;
1698 message_put(message);
1701 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1703 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1704 if (p_m_b_index > -1)
1705 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)
1706 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);
1709 case CC_DACT_REQ: /* deactivate session encryption */
1714 case CR_LISTEN_REQ: /* start listening to messages */
1715 p_m_crypt_listen = 1;
1717 p_m_crypt_listen_state = 0;
1720 case CR_UNLISTEN_REQ: /* stop listening to messages */
1721 p_m_crypt_listen = 0;
1725 case CR_MESSAGE_REQ: /* send message */
1726 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1727 if (!p_m_crypt_msg_len) {
1728 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1731 p_m_crypt_msg_current = 0; /* reset */
1732 p_m_crypt_msg_loops = 6; /* enable */
1736 /* disable txmix, or we get corrupt data due to audio process */
1737 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1738 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1739 ph_control(p_m_mISDNport, this, p_mISDNport->b_sock[p_m_b_index].fd, DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1745 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1751 * endpoint sends messages to the port
1753 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1755 if (Port::message_epoint(epoint_id, message_id, param))
1758 switch(message_id) {
1759 case MESSAGE_DATA: /* tx-data from upper layer */
1760 txfromup(param->data.data, param->data.len);
1763 case MESSAGE_mISDNSIGNAL: /* user command */
1764 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1765 message_mISDNsignal(epoint_id, message_id, param);
1768 case MESSAGE_CRYPT: /* crypt control command */
1769 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1770 message_crypt(epoint_id, message_id, param);
1777 void PmISDN::update_rxoff(void)
1779 /* call bridges in user space OR crypto OR recording */
1780 if (p_m_joindata || p_m_crypt_msg_loops || p_m_crypt_listen || p_record || p_m_inband_receive_on) {
1781 /* rx IS required */
1785 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1786 if (p_m_b_index > -1)
1787 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1788 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1791 /* rx NOT required */
1795 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1796 if (p_m_b_index > -1)
1797 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1798 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1803 /* txdata IS required */
1807 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1808 if (p_m_b_index > -1)
1809 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1810 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1813 /* txdata NOT required */
1817 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1818 if (p_m_b_index > -1)
1819 if (p_m_mISDNport->b_port[p_m_b_index] && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1820 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_sock[p_m_b_index].fd, DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1825 static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1827 struct mISDNport *mISDNport;
1833 /* unset global semaphore */
1835 // with a very small incident, upqueue_avail may be set by mISDN thread and
1836 // another byte may be sent to the pipe, which causes a call to this function
1837 // again with nothing in the upqueue. this is no problem.
1838 ret = read(fd->fd, &byte, 1);
1840 /* process all ports */
1841 mISDNport = mISDNport_first;
1843 /* handle queued up-messages (d-channel) */
1844 if (!mISDNport->gsm) {
1845 while ((mb = mdequeue(&mISDNport->upqueue))) {
1848 case MPH_ACTIVATE_IND:
1849 if (mISDNport->l1link != 1) {
1850 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1852 mISDNport->l1link = 1;
1856 case MPH_DEACTIVATE_IND:
1857 if (mISDNport->l1link != 0) {
1858 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1860 mISDNport->l1link = 0;
1864 case MPH_INFORMATION_IND:
1865 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1867 case L1_SIGNAL_LOS_ON:
1870 case L1_SIGNAL_LOS_OFF:
1873 case L1_SIGNAL_AIS_ON:
1876 case L1_SIGNAL_AIS_OFF:
1879 case L1_SIGNAL_RDI_ON:
1882 case L1_SIGNAL_RDI_OFF:
1885 case L1_SIGNAL_SLIP_TX:
1886 mISDNport->slip_tx++;
1888 case L1_SIGNAL_SLIP_RX:
1889 mISDNport->slip_rx++;
1894 case MT_L2ESTABLISH:
1895 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1896 add_trace("tei", NULL, "%d", l3m->pid);
1898 mISDNport->l2link = 1;
1900 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1901 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1902 if (mISDNport->l2establish.active) {
1903 unsched_timer(&mISDNport->l2establish);
1904 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1911 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1912 if (!mISDNport->l2establish.active) {
1913 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1914 add_trace("tei", NULL, "%d", l3m->pid);
1916 /* down if not nt-ptmp */
1917 if (!mISDNport->ntmode || mISDNport->ptp)
1918 mISDNport->l2link = 0;
1920 if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1921 if (!mISDNport->l2establish.active && mISDNport->l2hold) {
1922 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1923 schedule_timer(&mISDNport->l2establish, 5, 0);
1924 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1930 /* l3-data is sent to LCR */
1931 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1937 mISDNport = mISDNport->next;
1942 /* l2 establish timer fires */
1943 static int l2establish_timeout(struct lcr_timer *timer, void *instance, int i)
1945 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1947 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1948 // PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1949 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1950 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
1956 /* handle frames from bchannel */
1957 static int b_sock_callback(struct lcr_fd *fd, unsigned int what, void *instance, int i)
1959 struct mISDNport *mISDNport = (struct mISDNport *)instance;
1960 unsigned char buffer[2048+MISDN_HEADER_LEN];
1961 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1964 ret = recv(fd->fd, buffer, sizeof(buffer), 0);
1966 PERROR("read error frame, errno %d\n", errno);
1969 if (ret < (int)MISDN_HEADER_LEN) {
1970 PERROR("read short frame, got %d, expected %d\n", ret, (int)MISDN_HEADER_LEN);
1974 /* we don't care about confirms, we use rx data to sync tx */
1978 /* we receive audio data, we respond to it AND we send tones */
1983 case PH_CONTROL_IND:
1984 if (mISDNport->b_port[i])
1985 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1987 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", fd->fd);
1990 case PH_ACTIVATE_IND:
1991 case DL_ESTABLISH_IND:
1992 case PH_ACTIVATE_CNF:
1993 case DL_ESTABLISH_CNF:
1994 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", fd->fd);
1995 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1998 case PH_DEACTIVATE_IND:
1999 case DL_RELEASE_IND:
2000 case PH_DEACTIVATE_CNF:
2001 case DL_RELEASE_CNF:
2002 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", fd->fd);
2003 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
2007 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, fd->fd, ret-MISDN_HEADER_LEN);
2013 /* process timer events for bchannel handling */
2014 static int b_timer_timeout(struct lcr_timer *timer, void *instance, int i)
2016 struct mISDNport *mISDNport = (struct mISDNport *)instance;
2019 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
2025 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2029 * l3m must be queued, except for MT_ASSIGN
2032 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2035 /* special MT_ASSIGN handling:
2037 * if we request a PID from mlayer, we always do it while lcr is locked.
2038 * therefore we must check the MT_ASSIGN reply first before we lock.
2039 * this is because the MT_ASSIGN reply is received with the requesting
2040 * process, not by the mlayer thread!
2041 * this means, that the reply is sent during call of the request.
2042 * we must check if we get a reply and we know that we lcr is currently
2045 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
2046 /* let's do some checking if someone changes stack behaviour */
2047 if (mt_assign_pid != 0)
2048 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2049 mt_assign_pid = pid;
2052 /* queue message, create, if required */
2054 l3m = alloc_l3_msg();
2056 FATAL("No memory for layer 3 message\n");
2058 mb = container_of(l3m, struct mbuffer, l3);
2061 mqueue_tail(&mISDNport->upqueue, mb);
2062 if (!upqueue_avail) {
2063 // multiple threads may cause multiple calls of this section, but this
2064 // results only in multiple processing of the upqueue read.
2065 // this is no problem.
2069 ret = write(upqueue_pipe[1], &byte, 1);
2074 int mISDN_getportbyname(int sock, int cnt, char *portname)
2076 struct mISDN_devinfo devinfo;
2080 while (port < cnt) {
2082 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2085 if (!strcasecmp(devinfo.name, portname))
2096 * global function to add a new card (port)
2098 struct mISDNport *mISDNport_open(struct interface_port *ifport)
2101 struct mISDNport *mISDNport, **mISDNportp;
2102 int port = ifport->portnum;
2103 int ptp = ifport->ptp;
2104 int force_nt = ifport->nt;
2105 int l1hold = ifport->l1hold;
2106 int l2hold = ifport->l2hold;
2107 int gsm = ifport->gsm;
2108 int ss5 = ifport->ss5;
2112 // struct mlayer3 *ml3;
2113 struct mISDN_devinfo devinfo;
2114 unsigned int protocol, prop;
2116 /* check port counts */
2117 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2119 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2124 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2128 port = mISDN_getportbyname(mISDNsocket, cnt, ifport->portname);
2131 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", ifport->portname);
2133 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", ifport->portname);
2136 // note: 'port' has still the port number
2138 if (port>cnt || port<0) {
2139 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2143 /* get port attributes */
2144 pri = bri = pots = nt = te = 0;
2146 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2148 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2151 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2155 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2159 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2163 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2168 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2174 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2179 if (force_nt && !nt) {
2180 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2184 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2187 if (pots && !bri && !pri) {
2188 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2192 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2196 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2199 /* set NT by turning off TE */
2202 /* if TE an NT is supported (and not forced to NT), turn off NT */
2206 /* check for double use of port */
2208 mISDNport = mISDNport_first;
2210 if (mISDNport->portnum == port)
2212 mISDNport = mISDNport->next;
2215 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2220 /* check for continous channelmap with no bchannel on slot 16 */
2221 if (test_channelmap(0, devinfo.channelmap)) {
2222 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2226 while(i < (int)devinfo.nrbchan + 1) {
2228 if (test_channelmap(i, devinfo.channelmap)) {
2229 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2233 if (!test_channelmap(i, devinfo.channelmap)) {
2234 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2241 /* add mISDNport structure */
2242 mISDNportp = &mISDNport_first;
2244 mISDNportp = &((*mISDNportp)->next);
2245 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2246 add_timer(&mISDNport->l2establish, l2establish_timeout, mISDNport, 0);
2248 /* gsm/ss5 link is always active */
2249 mISDNport->l1link = 1;
2250 mISDNport->l2link = 1;
2252 mISDNport->l1link = -1;
2253 mISDNport->l2link = -1;
2255 mISDNport->gsm = gsm;
2257 *mISDNportp = mISDNport;
2259 /* if pri, must set PTP */
2263 /* set ss5 params */
2265 /* try to keep interface enabled */
2285 /* allocate ressources of port */
2286 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2287 prop = (1 << MISDN_FLG_L2_CLEAN);
2288 if (ptp) // ptp forced
2289 prop |= (1 << MISDN_FLG_PTP);
2290 if (nt) // supports hold/retrieve on nt-mode
2291 prop |= (1 << MISDN_FLG_NET_HOLD);
2292 if (l1hold) // supports layer 1 hold
2293 prop |= (1 << MISDN_FLG_L1_HOLD);
2294 if (l2hold) // supports layer 2 hold
2295 prop |= (1 << MISDN_FLG_L2_HOLD);
2296 /* open layer 3 and init upqueue */
2298 unsigned long on = 1;
2299 struct sockaddr_mISDN addr;
2301 if (devinfo.nrbchan < 8) {
2302 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2303 mISDNport_close(mISDNport);
2307 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2308 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2309 mISDNport_close(mISDNport);
2312 /* set nonblocking io */
2313 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2314 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2315 mISDNport_close(mISDNport);
2318 /* bind socket to dchannel */
2319 memset(&addr, 0, sizeof(addr));
2320 addr.family = AF_ISDN;
2323 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2324 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2325 mISDNport_close(mISDNport);
2329 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2330 mqueue_init(&mISDNport->upqueue);
2331 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2332 if (!mISDNport->ml3) {
2333 mqueue_purge(&mISDNport->upqueue);
2334 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2342 "PORT (open failed)");
2344 mISDNport_close(mISDNport);
2349 SCPY(mISDNport->name, devinfo.name);
2350 mISDNport->b_num = devinfo.nrbchan;
2351 mISDNport->portnum = port;
2352 mISDNport->ntmode = nt;
2353 mISDNport->tespecial = ifport->tespecial;
2354 mISDNport->pri = pri;
2355 mISDNport->ptp = ptp;
2356 mISDNport->l1hold = l1hold;
2357 mISDNport->l2hold = l2hold;
2358 mISDNport->ss5 = ss5;
2359 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2361 while(i < mISDNport->b_num) {
2362 mISDNport->b_state[i] = B_STATE_IDLE;
2363 add_timer(&mISDNport->b_timer[i], b_timer_timeout, mISDNport, i);
2367 /* if ptp, pull up the link */
2368 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2369 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2370 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2371 add_trace("tei", NULL, "%d", 0);
2373 schedule_timer(&mISDNport->l2establish, 5, 0); /* 5 seconds */
2376 /* for nt-mode ptmp the link is always up */
2377 if (mISDNport->ntmode && !mISDNport->ptp)
2378 mISDNport->l2link = 1;
2380 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2382 start_trace(mISDNport->portnum,
2390 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2391 add_trace("channels", NULL, "%d", mISDNport->b_num);
2393 add_trace("ccitt#5", NULL, "enabled");
2401 * load static port instances, if required by mISDNport
2403 void mISDNport_static(struct mISDNport *mISDNport)
2408 while(i < mISDNport->b_num) {
2411 ss5_create_channel(mISDNport, i);
2419 * function to free ALL cards (ports)
2421 void mISDNport_close_all(void)
2423 /* free all ports */
2424 while(mISDNport_first)
2425 mISDNport_close(mISDNport_first);
2429 * free only one port
2431 void mISDNport_close(struct mISDNport *mISDNport)
2433 struct mISDNport **mISDNportp;
2435 class PmISDN *isdnport;
2438 /* remove all port instance that are linked to this mISDNport */
2442 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2443 isdnport = (class PmISDN *)port;
2444 if (isdnport->p_m_mISDNport && isdnport->p_m_mISDNport == mISDNport) {
2445 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2453 /* only if we are already part of interface */
2454 if (mISDNport->ifport) {
2455 start_trace(mISDNport->portnum,
2456 mISDNport->ifport->interface,
2466 /* free bchannels */
2468 while(i < mISDNport->b_num) {
2469 if (mISDNport->b_sock[i].inuse) {
2470 _bchannel_destroy(mISDNport, i);
2471 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2473 if (mISDNport->b_timer[i].inuse) {
2474 del_timer(&mISDNport->b_timer[i]);
2478 del_timer(&mISDNport->l2establish);
2480 /* close layer 3, if open */
2481 if (!mISDNport->gsm && mISDNport->ml3) {
2482 close_layer3(mISDNport->ml3);
2485 /* close gsm socket, if open */
2486 if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2487 close(mISDNport->lcr_sock);
2491 if (!mISDNport->gsm)
2492 mqueue_purge(&mISDNport->upqueue);
2494 /* remove from list */
2495 mISDNportp = &mISDNport_first;
2496 while(*mISDNportp) {
2497 if (*mISDNportp == mISDNport) {
2498 *mISDNportp = (*mISDNportp)->next;
2502 mISDNportp = &((*mISDNportp)->next);
2506 FATAL("mISDNport not in list\n");
2508 FREE(mISDNport, sizeof(struct mISDNport));
2515 * enque data from upper buffer
2517 void PmISDN::txfromup(unsigned char *data, int length)
2519 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2520 struct mISDNhead *hh = (struct mISDNhead *)buf;
2523 if (p_m_b_index < 0)
2525 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2528 /* check if high priority tones exist
2529 * ignore data in this case
2531 if (p_tone_name[0] || p_m_crypt_msg_loops || p_m_inband_send_on)
2534 /* preload procedure
2535 * if transmit buffer in DSP module is empty,
2536 * preload it to DSP_LOAD to prevent jitter gaps.
2538 if (p_m_load == 0 && ISDN_LOAD > 0) {
2539 hh->prim = PH_DATA_REQ;
2541 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2542 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2544 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2545 p_m_load += ISDN_LOAD;
2546 schedule_timer(&p_m_loadtimer, 0, ISDN_TRANSMIT*125);
2549 /* drop if load would exceed ISDN_MAXLOAD
2550 * this keeps the delay not too high
2552 if (p_m_load+length > ISDN_MAXLOAD)
2555 /* make and send frame */
2556 hh->prim = PH_DATA_REQ;
2558 memcpy(buf+MISDN_HEADER_LEN, data, length);
2559 ret = sendto(p_m_mISDNport->b_sock[p_m_b_index].fd, buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2561 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_sock[p_m_b_index].fd);
2565 int PmISDN::inband_send(unsigned char *buffer, int len)
2567 PERROR("this function must be derived to function!\n");
2571 void PmISDN::inband_send_on(void)
2573 PDEBUG(DEBUG_PORT, "turning inband signalling send on.\n");
2574 p_m_inband_send_on = 1;
2575 /* trigger inband transmit */
2579 void PmISDN::inband_send_off(void)
2581 PDEBUG(DEBUG_PORT, "turning inband signalling send off.\n");
2582 p_m_inband_send_on = 0;
2585 void PmISDN::inband_receive(unsigned char *buffer, int len)
2588 // if (len >= SS5_DECODER_NPOINTS)
2589 // ss5_decode(buffer, SS5_DECODER_NPOINTS);
2590 PERROR("this function must be derived to function!\n");
2593 void PmISDN::inband_receive_on(void)
2595 /* this must work during constructor, see ss5.cpp */
2596 PDEBUG(DEBUG_PORT, "turning inband signalling receive on.\n");
2597 p_m_inband_receive_on = 1;
2601 void PmISDN::inband_receive_off(void)
2603 PDEBUG(DEBUG_PORT, "turning inband signalling receive off.\n");
2604 p_m_inband_receive_on = 0;
2608 void PmISDN::mute_on(void)
2612 PDEBUG(DEBUG_PORT, "turning mute on.\n");
2614 set_conf(p_m_conf, 0);
2617 void PmISDN::mute_off(void)
2621 PDEBUG(DEBUG_PORT, "turning mute off.\n");
2623 set_conf(0, p_m_conf);