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;
49 int mISDN_initialize(void)
55 /* try to open raw socket to check kernel */
56 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
57 if (mISDNsocket < 0) {
58 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
63 init_layer3(4); // buffer of 4
65 /* open debug, if enabled and not only stack debugging */
67 SPRINT(filename, "%s/debug.log", LOG_DIR);
68 debug_fp = fopen(filename, "a");
71 if (options.deb & DEBUG_STACK) {
72 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
73 mISDN_debug_init(0xfffffeff, filename, filename, filename);
75 mISDN_debug_init(0, NULL, NULL, NULL);
80 void mISDN_deinitialize(void)
97 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
99 p_m_mISDNport = mISDNport;
100 p_m_portnum = mISDNport->portnum;
108 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
109 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
117 p_m_dtmf = !mISDNport->ifport->nodtmf;
120 p_m_remote_ref = 0; /* channel shall be exported to given remote */
121 p_m_remote_id = 0; /* remote admin socket */
122 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
130 p_m_crypt_listen = 0;
131 p_m_crypt_msg_loops = 0;
132 p_m_crypt_msg_loops = 0;
133 p_m_crypt_msg_len = 0;
134 p_m_crypt_msg[0] = '\0';
135 p_m_crypt_msg_current = 0;
136 p_m_crypt_key_len = 0;
137 p_m_crypt_listen = 0;
138 p_m_crypt_listen_state = 0;
139 p_m_crypt_listen_len = 0;
140 p_m_crypt_listen_msg[0] = '\0';
141 p_m_crypt_listen_crc = 0;
142 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
143 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
144 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
148 /* if any channel requested by constructor */
149 if (channel == CHANNEL_ANY) {
150 /* reserve channel */
152 mISDNport->b_reserved++;
155 /* reserve channel */
156 if (channel > 0) // only if constructor was called with a channel resevation
157 seize_bchannel(channel, exclusive);
159 /* we increase the number of objects: */
161 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
170 struct lcr_msg *message;
172 /* remove bchannel relation */
176 while (p_epointlist) {
177 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
178 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
179 message->param.disconnectinfo.cause = 16;
180 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
181 message_put(message);
182 /* remove from list */
183 free_epointlist(p_epointlist);
186 /* we decrease the number of objects: */
187 p_m_mISDNport->use--;
188 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
195 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
197 /* init trace with given values */
198 start_trace(mISDNport?mISDNport->portnum:-1,
199 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
200 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
201 port?port->p_dialinginfo.id:NULL,
204 port?port->p_serial:0,
212 static struct isdn_message {
216 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
217 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
218 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
219 {"DL_RELEASE", L2_RELEASE_REQ},
220 {"UNKNOWN", L3_UNKNOWN_REQ},
221 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
222 {"MT_SETUP", L3_SETUP_REQ},
223 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
224 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
225 {"MT_ALERTING", L3_ALERTING_REQ},
226 {"MT_CONNECT", L3_CONNECT_REQ},
227 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
228 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
229 {"MT_RELEASE", L3_RELEASE_REQ},
230 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
231 {"MT_INFORMATION", L3_INFORMATION_REQ},
232 {"MT_PROGRESS", L3_PROGRESS_REQ},
233 {"MT_NOTIFY", L3_NOTIFY_REQ},
234 {"MT_SUSPEND", L3_SUSPEND_REQ},
235 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
236 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
237 {"MT_RESUME", L3_RESUME_REQ},
238 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
239 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
240 {"MT_HOLD", L3_HOLD_REQ},
241 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
242 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
243 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
244 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
245 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
246 {"MT_FACILITY", L3_FACILITY_REQ},
247 {"MT_STATUS", L3_STATUS_REQ},
248 {"MT_RESTART", L3_RESTART_REQ},
249 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
250 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
253 static const char *isdn_prim[4] = {
259 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
264 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
265 /* select message and primitive text */
267 while(isdn_message[i].name) {
268 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
269 if (isdn_message[i].value == (msg&0xffffff00)) {
270 SCPY(msgtext, isdn_message[i].name);
275 SCAT(msgtext, isdn_prim[msg&0x00000003]);
278 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
280 if (mISDNport->ntmode) {
281 if (direction == DIRECTION_OUT)
282 SCAT(msgtext, " N->U");
284 SCAT(msgtext, " N<-U");
286 if (direction == DIRECTION_OUT)
287 SCAT(msgtext, " U->N");
289 SCAT(msgtext, " U<-N");
294 /* init trace with given values */
295 start_trace(mISDNport?mISDNport->portnum:-1,
296 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
297 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
298 port?port->p_dialinginfo.id:NULL,
301 port?port->p_serial:0,
307 * send control information to the channel (dsp-module)
309 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
311 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
312 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
313 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
319 ctrl->prim = PH_CONTROL_REQ;
323 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
325 PERROR("Failed to send to socket %d\n", sock);
326 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
327 if (c1 == DSP_CONF_JOIN)
328 add_trace(trace_name, NULL, "0x%08x", trace_value);
330 add_trace(trace_name, NULL, "%d", trace_value);
334 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)
336 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
337 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
338 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
344 ctrl->prim = PH_CONTROL_REQ;
347 memcpy(d, c2, c2_len);
348 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
350 PERROR("Failed to send to socket %d\n", sock);
351 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
352 add_trace(trace_name, NULL, "%d", trace_value);
358 * subfunction for bchannel_event
361 static int _bchannel_create(struct mISDNport *mISDNport, int i)
365 struct sockaddr_mISDN addr;
367 if (mISDNport->b_socket[i] > -1) {
368 PERROR("Error: Socket already created for index %d\n", i);
373 //#warning testing without DSP
374 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
375 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
376 if (mISDNport->b_socket[i] < 0) {
377 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
381 /* set nonblocking io */
382 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
384 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
385 close(mISDNport->b_socket[i]);
386 mISDNport->b_socket[i] = -1;
390 /* bind socket to bchannel */
391 addr.family = AF_ISDN;
392 addr.dev = mISDNport->portnum;
393 addr.channel = i+1+(i>=15);
394 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
396 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);
397 close(mISDNport->b_socket[i]);
398 mISDNport->b_socket[i] = -1;
402 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
403 add_trace("channel", NULL, "%d", i+1+(i>=15));
404 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
412 * subfunction for bchannel_event
413 * activate / deactivate request
415 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
417 struct mISDNhead act;
420 if (mISDNport->b_socket[i] < 0)
422 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
424 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
426 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
429 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
430 add_trace("channel", NULL, "%d", i+1+(i>=15));
431 if (mISDNport->b_timer[i])
432 add_trace("event", NULL, "timeout recovery");
438 * subfunction for bchannel_event
441 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
446 if (mISDNport->b_socket[i] < 0)
448 handle = mISDNport->b_socket[i];
449 port = mISDNport->b_port[i];
450 mode = mISDNport->b_mode[i];
452 PERROR("bchannel index i=%d not associated with a port object\n", i);
456 /* set dsp features */
457 if (port->p_m_txdata)
458 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
459 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
460 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
461 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
462 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
463 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
464 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
465 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
466 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
468 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
470 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
471 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
472 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
474 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
475 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
476 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
477 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
478 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
479 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
480 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);
484 * subfunction for bchannel_event
487 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
489 if (mISDNport->b_socket[i] < 0)
491 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
492 add_trace("channel", NULL, "%d", i+1+(i>=15));
493 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
495 close(mISDNport->b_socket[i]);
496 mISDNport->b_socket[i] = -1;
504 A bchannel goes through the following states in this order:
507 No one is using the bchannel.
508 It is available and not linked to Port class, nor reserved.
511 The bchannel stack is created and an activation request is sent.
512 It MAY be linked to Port class, but already unlinked due to Port class removal.
515 The bchannel is active and cofigured to the Port class needs.
516 Also it is linked to a Port class, otherwhise it would be deactivated.
518 - B_STATE_DEACTIVATING
519 The bchannel is in deactivating state, due to deactivation request.
520 It may be linked to a Port class, that likes to reactivate it.
524 After deactivating bchannel, and if not used, the bchannel becomes idle again.
526 Also the bchannel may be exported, but only if the state is or becomes idle:
529 The bchannel assignment has been sent to the remove application.
532 The bchannel assignment is acknowledged by the remote application.
535 The bchannel is re-imported by mISDN port object.
539 After re-importing bchannel, and if not used, the bchannel becomes idle again.
542 A bchannel can have the following events:
545 A bchannel is required by a Port class.
548 The bchannel beomes active.
551 The bchannel is not required by Port class anymore
553 - B_EVENT_DEACTIVATED
554 The bchannel becomes inactive.
557 The bchannel is now used by remote application.
560 The bchannel is not used by remote application.
562 - B_EVENT_EXPORTREQUEST
563 The bchannel shall be exported to the remote application.
565 - B_EVENT_IMPORTREQUEST
566 The bchannel is released from the remote application.
568 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
570 if an export request is receive by remote application, p_m_remote_* is set.
571 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.)
572 - set on export request from remote application (if port is assigned)
573 - set on channel use, if requested by remote application (p_m_remote_*)
574 - cleared on drop request
576 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
577 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
578 the bchannel import/export is acknowledged with stack given.
580 if exporting, b_remote_*[index] is set to the remote socket id.
581 if importing has been acknowledged. b_remote_*[index] is cleared.
586 * process bchannel events
587 * - mISDNport is a pointer to the port's structure
588 * - i is the index of the bchannel
589 * - event is the B_EVENT_* value
590 * - port is the PmISDN class pointer
592 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
594 class PmISDN *b_port = mISDNport->b_port[i];
595 int state = mISDNport->b_state[i];
596 double timer = mISDNport->b_timer[i];
597 unsigned int p_m_remote_ref = 0;
598 unsigned int p_m_remote_id = 0;
601 char *p_m_pipeline = NULL;
602 unsigned char *p_m_crypt_key = NULL;
603 int p_m_crypt_key_len = 0;
604 int p_m_crypt_key_type = 0;
605 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
608 p_m_remote_id = b_port->p_m_remote_id;
609 p_m_remote_ref = b_port->p_m_remote_ref;
610 p_m_tx_gain = b_port->p_m_tx_gain;
611 p_m_rx_gain = b_port->p_m_rx_gain;
612 p_m_pipeline = b_port->p_m_pipeline;
613 p_m_crypt_key = b_port->p_m_crypt_key;
614 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
615 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
620 /* port must be linked in order to allow activation */
622 FATAL("bchannel must be linked to a Port class\n");
625 if (p_m_remote_ref) {
626 /* export bchannel */
627 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);
628 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
629 add_trace("type", NULL, "assign");
630 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
632 state = B_STATE_EXPORTING;
633 mISDNport->b_remote_id[i] = p_m_remote_id;
634 mISDNport->b_remote_ref[i] = p_m_remote_ref;
636 /* create stack and send activation request */
637 if (_bchannel_create(mISDNport, i)) {
638 _bchannel_activate(mISDNport, i, 1);
639 state = B_STATE_ACTIVATING;
640 timer = now_d + B_TIMER_ACTIVATING;
645 case B_STATE_ACTIVATING:
646 case B_STATE_EXPORTING:
647 /* do nothing, because it is already activating */
650 case B_STATE_DEACTIVATING:
651 case B_STATE_IMPORTING:
652 /* do nothing, because we must wait until we can reactivate */
656 /* problems that might ocurr:
657 * B_EVENT_USE is received when channel already in use.
658 * bchannel exported, but not freed by other port
660 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
664 case B_EVENT_EXPORTREQUEST:
665 /* special case where the bchannel is requested by remote */
666 if (!p_m_remote_ref) {
667 PERROR("export request without remote channel set, please correct.\n");
672 /* in case, the bchannel is exported right after seize_bchannel */
673 /* export bchannel */
674 /* p_m_remote_id is set, when this event happens. */
675 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);
676 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
677 add_trace("type", NULL, "assign");
678 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
680 state = B_STATE_EXPORTING;
681 mISDNport->b_remote_id[i] = p_m_remote_id;
682 mISDNport->b_remote_ref[i] = p_m_remote_ref;
685 case B_STATE_ACTIVATING:
686 case B_STATE_EXPORTING:
687 /* do nothing, because it is already activating */
690 case B_STATE_DEACTIVATING:
691 case B_STATE_IMPORTING:
692 /* do nothing, because we must wait until we can reactivate */
696 /* bchannel is active, so we deactivate */
697 _bchannel_activate(mISDNport, i, 0);
698 state = B_STATE_DEACTIVATING;
699 timer = now_d + B_TIMER_DEACTIVATING;
703 /* problems that might ocurr:
704 * ... when channel already in use.
705 * bchannel exported, but not freed by other port
707 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
711 case B_EVENT_IMPORTREQUEST:
712 /* special case where the bchannel is released by remote */
713 if (p_m_remote_ref) {
714 PERROR("import request with remote channel set, please correct.\n");
720 /* bchannel is not exported */
723 case B_STATE_ACTIVATING:
724 case B_STATE_EXPORTING:
725 /* do nothing because we must wait until bchanenl is active before deactivating */
729 /* bchannel is exported, so we re-import */
730 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
731 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
732 add_trace("type", NULL, "remove");
733 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
735 state = B_STATE_IMPORTING;
738 case B_STATE_DEACTIVATING:
739 case B_STATE_IMPORTING:
740 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
744 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
748 case B_EVENT_ACTIVATED:
751 case B_STATE_ACTIVATING:
752 if (b_port && !p_m_remote_id) {
753 /* bchannel is active and used by Port class, so we configure bchannel */
754 _bchannel_configure(mISDNport, i);
755 state = B_STATE_ACTIVE;
756 b_port->p_m_load = 0;
758 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
759 _bchannel_activate(mISDNport, i, 0);
760 state = B_STATE_DEACTIVATING;
761 timer = now_d + B_TIMER_DEACTIVATING;
766 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
770 case B_EVENT_EXPORTED:
772 case B_STATE_EXPORTING:
773 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
774 /* remote export done */
775 state = B_STATE_REMOTE;
777 /* bchannel is now exported, but we need bchannel back
778 * OR bchannel is not used anymore
779 * OR bchannel has been exported to an obsolete ref,
780 * so reimport, to later export to new remote */
781 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
782 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
783 add_trace("type", NULL, "remove");
784 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
786 state = B_STATE_IMPORTING;
791 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
797 FATAL("bchannel must be linked to a Port class\n");
800 /* bchannel is idle due to an error, so we do nothing */
803 case B_STATE_ACTIVATING:
804 case B_STATE_EXPORTING:
805 /* do nothing because we must wait until bchanenl is active before deactivating */
809 /* bchannel is active, so we deactivate */
810 _bchannel_activate(mISDNport, i, 0);
811 state = B_STATE_DEACTIVATING;
812 timer = now_d + B_TIMER_DEACTIVATING;
816 /* bchannel is exported, so we re-import */
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;
825 case B_STATE_DEACTIVATING:
826 case B_STATE_IMPORTING:
827 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
831 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
835 case B_EVENT_DEACTIVATED:
839 /* ignore due to deactivation confirm after unloading */
842 case B_STATE_DEACTIVATING:
843 _bchannel_destroy(mISDNport, i);
844 state = B_STATE_IDLE;
846 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
847 if (p_m_remote_ref) {
848 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);
849 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
850 add_trace("type", NULL, "assign");
851 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
853 state = B_STATE_EXPORTING;
854 mISDNport->b_remote_id[i] = p_m_remote_id;
855 mISDNport->b_remote_ref[i] = p_m_remote_ref;
857 if (_bchannel_create(mISDNport, i)) {
858 _bchannel_activate(mISDNport, i, 1);
859 state = B_STATE_ACTIVATING;
860 timer = now_d + B_TIMER_ACTIVATING;
867 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
871 case B_EVENT_IMPORTED:
873 case B_STATE_IMPORTING:
874 state = B_STATE_IDLE;
875 mISDNport->b_remote_id[i] = 0;
876 mISDNport->b_remote_ref[i] = 0;
878 /* bchannel is now imported, 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);
891 state = B_STATE_ACTIVATING;
892 timer = now_d + B_TIMER_ACTIVATING;
899 /* ignore, because not assigned */
904 case B_EVENT_TIMEOUT:
908 /* ignore due to deactivation confirm after unloading */
911 case B_STATE_ACTIVATING:
912 _bchannel_activate(mISDNport, i, 1);
913 timer = now_d + B_TIMER_ACTIVATING;
916 case B_STATE_DEACTIVATING:
917 _bchannel_activate(mISDNport, i, 0);
918 timer = now_d + B_TIMER_DEACTIVATING;
922 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
927 PERROR("Illegal event %d, please correct.\n", event);
930 mISDNport->b_state[i] = state;
931 mISDNport->b_timer[i] = timer;
938 * check for available channel and reserve+set it.
939 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
941 * returns -(cause value) or x = channel x or 0 = no channel
942 * NOTE: no activation is done here
944 int PmISDN::seize_bchannel(int channel, int exclusive)
948 /* the channel is what we have */
949 if (p_m_b_channel == channel)
952 /* if channel already in use, release it */
957 if (channel==CHANNEL_NO || channel==0)
960 /* is channel in range ? */
962 || (channel>p_m_mISDNport->b_num && channel<16)
963 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
964 return(-6); /* channel unacceptable */
966 /* request exclusive channel */
967 if (exclusive && channel>0) {
968 i = channel-1-(channel>16);
969 if (p_m_mISDNport->b_port[i])
970 return(-44); /* requested channel not available */
974 /* ask for channel */
976 i = channel-1-(channel>16);
977 if (p_m_mISDNport->b_port[i] == NULL)
981 /* search for channel */
983 while(i < p_m_mISDNport->b_num) {
984 if (!p_m_mISDNport->b_port[i]) {
985 channel = i+1+(i>=15);
990 return(-34); /* no free channel */
993 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
995 /* link Port, set parameters */
996 p_m_mISDNport->b_port[i] = this;
998 p_m_b_channel = channel;
999 p_m_b_exclusive = exclusive;
1000 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1002 /* reserve channel */
1003 if (!p_m_b_reserve) {
1005 p_m_mISDNport->b_reserved++;
1012 * drop reserved channel and unset it.
1013 * deactivation is also done
1015 void PmISDN::drop_bchannel(void)
1017 /* unreserve channel */
1019 p_m_mISDNport->b_reserved--;
1023 if (p_m_b_index < 0)
1028 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1030 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1031 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1032 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1033 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1036 p_m_b_exclusive = 0;
1039 /* process bchannel export/import message from join */
1040 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1042 class Endpoint *epoint;
1044 class PmISDN *isdnport;
1045 struct mISDNport *mISDNport;
1049 case BCHANNEL_REQUEST:
1050 /* find the port object for the join object ref */
1051 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1052 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1055 if (!epoint->ep_portlist) {
1056 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1059 if (epoint->ep_portlist->next) {
1060 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);
1062 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1063 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1066 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1067 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1069 isdnport = (class PmISDN *)port;
1072 if (isdnport->p_m_remote_id) {
1073 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1076 mISDNport = isdnport->p_m_mISDNport;
1077 i = isdnport->p_m_b_index;
1078 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1079 add_trace("type", NULL, "export request");
1081 isdnport->p_m_remote_ref = joinremote->j_serial;
1082 isdnport->p_m_remote_id = joinremote->j_remote_id;
1083 if (mISDNport && i>=0) {
1084 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1088 case BCHANNEL_RELEASE:
1089 case BCHANNEL_ASSIGN_ACK:
1090 case BCHANNEL_REMOVE_ACK:
1091 /* find mISDNport for stack ID */
1092 mISDNport = mISDNport_first;
1095 ii = mISDNport->b_num;
1097 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1103 mISDNport = mISDNport->next;
1106 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1110 if (type!=BCHANNEL_RELEASE) {
1112 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1113 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1115 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1118 isdnport = mISDNport->b_port[i];
1119 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1120 add_trace("type", NULL, "import request");
1123 isdnport->p_m_remote_ref = 0;
1124 isdnport->p_m_remote_id = 0;
1126 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1130 PERROR("received wrong bchannel message type %d from remote\n", type);
1138 audio transmission procedure:
1139 -----------------------------
1142 three sources of audio transmission:
1143 - crypto-data high priority
1144 - tones high priority (also high)
1145 - remote-data low priority
1148 a variable that temporarily shows the number of samples elapsed since last transmission process.
1149 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1152 a variable that is increased whenever data is transmitted.
1153 it is decreased while time elapses. it stores the number of samples that
1154 are currently loaded to dsp module.
1155 since clock in dsp module is the same clock for user space process, these
1159 there are two levels:
1160 ISDN_LOAD will give the load that have to be kept in dsp.
1161 ISDN_MAXLOAD will give the maximum load before dropping.
1163 * procedure for low priority data
1164 see txfromup() for procedure
1165 in short: remote data is ignored during high priority tones
1167 * procedure for high priority data
1168 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1169 if no more data is available, load becomes empty again.
1172 0 ISDN_LOAD ISDN_MAXLOAD
1173 +--------------------+----------------------+
1175 +--------------------+----------------------+
1177 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1178 0 ISDN_LOAD ISDN_MAXLOAD
1179 +--------------------+----------------------+
1180 |TTTTTTTTTTTTTTTTTTTT| |
1181 +--------------------+----------------------+
1183 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1184 0 ISDN_LOAD ISDN_MAXLOAD
1185 +--------------------+----------------------+
1186 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1187 +--------------------+----------------------+
1190 int PmISDN::handler(void)
1192 struct lcr_msg *message;
1196 if ((ret = Port::handler()))
1200 if (p_m_last_tv_sec) {
1201 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1202 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1204 /* set clock of first process ever in this instance */
1205 p_m_last_tv_sec = now_tv.tv_sec;
1206 p_m_last_tv_msec = now_tv.tv_usec/1000;
1208 /* process only if we have a minimum of samples, to make packets not too small */
1209 if (elapsed >= ISDN_TRANSMIT
1210 && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1211 /* set clock of last process! */
1212 p_m_last_tv_sec = now_tv.tv_sec;
1213 p_m_last_tv_msec = now_tv.tv_usec/1000;
1216 if (elapsed < p_m_load)
1217 p_m_load -= elapsed;
1221 /* to send data, tone must be active OR crypt messages must be on */
1222 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1223 && (p_m_load < ISDN_LOAD)
1224 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones)) {
1225 int tosend = ISDN_LOAD - p_m_load, length;
1226 unsigned char buf[MISDN_HEADER_LEN+tosend];
1227 struct mISDNhead *frm = (struct mISDNhead *)buf;
1228 unsigned char *p = buf+MISDN_HEADER_LEN;
1230 /* copy crypto loops */
1231 while (p_m_crypt_msg_loops && tosend) {
1232 /* how much do we have to send */
1233 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1236 if (length > tosend)
1239 /* copy message (part) to buffer */
1240 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1243 p_m_crypt_msg_current += length;
1244 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1246 p_m_crypt_msg_current = 0;
1247 p_m_crypt_msg_loops--;
1248 // puts("eine loop weniger");
1256 if (p_tone_name[0] && tosend) {
1257 tosend -= read_audio(p, tosend);
1261 if (ISDN_LOAD - p_m_load - tosend > 0) {
1262 frm->prim = PH_DATA_REQ;
1264 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1266 PERROR("Failed to send to socket %d (samples = %d)\n", p_m_mISDNport->b_socket[p_m_b_index], ISDN_LOAD-p_m_load-tosend);
1267 p_m_load += ISDN_LOAD - p_m_load - tosend;
1272 // NOTE: deletion is done by the child class
1274 /* handle timeouts */
1276 if (p_m_timer+p_m_timeout < now_d) {
1277 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1279 /* send timeout to endpoint */
1280 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1281 message->param.state = p_state;
1282 message_put(message);
1287 return(0); /* nothing done */
1292 * whenever we get audio data from bchannel, we process it here
1294 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1296 unsigned int cont = *((unsigned int *)data);
1297 unsigned char *data_temp;
1298 unsigned int length_temp;
1299 struct lcr_msg *message;
1303 if (hh->prim == PH_CONTROL_IND) {
1305 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1308 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1309 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1310 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1312 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1313 message->param.dtmf = cont & DTMF_TONE_MASK;
1314 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1315 message_put(message);
1320 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1321 add_trace("DSP-CRYPT", NULL, "error");
1323 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1324 message->param.crypt.type = CC_ERROR_IND;
1325 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1326 message_put(message);
1330 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1331 add_trace("DSP-CRYPT", NULL, "ok");
1333 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1334 message->param.crypt.type = CC_ACTBF_CONF;
1335 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1336 message_put(message);
1340 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1341 add_trace("unknown", NULL, "0x%x", cont);
1346 if (hh->prim == PH_CONTROL_IND) {
1349 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1350 add_trace("unknown", NULL, "0x%x", hh->id);
1355 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1357 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1358 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1361 /* see below (same condition) */
1362 if (p_state!=PORT_STATE_CONNECT
1363 && !p_m_mISDNport->tones)
1365 // printf(".");fflush(stdout);return;
1367 record(data, len, 1); // from up
1370 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1371 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1375 /* calls will not process any audio data unless
1376 * the call is connected OR tones feature is enabled.
1378 #ifndef DEBUG_COREBRIDGE
1379 if (p_state!=PORT_STATE_CONNECT
1380 && !p_m_mISDNport->tones)
1385 /* the bearer capability must be audio in order to send and receive
1386 * audio prior or after connect.
1388 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1392 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1394 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1400 record(data, len, 0); // from down
1402 /* randomize and listen to crypt message if enabled */
1403 if (p_m_crypt_listen) {
1404 /* the noisy randomizer */
1408 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1410 cryptman_listen_bch(data, len);
1415 /* send data to epoint */
1416 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1419 while(length_temp) {
1420 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1421 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1422 memcpy(message->param.data.data, data_temp, message->param.data.len);
1423 message_put(message);
1424 if (length_temp <= sizeof(message->param.data.data))
1426 data_temp += sizeof(message->param.data.data);
1427 length_temp -= sizeof(message->param.data.data);
1436 void PmISDN::set_echotest(int echo)
1438 if (p_m_echo != echo) {
1440 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1442 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1443 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_echo?DSP_ECHO_ON:DSP_ECHO_OFF, 0, "DSP-ECHO", p_m_echo);
1450 void PmISDN::set_tone(const char *dir, const char *tone)
1455 /* if no directory is given (by extension), we use interface.conf or options.conf */
1456 if (!dir || !dir[0]) {
1457 if (p_m_mISDNport->ifport->tones_dir[0])
1458 dir = p_m_mISDNport->ifport->tones_dir;
1459 else if (options.tones_dir[0])
1460 dir = options.tones_dir;
1465 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1471 /* check for dsp tones */
1472 if (!strcmp(dir, "american"))
1474 if (!strcmp(dir, "german"))
1476 if (!strcmp(dir, "oldgerman"))
1477 dsp = DSP_OLDGERMAN;
1479 /* check if we NOT really have to use a dsp-tone */
1480 if (dsp == DSP_NONE) {
1483 if (p_m_b_index > -1)
1484 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) {
1485 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1486 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1489 Port::set_tone(dir, tone);
1493 /* now we USE dsp-tone, convert name */
1494 if (!strcmp(tone, "dialtone")) {
1496 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1497 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1498 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1500 } else if (!strcmp(tone, "dialpbx")) {
1502 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1503 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1504 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1506 } else if (!strcmp(tone, "ringing")) {
1508 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1509 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1510 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1512 } else if (!strcmp(tone, "ringpbx")) {
1514 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1515 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1516 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1518 } else if (!strcmp(tone, "busy")) {
1521 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1522 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1523 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1525 } else if (!strcmp(tone, "release")) {
1528 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1529 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1530 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1532 } else if (!strcmp(tone, "cause_10"))
1534 else if (!strcmp(tone, "cause_11"))
1536 else if (!strcmp(tone, "cause_22")) {
1538 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1539 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1540 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1542 } else if (!strncmp(tone, "cause_", 6))
1543 id = TONE_SPECIAL_INFO;
1547 /* if we have a tone that is not supported by dsp */
1548 if (id==TONE_OFF && tone[0])
1552 if (p_m_tone != id) {
1555 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1556 if (p_m_b_index > -1)
1557 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)
1558 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_tone?DSP_TONE_PATT_ON:DSP_TONE_PATT_OFF, p_m_tone, "DSP-TONE", p_m_tone);
1560 /* turn user-space tones off in cases of no tone OR dsp tone */
1561 Port::set_tone("",NULL);
1565 /* MESSAGE_mISDNSIGNAL */
1566 //extern struct lcr_msg *dddebug;
1567 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1569 switch(param->mISDNsignal.message) {
1570 case mISDNSIGNAL_VOLUME:
1571 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1572 p_m_tx_gain = param->mISDNsignal.tx_gain;
1573 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1574 if (p_m_b_index > -1)
1575 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)
1576 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
1578 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1579 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1580 p_m_rx_gain = param->mISDNsignal.rx_gain;
1581 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1582 if (p_m_b_index > -1)
1583 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)
1584 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
1586 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1589 case mISDNSIGNAL_CONF:
1590 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1591 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1592 if (p_m_conf != param->mISDNsignal.conf) {
1593 p_m_conf = param->mISDNsignal.conf;
1594 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1595 if (p_m_b_index > -1)
1596 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1597 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], (p_m_conf)?DSP_CONF_JOIN:DSP_CONF_SPLIT, p_m_conf, "DSP-CONF", p_m_conf);
1599 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1600 /* we must set, even if currently tone forbids conf */
1601 p_m_conf = param->mISDNsignal.conf;
1602 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1605 case mISDNSIGNAL_JOINDATA:
1606 if (p_m_joindata != param->mISDNsignal.joindata) {
1607 p_m_joindata = param->mISDNsignal.joindata;
1608 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1610 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1613 case mISDNSIGNAL_DELAY:
1614 if (p_m_delay != param->mISDNsignal.delay) {
1615 p_m_delay = param->mISDNsignal.delay;
1616 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1617 if (p_m_b_index > -1)
1618 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)
1619 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], p_m_delay?DSP_DELAY:DSP_JITTER, p_m_delay, "DSP-DELAY", p_m_delay);
1621 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1625 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1630 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1632 struct lcr_msg *message;
1634 switch(param->crypt.type) {
1635 case CC_ACTBF_REQ: /* activate blowfish */
1637 p_m_crypt_key_len = param->crypt.len;
1638 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1639 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1640 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1641 message->param.crypt.type = CC_ERROR_IND;
1642 message_put(message);
1645 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1647 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1648 if (p_m_b_index > -1)
1649 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)
1650 ph_control_block(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], 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);
1653 case CC_DACT_REQ: /* deactivate session encryption */
1658 case CR_LISTEN_REQ: /* start listening to messages */
1659 p_m_crypt_listen = 1;
1660 p_m_crypt_listen_state = 0;
1663 case CR_UNLISTEN_REQ: /* stop listening to messages */
1664 p_m_crypt_listen = 0;
1667 case CR_MESSAGE_REQ: /* send message */
1668 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1669 if (!p_m_crypt_msg_len) {
1670 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1673 p_m_crypt_msg_current = 0; /* reset */
1674 p_m_crypt_msg_loops = 6; /* enable */
1676 /* disable txmix, or we get corrupt data due to audio process */
1677 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1678 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1679 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1685 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1691 * endpoint sends messages to the port
1693 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1695 if (Port::message_epoint(epoint_id, message_id, param))
1698 switch(message_id) {
1699 case MESSAGE_DATA: /* tx-data from upper layer */
1700 txfromup(param->data.data, param->data.len);
1703 case MESSAGE_mISDNSIGNAL: /* user command */
1704 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1705 message_mISDNsignal(epoint_id, message_id, param);
1708 case MESSAGE_CRYPT: /* crypt control command */
1709 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1710 message_crypt(epoint_id, message_id, param);
1719 * main loop for processing messages from mISDN
1721 int mISDN_handler(void)
1724 struct mISDNport *mISDNport;
1725 class PmISDN *isdnport;
1727 unsigned char buffer[2048+MISDN_HEADER_LEN];
1728 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1732 /* process all ports */
1733 mISDNport = mISDNport_first;
1735 /* process all bchannels */
1737 while(i < mISDNport->b_num) {
1738 /* process timer events for bchannel handling */
1739 if (mISDNport->b_timer[i]) {
1740 if (mISDNport->b_timer[i] <= now_d)
1741 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1743 /* handle port of bchannel */
1744 isdnport=mISDNport->b_port[i];
1746 /* call bridges in user space OR crypto OR recording */
1747 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record) {
1748 /* rx IS required */
1749 if (isdnport->p_m_rxoff) {
1751 isdnport->p_m_rxoff = 0;
1752 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1753 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1754 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1758 /* rx NOT required */
1759 if (!isdnport->p_m_rxoff) {
1761 isdnport->p_m_rxoff = 1;
1762 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1763 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1764 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1769 if (isdnport->p_record) {
1770 /* txdata IS required */
1771 if (!isdnport->p_m_txdata) {
1773 isdnport->p_m_txdata = 1;
1774 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1775 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1776 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1780 /* txdata NOT required */
1781 if (isdnport->p_m_txdata) {
1783 isdnport->p_m_txdata = 0;
1784 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1785 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1786 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1792 /* handle message from bchannel */
1793 if (mISDNport->b_socket[i] > -1) {
1794 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1795 if (ret >= (int)MISDN_HEADER_LEN) {
1798 /* we don't care about confirms, we use rx data to sync tx */
1802 /* we receive audio data, we respond to it AND we send tones */
1807 case PH_CONTROL_IND:
1808 if (mISDNport->b_port[i])
1809 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1811 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1814 case PH_ACTIVATE_IND:
1815 case DL_ESTABLISH_IND:
1816 case PH_ACTIVATE_CNF:
1817 case DL_ESTABLISH_CNF:
1818 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1819 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1822 case PH_DEACTIVATE_IND:
1823 case DL_RELEASE_IND:
1824 case PH_DEACTIVATE_CNF:
1825 case DL_RELEASE_CNF:
1826 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1827 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1831 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1834 if (ret < 0 && errno != EWOULDBLOCK)
1835 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1842 /* handle queued up-messages (d-channel) */
1843 if (!mISDNport->gsm) {
1844 while ((mb = mdequeue(&mISDNport->upqueue))) {
1847 case MPH_ACTIVATE_IND:
1848 if (mISDNport->l1link != 1) {
1849 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1851 mISDNport->l1link = 1;
1855 case MPH_DEACTIVATE_IND:
1856 if (mISDNport->l1link != 0) {
1857 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1859 mISDNport->l1link = 0;
1863 case MPH_INFORMATION_IND:
1864 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1866 case L1_SIGNAL_LOS_ON:
1869 case L1_SIGNAL_LOS_OFF:
1872 case L1_SIGNAL_AIS_ON:
1875 case L1_SIGNAL_AIS_OFF:
1878 case L1_SIGNAL_RDI_ON:
1881 case L1_SIGNAL_RDI_OFF:
1884 case L1_SIGNAL_SLIP_TX:
1885 mISDNport->slip_tx++;
1887 case L1_SIGNAL_SLIP_RX:
1888 mISDNport->slip_rx++;
1893 case MT_L2ESTABLISH:
1894 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1895 add_trace("tei", NULL, "%d", l3m->pid);
1897 mISDNport->l2link = 1;
1899 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1900 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1901 if (mISDNport->l2establish) {
1902 mISDNport->l2establish = 0;
1903 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1910 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1911 if (!mISDNport->l2establish) {
1912 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1913 add_trace("tei", NULL, "%d", l3m->pid);
1915 /* down if not nt-ptmp */
1916 if (!mISDNport->ntmode || mISDNport->ptp)
1917 mISDNport->l2link = 0;
1919 if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1920 if (!mISDNport->l2establish && mISDNport->l2hold) {
1921 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1922 time(&mISDNport->l2establish);
1923 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1929 /* l3-data is sent to LCR */
1930 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1938 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1940 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1941 mISDNport->l1timeout = 0;
1944 /* layer 2 establish timer */
1945 if (mISDNport->l2establish) {
1946 if (now-mISDNport->l2establish > 5) {
1947 mISDNport->l2establish = 0;
1948 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1950 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1951 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1952 time(&mISDNport->l2establish);
1959 mISDNport = mISDNport->next;
1962 /* if we received at least one b-frame, we will return 1 */
1966 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1970 * l3m must be queued, except for MT_ASSIGN
1973 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
1976 /* special MT_ASSIGN handling:
1978 * if we request a PID from mlayer, we always do it while lcr is locked.
1979 * therefore we must check the MT_ASSIGN reply first before we lock.
1980 * this is because the MT_ASSIGN reply is received with the requesting
1981 * process, not by the mlayer thread!
1982 * this means, that the reply is sent during call of the request.
1983 * we must check if we get a reply and we know that we lcr is currently
1986 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
1987 /* let's do some checking if someone changes stack behaviour */
1988 if (mt_assign_pid != 0)
1989 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
1990 mt_assign_pid = pid;
1993 /* queue message, create, if required */
1995 l3m = alloc_l3_msg();
1997 FATAL("No memory for layer 3 message\n");
1999 mb = container_of(l3m, struct mbuffer, l3);
2002 mqueue_tail(&mISDNport->upqueue, mb);
2006 int mISDN_getportbyname(int sock, int cnt, char *portname)
2008 struct mISDN_devinfo devinfo;
2012 while (port < cnt) {
2014 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2017 if (!strcasecmp(devinfo.name, portname))
2028 * global function to add a new card (port)
2030 struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l1hold, int l2hold, struct interface *interface, int gsm)
2033 struct mISDNport *mISDNport, **mISDNportp;
2037 // struct mlayer3 *ml3;
2038 struct mISDN_devinfo devinfo;
2039 unsigned int protocol, prop;
2041 /* check port counts */
2042 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2044 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2049 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2053 port = mISDN_getportbyname(mISDNsocket, cnt, portname);
2056 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", portname);
2058 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", portname);
2061 // note: 'port' has still the port number
2063 if (port>cnt || port<0) {
2064 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2068 /* get port attributes */
2069 pri = bri = pots = nt = te = 0;
2071 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2073 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2076 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2080 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2084 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2088 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2093 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2099 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2104 if (force_nt && !nt) {
2105 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2109 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2112 if (pots && !bri && !pri) {
2113 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2117 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2121 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2124 /* set NT by turning off TE */
2127 /* if TE an NT is supported (and not forced to NT), turn off NT */
2131 /* check for double use of port */
2133 mISDNport = mISDNport_first;
2135 if (mISDNport->portnum == port)
2137 mISDNport = mISDNport->next;
2140 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2145 /* check for continous channelmap with no bchannel on slot 16 */
2146 if (test_channelmap(0, devinfo.channelmap)) {
2147 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2151 while(i < (int)devinfo.nrbchan + 1) {
2153 if (test_channelmap(i, devinfo.channelmap)) {
2154 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2158 if (!test_channelmap(i, devinfo.channelmap)) {
2159 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2166 /* add mISDNport structure */
2167 mISDNportp = &mISDNport_first;
2169 mISDNportp = &((*mISDNportp)->next);
2170 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2172 /* gsm audio is always active */
2173 mISDNport->l1link = 1;
2174 mISDNport->l2link = 1;
2176 mISDNport->l1link = -1;
2177 mISDNport->l2link = -1;
2179 mISDNport->gsm = gsm;
2181 *mISDNportp = mISDNport;
2183 /* if pri, must set PTP */
2203 /* allocate ressources of port */
2204 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2205 prop = (1 << MISDN_FLG_L2_CLEAN);
2206 if (ptp) // ptp forced
2207 prop |= (1 << MISDN_FLG_PTP);
2208 if (nt) // supports hold/retrieve on nt-mode
2209 prop |= (1 << MISDN_FLG_NET_HOLD);
2210 if (l1hold) // supports layer 1 hold
2211 prop |= (1 << MISDN_FLG_L1_HOLD);
2212 if (l2hold) // supports layer 2 hold
2213 prop |= (1 << MISDN_FLG_L2_HOLD);
2214 /* open layer 3 and init upqueue */
2216 unsigned long on = 1;
2217 struct sockaddr_mISDN addr;
2219 if (devinfo.nrbchan < 8) {
2220 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2221 mISDNport_close(mISDNport);
2225 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2226 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2227 mISDNport_close(mISDNport);
2230 /* set nonblocking io */
2231 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2232 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2233 mISDNport_close(mISDNport);
2236 /* bind socket to dchannel */
2237 memset(&addr, 0, sizeof(addr));
2238 addr.family = AF_ISDN;
2241 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2242 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2243 mISDNport_close(mISDNport);
2247 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2248 mqueue_init(&mISDNport->upqueue);
2249 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2250 if (!mISDNport->ml3) {
2251 mqueue_purge(&mISDNport->upqueue);
2252 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2260 "PORT (open failed)");
2262 mISDNport_close(mISDNport);
2267 SCPY(mISDNport->name, devinfo.name);
2268 mISDNport->b_num = devinfo.nrbchan;
2269 mISDNport->portnum = port;
2270 mISDNport->ntmode = nt;
2271 mISDNport->tespecial = te_special;
2272 mISDNport->pri = pri;
2273 mISDNport->ptp = ptp;
2274 mISDNport->l1hold = l1hold;
2275 mISDNport->l2hold = l2hold;
2276 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2278 while(i < mISDNport->b_num) {
2279 mISDNport->b_state[i] = B_STATE_IDLE;
2280 mISDNport->b_socket[i] = -1;
2284 /* if ptp, pull up the link */
2285 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2286 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2287 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2288 add_trace("tei", NULL, "%d", 0);
2290 time(&mISDNport->l2establish);
2293 /* for nt-mode ptmp the link is always up */
2294 if (mISDNport->ntmode && !mISDNport->ptp)
2295 mISDNport->l2link = 1;
2297 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2299 start_trace(mISDNport->portnum,
2307 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2308 add_trace("channels", NULL, "%d", mISDNport->b_num);
2315 * function to free ALL cards (ports)
2317 void mISDNport_close_all(void)
2319 /* free all ports */
2320 while(mISDNport_first)
2321 mISDNport_close(mISDNport_first);
2325 * free only one port
2327 void mISDNport_close(struct mISDNport *mISDNport)
2329 struct mISDNport **mISDNportp;
2331 class PmISDN *isdnport;
2334 /* remove all port instance that are linked to this mISDNport */
2337 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2338 isdnport = (class PmISDN *)port;
2339 if (isdnport->p_m_mISDNport) {
2340 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2347 /* only if we are already part of interface */
2348 if (mISDNport->ifport) {
2349 start_trace(mISDNport->portnum,
2350 mISDNport->ifport->interface,
2360 /* free bchannels */
2362 while(i < mISDNport->b_num) {
2363 if (mISDNport->b_socket[i] > -1) {
2364 _bchannel_destroy(mISDNport, i);
2365 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2370 /* close layer 3, if open */
2371 if (!mISDNport->gsm && mISDNport->ml3) {
2372 close_layer3(mISDNport->ml3);
2375 /* close gsm socket, if open */
2376 if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2377 close(mISDNport->lcr_sock);
2381 if (!mISDNport->gsm)
2382 mqueue_purge(&mISDNport->upqueue);
2384 /* remove from list */
2385 mISDNportp = &mISDNport_first;
2386 while(*mISDNportp) {
2387 if (*mISDNportp == mISDNport) {
2388 *mISDNportp = (*mISDNportp)->next;
2392 mISDNportp = &((*mISDNportp)->next);
2396 FATAL("mISDNport not in list\n");
2398 FREE(mISDNport, sizeof(struct mISDNport));
2405 * enque data from upper buffer
2407 void PmISDN::txfromup(unsigned char *data, int length)
2409 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2410 struct mISDNhead *hh = (struct mISDNhead *)buf;
2413 if (p_m_b_index < 0)
2415 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2418 /* check if high priority tones exist
2419 * ignore data in this case
2421 if (p_tone_name[0] || p_m_crypt_msg_loops)
2424 /* preload procedure
2425 * if transmit buffer in DSP module is empty,
2426 * preload it to DSP_LOAD to prevent jitter gaps.
2428 if (p_m_load==0 && ISDN_LOAD>0) {
2429 hh->prim = PH_DATA_REQ;
2431 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2432 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2434 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2435 p_m_load += ISDN_LOAD;
2438 /* drop if load would exceed ISDN_MAXLOAD
2439 * this keeps the delay not too high
2441 if (p_m_load+length > ISDN_MAXLOAD)
2444 /* make and send frame */
2445 hh->prim = PH_DATA_REQ;
2447 memcpy(buf+MISDN_HEADER_LEN, data, length);
2448 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2450 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);