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)
28 #define container_of(ptr, type, member) ({ \
29 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
30 (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;
47 int mISDN_initialize(void)
53 /* try to open raw socket to check kernel */
54 mISDNsocket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
57 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
62 init_layer3(4); // buffer of 4
64 /* 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)
73 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
74 mISDN_debug_init(0xfffffeff, filename, filename, filename);
76 mISDN_debug_init(0, NULL, NULL, NULL);
81 void mISDN_deinitialize(void)
98 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
100 p_m_mISDNport = mISDNport;
101 p_m_portnum = mISDNport->portnum;
109 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
110 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
118 p_m_dtmf = !mISDNport->ifport->nodtmf;
121 p_m_remote_ref = 0; /* channel shall be exported to given remote */
122 p_m_remote_id = 0; /* remote admin socket */
123 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
131 p_m_crypt_listen = 0;
132 p_m_crypt_msg_loops = 0;
133 p_m_crypt_msg_loops = 0;
134 p_m_crypt_msg_len = 0;
135 p_m_crypt_msg[0] = '\0';
136 p_m_crypt_msg_current = 0;
137 p_m_crypt_key_len = 0;
138 p_m_crypt_listen = 0;
139 p_m_crypt_listen_state = 0;
140 p_m_crypt_listen_len = 0;
141 p_m_crypt_listen_msg[0] = '\0';
142 p_m_crypt_listen_crc = 0;
143 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56)
145 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
146 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
150 /* if any channel requested by constructor */
151 if (channel == CHANNEL_ANY)
153 /* reserve channel */
155 mISDNport->b_reserved++;
158 /* reserve channel */
159 if (channel > 0) // only if constructor was called with a channel resevation
160 seize_bchannel(channel, exclusive);
162 /* we increase the number of objects: */
164 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
173 struct lcr_msg *message;
175 /* remove bchannel relation */
181 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
182 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
183 message->param.disconnectinfo.cause = 16;
184 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
185 message_put(message);
186 /* remove from list */
187 free_epointlist(p_epointlist);
190 /* we decrease the number of objects: */
191 p_m_mISDNport->use--;
192 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
199 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
201 /* init trace with given values */
202 start_trace(mISDNport?mISDNport->portnum:-1,
203 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
204 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
205 port?port->p_dialinginfo.id:NULL,
208 port?port->p_serial:0,
216 static struct isdn_message {
220 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
221 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
222 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
223 {"DL_RELEASE", L2_RELEASE_REQ},
224 {"UNKNOWN", L3_UNKNOWN_REQ},
225 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
226 {"MT_SETUP", L3_SETUP_REQ},
227 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
228 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
229 {"MT_ALERTING", L3_ALERTING_REQ},
230 {"MT_CONNECT", L3_CONNECT_REQ},
231 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
232 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
233 {"MT_RELEASE", L3_RELEASE_REQ},
234 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
235 {"MT_INFORMATION", L3_INFORMATION_REQ},
236 {"MT_PROGRESS", L3_PROGRESS_REQ},
237 {"MT_NOTIFY", L3_NOTIFY_REQ},
238 {"MT_SUSPEND", L3_SUSPEND_REQ},
239 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
240 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
241 {"MT_RESUME", L3_RESUME_REQ},
242 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
243 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
244 {"MT_HOLD", L3_HOLD_REQ},
245 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
246 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
247 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
248 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
249 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
250 {"MT_FACILITY", L3_FACILITY_REQ},
251 {"MT_STATUS", L3_STATUS_REQ},
252 {"MT_RESTART", L3_RESTART_REQ},
253 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
254 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
257 static const char *isdn_prim[4] = {
263 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
268 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
269 /* select message and primitive text */
271 while(isdn_message[i].name)
273 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
274 if (isdn_message[i].value == (msg&0xffffff00))
276 SCPY(msgtext, isdn_message[i].name);
281 SCAT(msgtext, isdn_prim[msg&0x00000003]);
284 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
288 if (mISDNport->ntmode)
290 if (direction == DIRECTION_OUT)
291 SCAT(msgtext, " N->U");
293 SCAT(msgtext, " N<-U");
296 if (direction == DIRECTION_OUT)
297 SCAT(msgtext, " U->N");
299 SCAT(msgtext, " U<-N");
304 /* init trace with given values */
305 start_trace(mISDNport?mISDNport->portnum:-1,
306 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
307 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
308 port?port->p_dialinginfo.id:NULL,
311 port?port->p_serial:0,
317 * send control information to the channel (dsp-module)
319 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
321 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
322 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
323 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
329 ctrl->prim = PH_CONTROL_REQ;
333 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
335 PERROR("Failed to send to socket %d\n", sock);
336 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
337 if (c1 == DSP_CONF_JOIN)
338 add_trace(trace_name, NULL, "0x%08x", trace_value);
340 add_trace(trace_name, NULL, "%d", trace_value);
344 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)
346 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
347 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
348 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
354 ctrl->prim = PH_CONTROL_REQ;
357 memcpy(d, c2, c2_len);
358 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
360 PERROR("Failed to send to socket %d\n", sock);
361 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
362 add_trace(trace_name, NULL, "%d", trace_value);
368 * subfunction for bchannel_event
371 static int _bchannel_create(struct mISDNport *mISDNport, int i)
375 struct sockaddr_mISDN addr;
377 if (mISDNport->b_socket[i] > -1)
379 PERROR("Error: Socket already created for index %d\n", i);
384 //#warning testing without DSP
385 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
386 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
387 if (mISDNport->b_socket[i] < 0)
389 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
393 /* set nonblocking io */
394 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
397 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
398 close(mISDNport->b_socket[i]);
399 mISDNport->b_socket[i] = -1;
403 /* bind socket to bchannel */
404 addr.family = AF_ISDN;
405 addr.dev = mISDNport->portnum;
406 addr.channel = i+1+(i>=15);
407 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
410 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);
411 close(mISDNport->b_socket[i]);
412 mISDNport->b_socket[i] = -1;
416 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
417 add_trace("channel", NULL, "%d", i+1+(i>=15));
418 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
426 * subfunction for bchannel_event
427 * activate / deactivate request
429 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
431 struct mISDNhead act;
434 if (mISDNport->b_socket[i] < 0)
436 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
438 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
440 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
443 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
444 add_trace("channel", NULL, "%d", i+1+(i>=15));
445 if (mISDNport->b_timer[i])
446 add_trace("event", NULL, "timeout recovery");
452 * subfunction for bchannel_event
455 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
460 if (mISDNport->b_socket[i] < 0)
462 handle = mISDNport->b_socket[i];
463 port = mISDNport->b_port[i];
464 mode = mISDNport->b_mode[i];
467 PERROR("bchannel index i=%d not associated with a port object\n", i);
471 /* set dsp features */
472 if (port->p_m_txdata)
473 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
474 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
475 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
476 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
477 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
478 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
479 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
480 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
481 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
483 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
485 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
486 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
487 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
489 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
490 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
491 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
492 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
493 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
494 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
495 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);
499 * subfunction for bchannel_event
502 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
504 if (mISDNport->b_socket[i] < 0)
506 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
507 add_trace("channel", NULL, "%d", i+1+(i>=15));
508 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
510 close(mISDNport->b_socket[i]);
511 mISDNport->b_socket[i] = -1;
519 A bchannel goes through the following states in this order:
522 No one is using the bchannel.
523 It is available and not linked to Port class, nor reserved.
526 The bchannel stack is created and an activation request is sent.
527 It MAY be linked to Port class, but already unlinked due to Port class removal.
530 The bchannel is active and cofigured to the Port class needs.
531 Also it is linked to a Port class, otherwhise it would be deactivated.
533 - B_STATE_DEACTIVATING
534 The bchannel is in deactivating state, due to deactivation request.
535 It may be linked to a Port class, that likes to reactivate it.
539 After deactivating bchannel, and if not used, the bchannel becomes idle again.
541 Also the bchannel may be exported, but only if the state is or becomes idle:
544 The bchannel assignment has been sent to the remove application.
547 The bchannel assignment is acknowledged by the remote application.
550 The bchannel is re-imported by mISDN port object.
554 After re-importing bchannel, and if not used, the bchannel becomes idle again.
557 A bchannel can have the following events:
560 A bchannel is required by a Port class.
563 The bchannel beomes active.
566 The bchannel is not required by Port class anymore
568 - B_EVENT_DEACTIVATED
569 The bchannel becomes inactive.
572 The bchannel is now used by remote application.
575 The bchannel is not used by remote application.
577 - B_EVENT_EXPORTREQUEST
578 The bchannel shall be exported to the remote application.
580 - B_EVENT_IMPORTREQUEST
581 The bchannel is released from the remote application.
583 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
585 if an export request is receive by remote application, p_m_remote_* is set.
586 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.)
587 - set on export request from remote application (if port is assigned)
588 - set on channel use, if requested by remote application (p_m_remote_*)
589 - cleared on drop request
591 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
592 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
593 the bchannel import/export is acknowledged with stack given.
595 if exporting, b_remote_*[index] is set to the remote socket id.
596 if importing has been acknowledged. b_remote_*[index] is cleared.
601 * process bchannel events
602 * - mISDNport is a pointer to the port's structure
603 * - i is the index of the bchannel
604 * - event is the B_EVENT_* value
605 * - port is the PmISDN class pointer
607 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
609 class PmISDN *b_port = mISDNport->b_port[i];
610 int state = mISDNport->b_state[i];
611 double timer = mISDNport->b_timer[i];
612 unsigned int p_m_remote_ref = 0;
613 unsigned int p_m_remote_id = 0;
616 char *p_m_pipeline = NULL;
617 unsigned char *p_m_crypt_key = NULL;
618 int p_m_crypt_key_len = 0;
619 int p_m_crypt_key_type = 0;
620 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
624 p_m_remote_id = b_port->p_m_remote_id;
625 p_m_remote_ref = b_port->p_m_remote_ref;
626 p_m_tx_gain = b_port->p_m_tx_gain;
627 p_m_rx_gain = b_port->p_m_rx_gain;
628 p_m_pipeline = b_port->p_m_pipeline;
629 p_m_crypt_key = b_port->p_m_crypt_key;
630 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
631 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
637 /* port must be linked in order to allow activation */
639 FATAL("bchannel must be linked to a Port class\n");
645 /* export bchannel */
646 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);
647 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
648 add_trace("type", NULL, "assign");
649 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
651 state = B_STATE_EXPORTING;
652 mISDNport->b_remote_id[i] = p_m_remote_id;
653 mISDNport->b_remote_ref[i] = p_m_remote_ref;
656 /* create stack and send activation request */
657 if (_bchannel_create(mISDNport, i))
659 _bchannel_activate(mISDNport, i, 1);
660 state = B_STATE_ACTIVATING;
661 timer = now_d + B_TIMER_ACTIVATING;
666 case B_STATE_ACTIVATING:
667 case B_STATE_EXPORTING:
668 /* do nothing, because it is already activating */
671 case B_STATE_DEACTIVATING:
672 case B_STATE_IMPORTING:
673 /* do nothing, because we must wait until we can reactivate */
677 /* problems that might ocurr:
678 * B_EVENT_USE is received when channel already in use.
679 * bchannel exported, but not freed by other port
681 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
685 case B_EVENT_EXPORTREQUEST:
686 /* special case where the bchannel is requested by remote */
689 PERROR("export request without remote channel set, please correct.\n");
695 /* in case, the bchannel is exported right after seize_bchannel */
696 /* export bchannel */
697 /* p_m_remote_id is set, when this event happens. */
698 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);
699 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
700 add_trace("type", NULL, "assign");
701 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
703 state = B_STATE_EXPORTING;
704 mISDNport->b_remote_id[i] = p_m_remote_id;
705 mISDNport->b_remote_ref[i] = p_m_remote_ref;
708 case B_STATE_ACTIVATING:
709 case B_STATE_EXPORTING:
710 /* do nothing, because it is already activating */
713 case B_STATE_DEACTIVATING:
714 case B_STATE_IMPORTING:
715 /* do nothing, because we must wait until we can reactivate */
719 /* bchannel is active, so we deactivate */
720 _bchannel_activate(mISDNport, i, 0);
721 state = B_STATE_DEACTIVATING;
722 timer = now_d + B_TIMER_DEACTIVATING;
726 /* problems that might ocurr:
727 * ... when channel already in use.
728 * bchannel exported, but not freed by other port
730 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
734 case B_EVENT_IMPORTREQUEST:
735 /* special case where the bchannel is released by remote */
738 PERROR("import request with remote channel set, please correct.\n");
745 /* bchannel is not exported */
748 case B_STATE_ACTIVATING:
749 case B_STATE_EXPORTING:
750 /* do nothing because we must wait until bchanenl is active before deactivating */
754 /* bchannel is exported, so we re-import */
755 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
756 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
757 add_trace("type", NULL, "remove");
758 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
760 state = B_STATE_IMPORTING;
763 case B_STATE_DEACTIVATING:
764 case B_STATE_IMPORTING:
765 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
769 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
773 case B_EVENT_ACTIVATED:
777 case B_STATE_ACTIVATING:
778 if (b_port && !p_m_remote_id)
780 /* bchannel is active and used by Port class, so we configure bchannel */
781 _bchannel_configure(mISDNport, i);
782 state = B_STATE_ACTIVE;
783 b_port->p_m_load = 0;
786 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
787 _bchannel_activate(mISDNport, i, 0);
788 state = B_STATE_DEACTIVATING;
789 timer = now_d + B_TIMER_DEACTIVATING;
794 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
798 case B_EVENT_EXPORTED:
801 case B_STATE_EXPORTING:
802 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
804 /* remote export done */
805 state = B_STATE_REMOTE;
808 /* bchannel is now exported, but we need bchannel back
809 * OR bchannel is not used anymore
810 * OR bchannel has been exported to an obsolete ref,
811 * so reimport, to later export to new remote */
812 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
813 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
814 add_trace("type", NULL, "remove");
815 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
817 state = B_STATE_IMPORTING;
822 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
828 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);
843 state = B_STATE_DEACTIVATING;
844 timer = now_d + 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:
872 /* ignore due to deactivation confirm after unloading */
875 case B_STATE_DEACTIVATING:
876 _bchannel_destroy(mISDNport, i);
877 state = B_STATE_IDLE;
880 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
883 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);
884 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
885 add_trace("type", NULL, "assign");
886 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
888 state = B_STATE_EXPORTING;
889 mISDNport->b_remote_id[i] = p_m_remote_id;
890 mISDNport->b_remote_ref[i] = p_m_remote_ref;
893 if (_bchannel_create(mISDNport, i))
895 _bchannel_activate(mISDNport, i, 1);
896 state = B_STATE_ACTIVATING;
897 timer = now_d + B_TIMER_ACTIVATING;
904 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
908 case B_EVENT_IMPORTED:
911 case B_STATE_IMPORTING:
912 state = B_STATE_IDLE;
913 mISDNport->b_remote_id[i] = 0;
914 mISDNport->b_remote_ref[i] = 0;
917 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
920 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);
921 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
922 add_trace("type", NULL, "assign");
923 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
925 state = B_STATE_EXPORTING;
926 mISDNport->b_remote_id[i] = p_m_remote_id;
927 mISDNport->b_remote_ref[i] = p_m_remote_ref;
930 if (_bchannel_create(mISDNport, i))
932 _bchannel_activate(mISDNport, i, 1);
933 state = B_STATE_ACTIVATING;
934 timer = now_d + B_TIMER_ACTIVATING;
941 /* ignore, because not assigned */
946 case B_EVENT_TIMEOUT:
951 /* ignore due to deactivation confirm after unloading */
954 case B_STATE_ACTIVATING:
955 _bchannel_activate(mISDNport, i, 1);
956 timer = now_d + B_TIMER_ACTIVATING;
959 case B_STATE_DEACTIVATING:
960 _bchannel_activate(mISDNport, i, 0);
961 timer = now_d + B_TIMER_DEACTIVATING;
965 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
970 PERROR("Illegal event %d, please correct.\n", event);
973 mISDNport->b_state[i] = state;
974 mISDNport->b_timer[i] = timer;
981 * check for available channel and reserve+set it.
982 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
984 * returns -(cause value) or x = channel x or 0 = no channel
985 * NOTE: no activation is done here
987 int PmISDN::seize_bchannel(int channel, int exclusive)
991 /* the channel is what we have */
992 if (p_m_b_channel == channel)
995 /* if channel already in use, release it */
1000 if (channel==CHANNEL_NO || channel==0)
1003 /* is channel in range ? */
1005 || (channel>p_m_mISDNport->b_num && channel<16)
1006 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1007 return(-6); /* channel unacceptable */
1009 /* request exclusive channel */
1010 if (exclusive && channel>0)
1012 i = channel-1-(channel>16);
1013 if (p_m_mISDNport->b_port[i])
1014 return(-44); /* requested channel not available */
1018 /* ask for channel */
1021 i = channel-1-(channel>16);
1022 if (p_m_mISDNport->b_port[i] == NULL)
1026 /* search for channel */
1028 while(i < p_m_mISDNport->b_num)
1030 if (!p_m_mISDNport->b_port[i])
1032 channel = i+1+(i>=15);
1037 return(-34); /* no free channel */
1040 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1042 /* link Port, set parameters */
1043 p_m_mISDNport->b_port[i] = this;
1045 p_m_b_channel = channel;
1046 p_m_b_exclusive = exclusive;
1047 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1049 /* reserve channel */
1053 p_m_mISDNport->b_reserved++;
1060 * drop reserved channel and unset it.
1061 * deactivation is also done
1063 void PmISDN::drop_bchannel(void)
1065 /* unreserve channel */
1067 p_m_mISDNport->b_reserved--;
1071 if (p_m_b_index < 0)
1076 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1078 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1079 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1080 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1081 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1084 p_m_b_exclusive = 0;
1087 /* process bchannel export/import message from join */
1088 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1090 class Endpoint *epoint;
1092 class PmISDN *isdnport;
1093 struct mISDNport *mISDNport;
1098 case BCHANNEL_REQUEST:
1099 /* find the port object for the join object ref */
1100 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1102 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1105 if (!epoint->ep_portlist)
1107 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1110 if (epoint->ep_portlist->next)
1112 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);
1114 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1116 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1119 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1121 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1123 isdnport = (class PmISDN *)port;
1126 if (isdnport->p_m_remote_id)
1128 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1131 mISDNport = isdnport->p_m_mISDNport;
1132 i = isdnport->p_m_b_index;
1133 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1134 add_trace("type", NULL, "export request");
1136 isdnport->p_m_remote_ref = joinremote->j_serial;
1137 isdnport->p_m_remote_id = joinremote->j_remote_id;
1138 if (mISDNport && i>=0)
1140 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1144 case BCHANNEL_RELEASE:
1145 case BCHANNEL_ASSIGN_ACK:
1146 case BCHANNEL_REMOVE_ACK:
1147 /* find mISDNport for stack ID */
1148 mISDNport = mISDNport_first;
1152 ii = mISDNport->b_num;
1155 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1161 mISDNport = mISDNport->next;
1165 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1169 if (type!=BCHANNEL_RELEASE)
1172 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1173 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1175 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1179 isdnport = mISDNport->b_port[i];
1180 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1181 add_trace("type", NULL, "import request");
1185 isdnport->p_m_remote_ref = 0;
1186 isdnport->p_m_remote_id = 0;
1188 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1192 PERROR("received wrong bchannel message type %d from remote\n", type);
1200 audio transmission procedure:
1201 -----------------------------
1204 three sources of audio transmission:
1205 - crypto-data high priority
1206 - tones high priority (also high)
1207 - remote-data low priority
1210 a variable that temporarily shows the number of samples elapsed since last transmission process.
1211 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1214 a variable that is increased whenever data is transmitted.
1215 it is decreased while time elapses. it stores the number of samples that
1216 are currently loaded to dsp module.
1217 since clock in dsp module is the same clock for user space process, these
1221 there are two levels:
1222 ISDN_LOAD will give the load that have to be kept in dsp.
1223 ISDN_MAXLOAD will give the maximum load before dropping.
1225 * procedure for low priority data
1226 see txfromup() for procedure
1227 in short: remote data is ignored during high priority tones
1229 * procedure for high priority data
1230 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1231 if no more data is available, load becomes empty again.
1234 0 ISDN_LOAD ISDN_MAXLOAD
1235 +--------------------+----------------------+
1237 +--------------------+----------------------+
1239 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1240 0 ISDN_LOAD ISDN_MAXLOAD
1241 +--------------------+----------------------+
1242 |TTTTTTTTTTTTTTTTTTTT| |
1243 +--------------------+----------------------+
1245 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1246 0 ISDN_LOAD ISDN_MAXLOAD
1247 +--------------------+----------------------+
1248 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1249 +--------------------+----------------------+
1252 int PmISDN::handler(void)
1254 struct lcr_msg *message;
1258 if ((ret = Port::handler()))
1262 if (p_m_last_tv_sec)
1264 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1265 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1268 /* set clock of first process ever in this instance */
1269 p_m_last_tv_sec = now_tv.tv_sec;
1270 p_m_last_tv_msec = now_tv.tv_usec/1000;
1272 /* process only if we have a minimum of samples, to make packets not too small */
1273 if (elapsed >= ISDN_TRANSMIT
1274 && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1276 /* set clock of last process! */
1277 p_m_last_tv_sec = now_tv.tv_sec;
1278 p_m_last_tv_msec = now_tv.tv_usec/1000;
1281 if (elapsed < p_m_load)
1282 p_m_load -= elapsed;
1286 /* to send data, tone must be active OR crypt messages must be on */
1287 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1288 && (p_m_load < ISDN_LOAD)
1289 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1291 int tosend = ISDN_LOAD - p_m_load, length;
1292 unsigned char buf[MISDN_HEADER_LEN+tosend];
1293 struct mISDNhead *frm = (struct mISDNhead *)buf;
1294 unsigned char *p = buf+MISDN_HEADER_LEN;
1296 /* copy crypto loops */
1297 while (p_m_crypt_msg_loops && tosend)
1299 /* how much do we have to send */
1300 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1303 if (length > tosend)
1306 /* copy message (part) to buffer */
1307 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1310 p_m_crypt_msg_current += length;
1311 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1314 p_m_crypt_msg_current = 0;
1315 p_m_crypt_msg_loops--;
1316 // puts("eine loop weniger");
1324 if (p_tone_name[0] && tosend)
1326 tosend -= read_audio(p, tosend);
1330 if (ISDN_LOAD - p_m_load - tosend > 0)
1332 frm->prim = PH_DATA_REQ;
1334 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1336 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);
1337 p_m_load += ISDN_LOAD - p_m_load - tosend;
1342 // NOTE: deletion is done by the child class
1344 /* handle timeouts */
1347 if (p_m_timer+p_m_timeout < now_d)
1349 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1351 /* send timeout to endpoint */
1352 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1353 message->param.state = p_state;
1354 message_put(message);
1359 return(0); /* nothing done */
1364 * whenever we get audio data from bchannel, we process it here
1366 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1368 unsigned int cont = *((unsigned int *)data);
1369 unsigned char *data_temp;
1370 unsigned int length_temp;
1371 struct lcr_msg *message;
1375 if (hh->prim == PH_CONTROL_IND)
1379 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1382 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1384 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1385 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1387 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1388 message->param.dtmf = cont & DTMF_TONE_MASK;
1389 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1390 message_put(message);
1396 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1397 add_trace("DSP-CRYPT", NULL, "error");
1399 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1400 message->param.crypt.type = CC_ERROR_IND;
1401 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1402 message_put(message);
1406 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1407 add_trace("DSP-CRYPT", NULL, "ok");
1409 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1410 message->param.crypt.type = CC_ACTBF_CONF;
1411 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1412 message_put(message);
1416 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1417 add_trace("unknown", NULL, "0x%x", cont);
1422 if (hh->prim == PH_CONTROL_IND)
1427 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1428 add_trace("unknown", NULL, "0x%x", hh->id);
1433 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1437 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1438 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1441 /* see below (same condition) */
1442 if (p_state!=PORT_STATE_CONNECT
1443 && !p_m_mISDNport->tones)
1445 // printf(".");fflush(stdout);return;
1447 record(data, len, 1); // from up
1450 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1452 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1456 /* calls will not process any audio data unless
1457 * the call is connected OR tones feature is enabled.
1459 #ifndef DEBUG_COREBRIDGE
1460 if (p_state!=PORT_STATE_CONNECT
1461 && !p_m_mISDNport->tones)
1466 /* the bearer capability must be audio in order to send and receive
1467 * audio prior or after connect.
1469 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1473 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1476 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1482 record(data, len, 0); // from down
1484 /* randomize and listen to crypt message if enabled */
1485 if (p_m_crypt_listen)
1487 /* the noisy randomizer */
1491 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1493 cryptman_listen_bch(data, len);
1498 /* send data to epoint */
1499 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1505 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1506 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1507 memcpy(message->param.data.data, data_temp, message->param.data.len);
1508 message_put(message);
1509 if (length_temp <= sizeof(message->param.data.data))
1511 data_temp += sizeof(message->param.data.data);
1512 length_temp -= sizeof(message->param.data.data);
1521 void PmISDN::set_echotest(int echo)
1523 if (p_m_echo != echo)
1526 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1528 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1529 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);
1536 void PmISDN::set_tone(const char *dir, const char *tone)
1542 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1549 /* check if we NOT really have to use a dsp-tone */
1550 if (!options.dsptones)
1554 if (p_m_b_index > -1)
1555 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)
1557 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1558 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1561 Port::set_tone(dir, tone);
1565 /* now we USE dsp-tone, convert name */
1566 if (!strcmp(tone, "dialtone"))
1568 switch(options.dsptones) {
1569 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1570 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1571 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1573 } else if (!strcmp(tone, "dialpbx"))
1575 switch(options.dsptones) {
1576 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1577 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1578 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1580 } else if (!strcmp(tone, "ringing"))
1582 switch(options.dsptones) {
1583 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1584 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1585 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1587 } else if (!strcmp(tone, "ringpbx"))
1589 switch(options.dsptones) {
1590 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1591 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1592 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1594 } else if (!strcmp(tone, "busy"))
1597 switch(options.dsptones) {
1598 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1599 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1600 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1602 } else if (!strcmp(tone, "release"))
1605 switch(options.dsptones) {
1606 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1607 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1608 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1610 } else if (!strcmp(tone, "cause_10"))
1612 else if (!strcmp(tone, "cause_11"))
1614 else if (!strcmp(tone, "cause_22"))
1616 switch(options.dsptones) {
1617 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1618 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1619 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1621 } else if (!strncmp(tone, "cause_", 6))
1622 id = TONE_SPECIAL_INFO;
1626 /* if we have a tone that is not supported by dsp */
1627 if (id==TONE_OFF && tone[0])
1635 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1636 if (p_m_b_index > -1)
1637 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)
1638 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);
1640 /* turn user-space tones off in cases of no tone OR dsp tone */
1641 Port::set_tone("",NULL);
1645 /* MESSAGE_mISDNSIGNAL */
1646 //extern struct lcr_msg *dddebug;
1647 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1649 switch(param->mISDNsignal.message)
1651 case mISDNSIGNAL_VOLUME:
1652 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1654 p_m_tx_gain = param->mISDNsignal.tx_gain;
1655 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1656 if (p_m_b_index > -1)
1657 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)
1658 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);
1660 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1661 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1663 p_m_rx_gain = param->mISDNsignal.rx_gain;
1664 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1665 if (p_m_b_index > -1)
1666 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)
1667 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);
1669 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1672 case mISDNSIGNAL_CONF:
1673 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1674 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1675 if (p_m_conf != param->mISDNsignal.conf)
1677 p_m_conf = param->mISDNsignal.conf;
1678 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1679 if (p_m_b_index > -1)
1680 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1681 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);
1683 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1684 /* we must set, even if currently tone forbids conf */
1685 p_m_conf = param->mISDNsignal.conf;
1686 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1689 case mISDNSIGNAL_JOINDATA:
1690 if (p_m_joindata != param->mISDNsignal.joindata)
1692 p_m_joindata = param->mISDNsignal.joindata;
1693 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1695 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1698 case mISDNSIGNAL_DELAY:
1699 if (p_m_delay != param->mISDNsignal.delay)
1701 p_m_delay = param->mISDNsignal.delay;
1702 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1703 if (p_m_b_index > -1)
1704 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)
1705 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);
1707 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1711 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1716 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1718 struct lcr_msg *message;
1720 switch(param->crypt.type)
1722 case CC_ACTBF_REQ: /* activate blowfish */
1724 p_m_crypt_key_len = param->crypt.len;
1725 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1727 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1728 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1729 message->param.crypt.type = CC_ERROR_IND;
1730 message_put(message);
1733 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1735 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1736 if (p_m_b_index > -1)
1737 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)
1738 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);
1741 case CC_DACT_REQ: /* deactivate session encryption */
1746 case CR_LISTEN_REQ: /* start listening to messages */
1747 p_m_crypt_listen = 1;
1748 p_m_crypt_listen_state = 0;
1751 case CR_UNLISTEN_REQ: /* stop listening to messages */
1752 p_m_crypt_listen = 0;
1755 case CR_MESSAGE_REQ: /* send message */
1756 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1757 if (!p_m_crypt_msg_len)
1759 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1762 p_m_crypt_msg_current = 0; /* reset */
1763 p_m_crypt_msg_loops = 6; /* enable */
1765 /* disable txmix, or we get corrupt data due to audio process */
1766 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1768 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1769 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1775 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1781 * endpoint sends messages to the port
1783 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1785 if (Port::message_epoint(epoint_id, message_id, param))
1790 case MESSAGE_DATA: /* tx-data from upper layer */
1791 txfromup(param->data.data, param->data.len);
1794 case MESSAGE_mISDNSIGNAL: /* user command */
1795 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1796 message_mISDNsignal(epoint_id, message_id, param);
1799 case MESSAGE_CRYPT: /* crypt control command */
1800 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1801 message_crypt(epoint_id, message_id, param);
1810 * main loop for processing messages from mISDN
1812 int mISDN_handler(void)
1815 struct mISDNport *mISDNport;
1816 class PmISDN *isdnport;
1818 unsigned char buffer[2048+MISDN_HEADER_LEN];
1819 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1823 /* process all ports */
1824 mISDNport = mISDNport_first;
1827 /* process all bchannels */
1829 while(i < mISDNport->b_num)
1831 /* process timer events for bchannel handling */
1832 if (mISDNport->b_timer[i])
1834 if (mISDNport->b_timer[i] <= now_d)
1835 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1837 /* handle port of bchannel */
1838 isdnport=mISDNport->b_port[i];
1841 /* call bridges in user space OR crypto OR recording */
1842 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1844 /* rx IS required */
1845 if (isdnport->p_m_rxoff)
1848 isdnport->p_m_rxoff = 0;
1849 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1850 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1851 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1856 /* rx NOT required */
1857 if (!isdnport->p_m_rxoff)
1860 isdnport->p_m_rxoff = 1;
1861 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1862 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1863 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1868 if (isdnport->p_record)
1870 /* txdata IS required */
1871 if (!isdnport->p_m_txdata)
1874 isdnport->p_m_txdata = 1;
1875 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1876 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1877 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1882 /* txdata NOT required */
1883 if (isdnport->p_m_txdata)
1886 isdnport->p_m_txdata = 0;
1887 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1888 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1889 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1895 /* handle message from bchannel */
1896 if (mISDNport->b_socket[i] > -1)
1898 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1899 if (ret >= (int)MISDN_HEADER_LEN)
1904 /* we don't care about confirms, we use rx data to sync tx */
1908 /* we receive audio data, we respond to it AND we send tones */
1913 case PH_CONTROL_IND:
1914 if (mISDNport->b_port[i])
1915 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1917 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1920 case PH_ACTIVATE_IND:
1921 case DL_ESTABLISH_IND:
1922 case PH_ACTIVATE_CNF:
1923 case DL_ESTABLISH_CNF:
1924 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1925 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1928 case PH_DEACTIVATE_IND:
1929 case DL_RELEASE_IND:
1930 case PH_DEACTIVATE_CNF:
1931 case DL_RELEASE_CNF:
1932 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1933 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1937 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1941 if (ret < 0 && errno != EWOULDBLOCK)
1942 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1949 /* handle queued up-messages (d-channel) */
1950 while ((mb = mdequeue(&mISDNport->upqueue)))
1955 case MPH_ACTIVATE_IND:
1956 if (mISDNport->l1link != 1)
1958 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1960 mISDNport->l1link = 1;
1964 case MPH_DEACTIVATE_IND:
1965 if (mISDNport->l1link != 0)
1967 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1969 mISDNport->l1link = 0;
1973 case MPH_INFORMATION_IND:
1974 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1977 case L1_SIGNAL_LOS_ON:
1980 case L1_SIGNAL_LOS_OFF:
1983 case L1_SIGNAL_AIS_ON:
1986 case L1_SIGNAL_AIS_OFF:
1989 case L1_SIGNAL_RDI_ON:
1992 case L1_SIGNAL_RDI_OFF:
1995 case L1_SIGNAL_SLIP_TX:
1996 mISDNport->slip_tx++;
1998 case L1_SIGNAL_SLIP_RX:
1999 mISDNport->slip_rx++;
2004 case MT_L2ESTABLISH:
2005 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2006 add_trace("tei", NULL, "%d", l3m->pid);
2008 mISDNport->l2link = 1;
2010 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
2011 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2013 if (mISDNport->l2establish)
2015 mISDNport->l2establish = 0;
2016 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2023 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
2024 if (!mISDNport->l2establish)
2026 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2027 add_trace("tei", NULL, "%d", l3m->pid);
2029 /* down if not nt-ptmp */
2030 if (!mISDNport->ntmode || mISDNport->ptp)
2031 mISDNport->l2link = 0;
2033 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2035 if (!mISDNport->l2establish && mISDNport->l2hold)
2037 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
2038 time(&mISDNport->l2establish);
2039 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2045 /* l3-data is sent to LCR */
2046 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2053 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2055 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2056 mISDNport->l1timeout = 0;
2059 /* layer 2 establish timer */
2060 if (mISDNport->l2establish)
2062 if (now-mISDNport->l2establish > 5)
2064 mISDNport->l2establish = 0;
2065 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2068 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2069 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2070 time(&mISDNport->l2establish);
2077 mISDNport = mISDNport->next;
2080 /* if we received at least one b-frame, we will return 1 */
2084 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2088 * l3m must be queued, except for MT_ASSIGN
2091 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2094 /* special MT_ASSIGN handling:
2096 * if we request a PID from mlayer, we always do it while lcr is locked.
2097 * therefore we must check the MT_ASSIGN reply first before we lock.
2098 * this is because the MT_ASSIGN reply is received with the requesting
2099 * process, not by the mlayer thread!
2100 * this means, that the reply is sent during call of the request.
2101 * we must check if we get a reply and we know that we lcr is currently
2104 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2106 /* let's do some checking if someone changes stack behaviour */
2107 if (mt_assign_pid != 0)
2108 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2109 mt_assign_pid = pid;
2113 /* queue message, create, if required */
2116 l3m = alloc_l3_msg();
2118 FATAL("No memory for layer 3 message\n");
2120 mb = container_of(l3m, struct mbuffer, l3);
2123 mqueue_tail(&mISDNport->upqueue, mb);
2129 * global function to add a new card (port)
2131 struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l1hold, int l2hold, struct interface *interface)
2134 struct mISDNport *mISDNport, **mISDNportp;
2138 // struct mlayer3 *ml3;
2139 struct mISDN_devinfo devinfo;
2140 unsigned int protocol, prop;
2142 /* check port counts */
2143 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2146 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2152 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2162 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2165 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2168 if (!strcasecmp(devinfo.name, portname))
2174 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", portname);
2177 // note: 'port' has still the port number
2179 if (port>cnt || port<0)
2181 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2185 /* get port attributes */
2186 pri = bri = pots = nt = te = 0;
2188 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2191 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2194 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2199 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2204 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2209 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2215 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2222 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2228 if (force_nt && !nt)
2230 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2235 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2238 if (pots && !bri && !pri)
2240 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2245 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2250 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2253 /* set NT by turning off TE */
2256 /* if TE an NT is supported (and not forced to NT), turn off NT */
2260 /* check for double use of port */
2263 mISDNport = mISDNport_first;
2266 if (mISDNport->portnum == port)
2268 mISDNport = mISDNport->next;
2272 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2278 /* add mISDNport structure */
2279 mISDNportp = &mISDNport_first;
2281 mISDNportp = &((*mISDNportp)->next);
2282 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2283 mISDNport->l1link = -1;
2284 mISDNport->l2link = -1;
2286 *mISDNportp = mISDNport;
2288 /* if pri, must set PTP */
2309 /* allocate ressources of port */
2310 /* open layer 3 and init upqueue */
2311 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2312 prop = (1 << MISDN_FLG_L2_CLEAN);
2313 if (ptp) // ptp forced
2314 prop |= (1 << MISDN_FLG_PTP);
2315 if (nt) // supports hold/retrieve on nt-mode
2316 prop |= (1 << MISDN_FLG_NET_HOLD);
2317 if (l1hold) // supports layer 1 hold
2318 prop |= (1 << MISDN_FLG_L1_HOLD);
2319 if (l2hold) // supports layer 2 hold
2320 prop |= (1 << MISDN_FLG_L2_HOLD);
2321 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2322 mqueue_init(&mISDNport->upqueue);
2323 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2324 if (!mISDNport->ml3)
2326 mqueue_purge(&mISDNport->upqueue);
2327 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2335 "PORT (open failed)");
2337 mISDNport_close(mISDNport);
2342 /* if ntmode, establish L1 to send the tei removal during start */
2343 if (mISDNport->ntmode)
2347 act.prim = PH_ACTIVATE | REQUEST;
2348 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2349 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2352 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2353 usleep(10000); /* to be sure, that l1 is up */
2357 SCPY(mISDNport->name, devinfo.name);
2358 mISDNport->b_num = devinfo.nrbchan;
2359 mISDNport->portnum = port;
2360 mISDNport->ntmode = nt;
2361 mISDNport->tespecial = te_special;
2362 mISDNport->pri = pri;
2363 mISDNport->ptp = ptp;
2364 mISDNport->l1hold = l1hold;
2365 mISDNport->l2hold = l2hold;
2366 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2368 while(i < mISDNport->b_num)
2370 mISDNport->b_state[i] = B_STATE_IDLE;
2371 mISDNport->b_socket[i] = -1;
2375 /* if ptp, pull up the link */
2376 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2378 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2379 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2380 add_trace("tei", NULL, "%d", 0);
2382 time(&mISDNport->l2establish);
2385 /* for nt-mode ptmp the link is always up */
2386 if (mISDNport->ntmode && !mISDNport->ptp)
2387 mISDNport->l2link = 1;
2389 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2391 start_trace(mISDNport->portnum,
2399 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2400 add_trace("channels", NULL, "%d", mISDNport->b_num);
2407 * function to free ALL cards (ports)
2409 void mISDNport_close_all(void)
2411 /* free all ports */
2412 while(mISDNport_first)
2413 mISDNport_close(mISDNport_first);
2417 * free only one port
2419 void mISDNport_close(struct mISDNport *mISDNport)
2421 struct mISDNport **mISDNportp;
2423 class PmISDN *isdnport;
2426 /* remove all port instance that are linked to this mISDNport */
2430 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2432 isdnport = (class PmISDN *)port;
2433 if (isdnport->p_m_mISDNport)
2435 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2442 /* only if we are already part of interface */
2443 if (mISDNport->ifport)
2445 start_trace(mISDNport->portnum,
2446 mISDNport->ifport->interface,
2456 /* free bchannels */
2458 while(i < mISDNport->b_num)
2460 if (mISDNport->b_socket[i] > -1)
2462 _bchannel_destroy(mISDNport, i);
2463 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2468 /* close layer 3, if open and purge upqueue */
2471 close_layer3(mISDNport->ml3);
2472 mqueue_purge(&mISDNport->upqueue);
2475 /* remove from list */
2476 mISDNportp = &mISDNport_first;
2479 if (*mISDNportp == mISDNport)
2481 *mISDNportp = (*mISDNportp)->next;
2485 mISDNportp = &((*mISDNportp)->next);
2489 FATAL("mISDNport not in list\n");
2491 FREE(mISDNport, sizeof(struct mISDNport));
2498 * enque data from upper buffer
2500 void PmISDN::txfromup(unsigned char *data, int length)
2502 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2503 struct mISDNhead *hh = (struct mISDNhead *)buf;
2506 if (p_m_b_index < 0)
2508 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2511 /* check if high priority tones exist
2512 * ignore data in this case
2514 if (p_tone_name[0] || p_m_crypt_msg_loops)
2517 /* preload procedure
2518 * if transmit buffer in DSP module is empty,
2519 * preload it to DSP_LOAD to prevent jitter gaps.
2521 if (p_m_load==0 && ISDN_LOAD>0)
2523 hh->prim = PH_DATA_REQ;
2525 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2526 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2528 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2529 p_m_load += ISDN_LOAD;
2532 /* drop if load would exceed ISDN_MAXLOAD
2533 * this keeps the delay not too high
2535 if (p_m_load+length > ISDN_MAXLOAD)
2538 /* make and send frame */
2539 hh->prim = PH_DATA_REQ;
2541 memcpy(buf+MISDN_HEADER_LEN, data, length);
2542 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2544 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);