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(0xffffffff, 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},
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 (isdn_message[i].value == (msg&0xffffff00))
275 SCPY(msgtext, isdn_message[i].name);
280 SCAT(msgtext, isdn_prim[msg&0x00000003]);
283 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ)
287 if (mISDNport->ntmode)
289 if (direction == DIRECTION_OUT)
290 SCAT(msgtext, " N->U");
292 SCAT(msgtext, " N<-U");
295 if (direction == DIRECTION_OUT)
296 SCAT(msgtext, " U->N");
298 SCAT(msgtext, " U<-N");
303 /* init trace with given values */
304 start_trace(mISDNport?mISDNport->portnum:-1,
305 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
306 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
307 port?port->p_dialinginfo.id:NULL,
310 port?port->p_serial:0,
316 * send control information to the channel (dsp-module)
318 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
320 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
321 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
322 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
328 ctrl->prim = PH_CONTROL_REQ;
332 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
334 PERROR("Failed to send to socket %d\n", sock);
335 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
336 if (c1 == DSP_CONF_JOIN)
337 add_trace(trace_name, NULL, "0x%08x", trace_value);
339 add_trace(trace_name, NULL, "%d", trace_value);
343 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)
345 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
346 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
347 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
353 ctrl->prim = PH_CONTROL_REQ;
356 memcpy(d, c2, c2_len);
357 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
359 PERROR("Failed to send to socket %d\n", sock);
360 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
361 add_trace(trace_name, NULL, "%d", trace_value);
367 * subfunction for bchannel_event
370 static int _bchannel_create(struct mISDNport *mISDNport, int i)
374 struct sockaddr_mISDN addr;
376 if (mISDNport->b_socket[i] > -1)
378 PERROR("Error: Socket already created for index %d\n", i);
383 //#warning testing without DSP
384 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
385 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
386 if (mISDNport->b_socket[i] < 0)
388 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
392 /* set nonblocking io */
393 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
396 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
397 close(mISDNport->b_socket[i]);
398 mISDNport->b_socket[i] = -1;
402 /* bind socket to bchannel */
403 addr.family = AF_ISDN;
404 addr.dev = mISDNport->portnum;
405 addr.channel = i+1+(i>=15);
406 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
409 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);
410 close(mISDNport->b_socket[i]);
411 mISDNport->b_socket[i] = -1;
415 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
416 add_trace("channel", NULL, "%d", i+1+(i>=15));
417 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
425 * subfunction for bchannel_event
426 * activate / deactivate request
428 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
430 struct mISDNhead act;
433 if (mISDNport->b_socket[i] < 0)
435 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
437 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
439 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
442 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
443 add_trace("channel", NULL, "%d", i+1+(i>=15));
444 if (mISDNport->b_timer[i])
445 add_trace("event", NULL, "timeout recovery");
451 * subfunction for bchannel_event
454 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
459 if (mISDNport->b_socket[i] < 0)
461 handle = mISDNport->b_socket[i];
462 port = mISDNport->b_port[i];
463 mode = mISDNport->b_mode[i];
466 PERROR("bchannel index i=%d not associated with a port object\n", i);
470 /* set dsp features */
471 if (port->p_m_txdata)
472 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
473 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
474 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
475 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
476 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
477 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
478 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
479 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
480 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
482 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
484 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
485 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
486 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
488 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
489 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
490 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
491 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
492 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
493 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
494 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);
498 * subfunction for bchannel_event
501 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
503 if (mISDNport->b_socket[i] < 0)
505 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
506 add_trace("channel", NULL, "%d", i+1+(i>=15));
507 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
509 close(mISDNport->b_socket[i]);
510 mISDNport->b_socket[i] = -1;
518 A bchannel goes through the following states in this order:
521 No one is using the bchannel.
522 It is available and not linked to Port class, nor reserved.
525 The bchannel stack is created and an activation request is sent.
526 It MAY be linked to Port class, but already unlinked due to Port class removal.
529 The bchannel is active and cofigured to the Port class needs.
530 Also it is linked to a Port class, otherwhise it would be deactivated.
532 - B_STATE_DEACTIVATING
533 The bchannel is in deactivating state, due to deactivation request.
534 It may be linked to a Port class, that likes to reactivate it.
538 After deactivating bchannel, and if not used, the bchannel becomes idle again.
540 Also the bchannel may be exported, but only if the state is or becomes idle:
543 The bchannel assignment has been sent to the remove application.
546 The bchannel assignment is acknowledged by the remote application.
549 The bchannel is re-imported by mISDN port object.
553 After re-importing bchannel, and if not used, the bchannel becomes idle again.
556 A bchannel can have the following events:
559 A bchannel is required by a Port class.
562 The bchannel beomes active.
565 The bchannel is not required by Port class anymore
567 - B_EVENT_DEACTIVATED
568 The bchannel becomes inactive.
571 The bchannel is now used by remote application.
574 The bchannel is not used by remote application.
576 - B_EVENT_EXPORTREQUEST
577 The bchannel shall be exported to the remote application.
579 - B_EVENT_IMPORTREQUEST
580 The bchannel is released from the remote application.
582 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
584 if an export request is receive by remote application, p_m_remote_* is set.
585 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.)
586 - set on export request from remote application (if port is assigned)
587 - set on channel use, if requested by remote application (p_m_remote_*)
588 - cleared on drop request
590 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
591 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
592 the bchannel import/export is acknowledged with stack given.
594 if exporting, b_remote_*[index] is set to the remote socket id.
595 if importing has been acknowledged. b_remote_*[index] is cleared.
600 * process bchannel events
601 * - mISDNport is a pointer to the port's structure
602 * - i is the index of the bchannel
603 * - event is the B_EVENT_* value
604 * - port is the PmISDN class pointer
606 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
608 class PmISDN *b_port = mISDNport->b_port[i];
609 int state = mISDNport->b_state[i];
610 double timer = mISDNport->b_timer[i];
611 unsigned int p_m_remote_ref = 0;
612 unsigned int p_m_remote_id = 0;
615 char *p_m_pipeline = NULL;
616 unsigned char *p_m_crypt_key = NULL;
617 int p_m_crypt_key_len = 0;
618 int p_m_crypt_key_type = 0;
619 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
623 p_m_remote_id = b_port->p_m_remote_id;
624 p_m_remote_ref = b_port->p_m_remote_ref;
625 p_m_tx_gain = b_port->p_m_tx_gain;
626 p_m_rx_gain = b_port->p_m_rx_gain;
627 p_m_pipeline = b_port->p_m_pipeline;
628 p_m_crypt_key = b_port->p_m_crypt_key;
629 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
630 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
636 /* port must be linked in order to allow activation */
638 FATAL("bchannel must be linked to a Port class\n");
644 /* export bchannel */
645 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);
646 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
647 add_trace("type", NULL, "assign");
648 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
650 state = B_STATE_EXPORTING;
651 mISDNport->b_remote_id[i] = p_m_remote_id;
652 mISDNport->b_remote_ref[i] = p_m_remote_ref;
655 /* create stack and send activation request */
656 if (_bchannel_create(mISDNport, i))
658 _bchannel_activate(mISDNport, i, 1);
659 state = B_STATE_ACTIVATING;
660 timer = now_d + B_TIMER_ACTIVATING;
665 case B_STATE_ACTIVATING:
666 case B_STATE_EXPORTING:
667 /* do nothing, because it is already activating */
670 case B_STATE_DEACTIVATING:
671 case B_STATE_IMPORTING:
672 /* do nothing, because we must wait until we can reactivate */
676 /* problems that might ocurr:
677 * B_EVENT_USE is received when channel already in use.
678 * bchannel exported, but not freed by other port
680 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
684 case B_EVENT_EXPORTREQUEST:
685 /* special case where the bchannel is requested by remote */
688 PERROR("export request without remote channel set, please correct.\n");
694 /* in case, the bchannel is exported right after seize_bchannel */
695 /* export bchannel */
696 /* p_m_remote_id is set, when this event happens. */
697 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);
698 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
699 add_trace("type", NULL, "assign");
700 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
702 state = B_STATE_EXPORTING;
703 mISDNport->b_remote_id[i] = p_m_remote_id;
704 mISDNport->b_remote_ref[i] = p_m_remote_ref;
707 case B_STATE_ACTIVATING:
708 case B_STATE_EXPORTING:
709 /* do nothing, because it is already activating */
712 case B_STATE_DEACTIVATING:
713 case B_STATE_IMPORTING:
714 /* do nothing, because we must wait until we can reactivate */
718 /* bchannel is active, so we deactivate */
719 _bchannel_activate(mISDNport, i, 0);
720 state = B_STATE_DEACTIVATING;
721 timer = now_d + B_TIMER_DEACTIVATING;
725 /* problems that might ocurr:
726 * ... when channel already in use.
727 * bchannel exported, but not freed by other port
729 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
733 case B_EVENT_IMPORTREQUEST:
734 /* special case where the bchannel is released by remote */
737 PERROR("import request with remote channel set, please correct.\n");
744 /* bchannel is not exported */
747 case B_STATE_ACTIVATING:
748 case B_STATE_EXPORTING:
749 /* do nothing because we must wait until bchanenl is active before deactivating */
753 /* bchannel is exported, so we re-import */
754 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
755 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
756 add_trace("type", NULL, "remove");
757 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
759 state = B_STATE_IMPORTING;
762 case B_STATE_DEACTIVATING:
763 case B_STATE_IMPORTING:
764 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
768 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
772 case B_EVENT_ACTIVATED:
776 case B_STATE_ACTIVATING:
777 if (b_port && !p_m_remote_id)
779 /* bchannel is active and used by Port class, so we configure bchannel */
780 _bchannel_configure(mISDNport, i);
781 state = B_STATE_ACTIVE;
782 b_port->p_m_load = 0;
785 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
786 _bchannel_activate(mISDNport, i, 0);
787 state = B_STATE_DEACTIVATING;
788 timer = now_d + B_TIMER_DEACTIVATING;
793 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
797 case B_EVENT_EXPORTED:
800 case B_STATE_EXPORTING:
801 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i])
803 /* remote export done */
804 state = B_STATE_REMOTE;
807 /* bchannel is now exported, but we need bchannel back
808 * OR bchannel is not used anymore
809 * OR bchannel has been exported to an obsolete ref,
810 * so reimport, to later export to new remote */
811 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
812 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
813 add_trace("type", NULL, "remove");
814 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
816 state = B_STATE_IMPORTING;
821 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
827 FATAL("bchannel must be linked to a Port class\n");
831 /* bchannel is idle due to an error, so we do nothing */
834 case B_STATE_ACTIVATING:
835 case B_STATE_EXPORTING:
836 /* do nothing because we must wait until bchanenl is active before deactivating */
840 /* bchannel is active, so we deactivate */
841 _bchannel_activate(mISDNport, i, 0);
842 state = B_STATE_DEACTIVATING;
843 timer = now_d + B_TIMER_DEACTIVATING;
847 /* bchannel is exported, so we re-import */
848 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
849 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
850 add_trace("type", NULL, "remove");
851 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
853 state = B_STATE_IMPORTING;
856 case B_STATE_DEACTIVATING:
857 case B_STATE_IMPORTING:
858 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
862 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
866 case B_EVENT_DEACTIVATED:
871 /* ignore due to deactivation confirm after unloading */
874 case B_STATE_DEACTIVATING:
875 _bchannel_destroy(mISDNport, i);
876 state = B_STATE_IDLE;
879 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
882 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);
883 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
884 add_trace("type", NULL, "assign");
885 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
887 state = B_STATE_EXPORTING;
888 mISDNport->b_remote_id[i] = p_m_remote_id;
889 mISDNport->b_remote_ref[i] = p_m_remote_ref;
892 if (_bchannel_create(mISDNport, i))
894 _bchannel_activate(mISDNport, i, 1);
895 state = B_STATE_ACTIVATING;
896 timer = now_d + B_TIMER_ACTIVATING;
903 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
907 case B_EVENT_IMPORTED:
910 case B_STATE_IMPORTING:
911 state = B_STATE_IDLE;
912 mISDNport->b_remote_id[i] = 0;
913 mISDNport->b_remote_ref[i] = 0;
916 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
919 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);
920 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
921 add_trace("type", NULL, "assign");
922 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
924 state = B_STATE_EXPORTING;
925 mISDNport->b_remote_id[i] = p_m_remote_id;
926 mISDNport->b_remote_ref[i] = p_m_remote_ref;
929 if (_bchannel_create(mISDNport, i))
931 _bchannel_activate(mISDNport, i, 1);
932 state = B_STATE_ACTIVATING;
933 timer = now_d + B_TIMER_ACTIVATING;
940 /* ignore, because not assigned */
945 case B_EVENT_TIMEOUT:
950 /* ignore due to deactivation confirm after unloading */
953 case B_STATE_ACTIVATING:
954 _bchannel_activate(mISDNport, i, 1);
955 timer = now_d + B_TIMER_ACTIVATING;
958 case B_STATE_DEACTIVATING:
959 _bchannel_activate(mISDNport, i, 0);
960 timer = now_d + B_TIMER_DEACTIVATING;
964 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
969 PERROR("Illegal event %d, please correct.\n", event);
972 mISDNport->b_state[i] = state;
973 mISDNport->b_timer[i] = timer;
980 * check for available channel and reserve+set it.
981 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
983 * returns -(cause value) or x = channel x or 0 = no channel
984 * NOTE: no activation is done here
986 int PmISDN::seize_bchannel(int channel, int exclusive)
990 /* the channel is what we have */
991 if (p_m_b_channel == channel)
994 /* if channel already in use, release it */
999 if (channel==CHANNEL_NO || channel==0)
1002 /* is channel in range ? */
1004 || (channel>p_m_mISDNport->b_num && channel<16)
1005 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
1006 return(-6); /* channel unacceptable */
1008 /* request exclusive channel */
1009 if (exclusive && channel>0)
1011 i = channel-1-(channel>16);
1012 if (p_m_mISDNport->b_port[i])
1013 return(-44); /* requested channel not available */
1017 /* ask for channel */
1020 i = channel-1-(channel>16);
1021 if (p_m_mISDNport->b_port[i] == NULL)
1025 /* search for channel */
1027 while(i < p_m_mISDNport->b_num)
1029 if (!p_m_mISDNport->b_port[i])
1031 channel = i+1+(i>=15);
1036 return(-34); /* no free channel */
1039 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
1041 /* link Port, set parameters */
1042 p_m_mISDNport->b_port[i] = this;
1044 p_m_b_channel = channel;
1045 p_m_b_exclusive = exclusive;
1046 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1048 /* reserve channel */
1052 p_m_mISDNport->b_reserved++;
1059 * drop reserved channel and unset it.
1060 * deactivation is also done
1062 void PmISDN::drop_bchannel(void)
1064 /* unreserve channel */
1066 p_m_mISDNport->b_reserved--;
1070 if (p_m_b_index < 0)
1075 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1077 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1078 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1079 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1080 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1083 p_m_b_exclusive = 0;
1086 /* process bchannel export/import message from join */
1087 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1089 class Endpoint *epoint;
1091 class PmISDN *isdnport;
1092 struct mISDNport *mISDNport;
1097 case BCHANNEL_REQUEST:
1098 /* find the port object for the join object ref */
1099 if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
1101 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1104 if (!epoint->ep_portlist)
1106 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1109 if (epoint->ep_portlist->next)
1111 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);
1113 if (!(port = find_port_id(epoint->ep_portlist->port_id)))
1115 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1118 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN)
1120 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1122 isdnport = (class PmISDN *)port;
1125 if (isdnport->p_m_remote_id)
1127 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1130 mISDNport = isdnport->p_m_mISDNport;
1131 i = isdnport->p_m_b_index;
1132 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1133 add_trace("type", NULL, "export request");
1135 isdnport->p_m_remote_ref = joinremote->j_serial;
1136 isdnport->p_m_remote_id = joinremote->j_remote_id;
1137 if (mISDNport && i>=0)
1139 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1143 case BCHANNEL_RELEASE:
1144 case BCHANNEL_ASSIGN_ACK:
1145 case BCHANNEL_REMOVE_ACK:
1146 /* find mISDNport for stack ID */
1147 mISDNport = mISDNport_first;
1151 ii = mISDNport->b_num;
1154 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1160 mISDNport = mISDNport->next;
1164 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1168 if (type!=BCHANNEL_RELEASE)
1171 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1172 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1174 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1178 isdnport = mISDNport->b_port[i];
1179 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1180 add_trace("type", NULL, "import request");
1184 isdnport->p_m_remote_ref = 0;
1185 isdnport->p_m_remote_id = 0;
1187 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1191 PERROR("received wrong bchannel message type %d from remote\n", type);
1199 audio transmission procedure:
1200 -----------------------------
1203 three sources of audio transmission:
1204 - crypto-data high priority
1205 - tones high priority (also high)
1206 - remote-data low priority
1209 a variable that temporarily shows the number of samples elapsed since last transmission process.
1210 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1213 a variable that is increased whenever data is transmitted.
1214 it is decreased while time elapses. it stores the number of samples that
1215 are currently loaded to dsp module.
1216 since clock in dsp module is the same clock for user space process, these
1220 there are two levels:
1221 ISDN_LOAD will give the load that have to be kept in dsp.
1222 ISDN_MAXLOAD will give the maximum load before dropping.
1224 * procedure for low priority data
1225 see txfromup() for procedure
1226 in short: remote data is ignored during high priority tones
1228 * procedure for high priority data
1229 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1230 if no more data is available, load becomes empty again.
1233 0 ISDN_LOAD ISDN_MAXLOAD
1234 +--------------------+----------------------+
1236 +--------------------+----------------------+
1238 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1239 0 ISDN_LOAD ISDN_MAXLOAD
1240 +--------------------+----------------------+
1241 |TTTTTTTTTTTTTTTTTTTT| |
1242 +--------------------+----------------------+
1244 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1245 0 ISDN_LOAD ISDN_MAXLOAD
1246 +--------------------+----------------------+
1247 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1248 +--------------------+----------------------+
1251 int PmISDN::handler(void)
1253 struct lcr_msg *message;
1257 if ((ret = Port::handler()))
1261 if (p_m_last_tv_sec)
1263 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1264 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1267 /* set clock of first process ever in this instance */
1268 p_m_last_tv_sec = now_tv.tv_sec;
1269 p_m_last_tv_msec = now_tv.tv_usec/1000;
1271 /* process only if we have a minimum of samples, to make packets not too small */
1272 if (elapsed >= ISDN_TRANSMIT
1273 && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1275 /* set clock of last process! */
1276 p_m_last_tv_sec = now_tv.tv_sec;
1277 p_m_last_tv_msec = now_tv.tv_usec/1000;
1280 if (elapsed < p_m_load)
1281 p_m_load -= elapsed;
1285 /* to send data, tone must be active OR crypt messages must be on */
1286 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1287 && (p_m_load < ISDN_LOAD)
1288 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones))
1290 int tosend = ISDN_LOAD - p_m_load, length;
1291 unsigned char buf[MISDN_HEADER_LEN+tosend];
1292 struct mISDNhead *frm = (struct mISDNhead *)buf;
1293 unsigned char *p = buf+MISDN_HEADER_LEN;
1295 /* copy crypto loops */
1296 while (p_m_crypt_msg_loops && tosend)
1298 /* how much do we have to send */
1299 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1302 if (length > tosend)
1305 /* copy message (part) to buffer */
1306 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1309 p_m_crypt_msg_current += length;
1310 if (p_m_crypt_msg_current == p_m_crypt_msg_len)
1313 p_m_crypt_msg_current = 0;
1314 p_m_crypt_msg_loops--;
1315 // puts("eine loop weniger");
1323 if (p_tone_name[0] && tosend)
1325 tosend -= read_audio(p, tosend);
1329 if (ISDN_LOAD - p_m_load - tosend > 0)
1331 frm->prim = PH_DATA_REQ;
1333 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1335 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);
1336 p_m_load += ISDN_LOAD - p_m_load - tosend;
1341 // NOTE: deletion is done by the child class
1343 /* handle timeouts */
1346 if (p_m_timer+p_m_timeout < now_d)
1348 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1350 /* send timeout to endpoint */
1351 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1352 message->param.state = p_state;
1353 message_put(message);
1358 return(0); /* nothing done */
1363 * whenever we get audio data from bchannel, we process it here
1365 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1367 unsigned int cont = *((unsigned int *)data);
1368 unsigned char *data_temp;
1369 unsigned int length_temp;
1370 struct lcr_msg *message;
1374 if (hh->prim == PH_CONTROL_IND)
1378 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1381 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
1383 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1384 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1386 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1387 message->param.dtmf = cont & DTMF_TONE_MASK;
1388 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1389 message_put(message);
1395 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1396 add_trace("DSP-CRYPT", NULL, "error");
1398 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1399 message->param.crypt.type = CC_ERROR_IND;
1400 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1401 message_put(message);
1405 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1406 add_trace("DSP-CRYPT", NULL, "ok");
1408 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1409 message->param.crypt.type = CC_ACTBF_CONF;
1410 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1411 message_put(message);
1415 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1416 add_trace("unknown", NULL, "0x%x", cont);
1421 if (hh->prim == PH_CONTROL_IND)
1426 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1427 add_trace("unknown", NULL, "0x%x", hh->id);
1432 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ)
1436 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1437 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1440 /* see below (same condition) */
1441 if (p_state!=PORT_STATE_CONNECT
1442 && !p_m_mISDNport->tones)
1444 // printf(".");fflush(stdout);return;
1446 record(data, len, 1); // from up
1449 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND)
1451 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1455 /* calls will not process any audio data unless
1456 * the call is connected OR tones feature is enabled.
1458 #ifndef DEBUG_COREBRIDGE
1459 if (p_state!=PORT_STATE_CONNECT
1460 && !p_m_mISDNport->tones)
1465 /* the bearer capability must be audio in order to send and receive
1466 * audio prior or after connect.
1468 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1472 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1475 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1481 record(data, len, 0); // from down
1483 /* randomize and listen to crypt message if enabled */
1484 if (p_m_crypt_listen)
1486 /* the noisy randomizer */
1490 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1492 cryptman_listen_bch(data, len);
1497 /* send data to epoint */
1498 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) /* only if we have an epoint object */
1504 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1505 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1506 memcpy(message->param.data.data, data_temp, message->param.data.len);
1507 message_put(message);
1508 if (length_temp <= sizeof(message->param.data.data))
1510 data_temp += sizeof(message->param.data.data);
1511 length_temp -= sizeof(message->param.data.data);
1520 void PmISDN::set_echotest(int echo)
1522 if (p_m_echo != echo)
1525 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1527 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1528 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);
1535 void PmISDN::set_tone(const char *dir, const char *tone)
1541 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1548 /* check if we NOT really have to use a dsp-tone */
1549 if (!options.dsptones)
1553 if (p_m_b_index > -1)
1554 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)
1556 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1557 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1560 Port::set_tone(dir, tone);
1566 /* now we USE dsp-tone, convert name */
1567 else if (!strcmp(tone, "dialtone"))
1569 switch(options.dsptones) {
1570 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1571 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1572 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1574 } else if (!strcmp(tone, "dialpbx"))
1576 switch(options.dsptones) {
1577 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1578 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1579 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1581 } else if (!strcmp(tone, "ringing"))
1583 switch(options.dsptones) {
1584 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1585 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1586 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1588 } else if (!strcmp(tone, "ringpbx"))
1590 switch(options.dsptones) {
1591 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1592 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1593 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1595 } else if (!strcmp(tone, "busy"))
1598 switch(options.dsptones) {
1599 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1600 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1601 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1603 } else if (!strcmp(tone, "release"))
1606 switch(options.dsptones) {
1607 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1608 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1609 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1611 } else if (!strcmp(tone, "cause_10"))
1613 else if (!strcmp(tone, "cause_11"))
1615 else if (!strcmp(tone, "cause_22"))
1617 switch(options.dsptones) {
1618 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1619 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1620 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1622 } else if (!strncmp(tone, "cause_", 6))
1623 id = TONE_SPECIAL_INFO;
1627 /* if we have a tone that is not supported by dsp */
1628 if (id==TONE_OFF && tone[0])
1636 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
1637 if (p_m_b_index > -1)
1638 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)
1639 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);
1641 /* turn user-space tones off in cases of no tone OR dsp tone */
1642 Port::set_tone("",NULL);
1646 /* MESSAGE_mISDNSIGNAL */
1647 //extern struct lcr_msg *dddebug;
1648 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1650 switch(param->mISDNsignal.message)
1652 case mISDNSIGNAL_VOLUME:
1653 if (p_m_tx_gain != param->mISDNsignal.tx_gain)
1655 p_m_tx_gain = param->mISDNsignal.tx_gain;
1656 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1657 if (p_m_b_index > -1)
1658 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)
1659 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);
1661 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1662 if (p_m_rx_gain != param->mISDNsignal.rx_gain)
1664 p_m_rx_gain = param->mISDNsignal.rx_gain;
1665 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1666 if (p_m_b_index > -1)
1667 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)
1668 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);
1670 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1673 case mISDNSIGNAL_CONF:
1674 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1675 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1676 if (p_m_conf != param->mISDNsignal.conf)
1678 p_m_conf = param->mISDNsignal.conf;
1679 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1680 if (p_m_b_index > -1)
1681 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1682 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);
1684 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1685 /* we must set, even if currently tone forbids conf */
1686 p_m_conf = param->mISDNsignal.conf;
1687 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1690 case mISDNSIGNAL_JOINDATA:
1691 if (p_m_joindata != param->mISDNsignal.joindata)
1693 p_m_joindata = param->mISDNsignal.joindata;
1694 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1696 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1699 case mISDNSIGNAL_DELAY:
1700 if (p_m_delay != param->mISDNsignal.delay)
1702 p_m_delay = param->mISDNsignal.delay;
1703 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1704 if (p_m_b_index > -1)
1705 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1706 ph_control(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);
1708 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1712 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1717 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1719 struct lcr_msg *message;
1721 switch(param->crypt.type)
1723 case CC_ACTBF_REQ: /* activate blowfish */
1725 p_m_crypt_key_len = param->crypt.len;
1726 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key))
1728 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1729 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1730 message->param.crypt.type = CC_ERROR_IND;
1731 message_put(message);
1734 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1736 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1737 if (p_m_b_index > -1)
1738 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)
1739 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);
1742 case CC_DACT_REQ: /* deactivate session encryption */
1747 case CR_LISTEN_REQ: /* start listening to messages */
1748 p_m_crypt_listen = 1;
1749 p_m_crypt_listen_state = 0;
1752 case CR_UNLISTEN_REQ: /* stop listening to messages */
1753 p_m_crypt_listen = 0;
1756 case CR_MESSAGE_REQ: /* send message */
1757 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1758 if (!p_m_crypt_msg_len)
1760 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1763 p_m_crypt_msg_current = 0; /* reset */
1764 p_m_crypt_msg_loops = 6; /* enable */
1766 /* disable txmix, or we get corrupt data due to audio process */
1767 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1769 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1770 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1776 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1782 * endpoint sends messages to the port
1784 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1786 if (Port::message_epoint(epoint_id, message_id, param))
1791 case MESSAGE_DATA: /* tx-data from upper layer */
1792 txfromup(param->data.data, param->data.len);
1795 case MESSAGE_mISDNSIGNAL: /* user command */
1796 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1797 message_mISDNsignal(epoint_id, message_id, param);
1800 case MESSAGE_CRYPT: /* crypt control command */
1801 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1802 message_crypt(epoint_id, message_id, param);
1811 * main loop for processing messages from mISDN
1813 int mISDN_handler(void)
1816 struct mISDNport *mISDNport;
1817 class PmISDN *isdnport;
1819 unsigned char buffer[2048+MISDN_HEADER_LEN];
1820 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1824 /* process all ports */
1825 mISDNport = mISDNport_first;
1828 /* process all bchannels */
1830 while(i < mISDNport->b_num)
1832 /* process timer events for bchannel handling */
1833 if (mISDNport->b_timer[i])
1835 if (mISDNport->b_timer[i] <= now_d)
1836 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1838 /* handle port of bchannel */
1839 isdnport=mISDNport->b_port[i];
1842 /* call bridges in user space OR crypto OR recording */
1843 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record)
1845 /* rx IS required */
1846 if (isdnport->p_m_rxoff)
1849 isdnport->p_m_rxoff = 0;
1850 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1851 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1852 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1857 /* rx NOT required */
1858 if (!isdnport->p_m_rxoff)
1861 isdnport->p_m_rxoff = 1;
1862 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1863 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1864 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1869 if (isdnport->p_record)
1871 /* txdata IS required */
1872 if (!isdnport->p_m_txdata)
1875 isdnport->p_m_txdata = 1;
1876 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1877 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1878 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1883 /* txdata NOT required */
1884 if (isdnport->p_m_txdata)
1887 isdnport->p_m_txdata = 0;
1888 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1889 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1890 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1896 /* handle message from bchannel */
1897 if (mISDNport->b_socket[i] > -1)
1899 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1900 if (ret >= (int)MISDN_HEADER_LEN)
1905 /* we don't care about confirms, we use rx data to sync tx */
1909 /* we receive audio data, we respond to it AND we send tones */
1914 case PH_CONTROL_IND:
1915 if (mISDNport->b_port[i])
1916 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1918 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1921 case PH_ACTIVATE_IND:
1922 case DL_ESTABLISH_IND:
1923 case PH_ACTIVATE_CNF:
1924 case DL_ESTABLISH_CNF:
1925 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1926 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1929 case PH_DEACTIVATE_IND:
1930 case DL_RELEASE_IND:
1931 case PH_DEACTIVATE_CNF:
1932 case DL_RELEASE_CNF:
1933 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1934 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1938 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1942 if (ret < 0 && errno != EWOULDBLOCK)
1943 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1950 /* handle queued up-messages (d-channel) */
1951 while ((mb = mdequeue(&mISDNport->upqueue)))
1956 case MPH_ACTIVATE_IND:
1957 if (mISDNport->l1link != 1)
1959 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1961 mISDNport->l1link = 1;
1965 case MPH_DEACTIVATE_IND:
1966 if (mISDNport->l1link != 0)
1968 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1970 mISDNport->l1link = 0;
1974 case MPH_INFORMATION_IND:
1975 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1978 case L1_SIGNAL_LOS_ON:
1981 case L1_SIGNAL_LOS_OFF:
1984 case L1_SIGNAL_AIS_ON:
1987 case L1_SIGNAL_AIS_OFF:
1990 case L1_SIGNAL_RDI_ON:
1993 case L1_SIGNAL_RDI_OFF:
1996 case L1_SIGNAL_SLIP_TX:
1997 mISDNport->slip_tx++;
1999 case L1_SIGNAL_SLIP_RX:
2000 mISDNport->slip_rx++;
2005 case MT_L2ESTABLISH:
2006 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
2007 add_trace("tei", NULL, "%d", l3m->pid);
2009 mISDNport->l2link = 1;
2010 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2012 if (mISDNport->l2establish)
2014 mISDNport->l2establish = 0;
2015 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
2021 if (!mISDNport->l2establish)
2023 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
2024 add_trace("tei", NULL, "%d", l3m->pid);
2026 /* down if not nt-ptmp */
2027 if (!mISDNport->ntmode || mISDNport->ptp)
2028 mISDNport->l2link = 0;
2030 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127)
2032 if (!mISDNport->l2establish && mISDNport->l2hold)
2034 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
2035 time(&mISDNport->l2establish);
2036 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2042 /* l3-data is sent to LCR */
2043 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
2050 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
2052 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
2053 mISDNport->l1timeout = 0;
2056 /* layer 2 establish timer */
2057 if (mISDNport->l2establish)
2059 if (now-mISDNport->l2establish > 5)
2061 mISDNport->l2establish = 0;
2062 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2065 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
2066 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2067 time(&mISDNport->l2establish);
2074 mISDNport = mISDNport->next;
2077 /* if we received at least one b-frame, we will return 1 */
2081 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
2085 * l3m must be queued, except for MT_ASSIGN
2088 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
2091 /* special MT_ASSIGN handling:
2093 * if we request a PID from mlayer, we always do it while lcr is locked.
2094 * therefore we must check the MT_ASSIGN reply first before we lock.
2095 * this is because the MT_ASSIGN reply is received with the requesting
2096 * process, not by the mlayer thread!
2097 * this means, that the reply is sent during call of the request.
2098 * we must check if we get a reply and we know that we lcr is currently
2101 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER)
2103 /* let's do some checking if someone changes stack behaviour */
2104 if (mt_assign_pid != 0)
2105 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
2106 mt_assign_pid = pid;
2110 /* queue message, create, if required */
2113 l3m = alloc_l3_msg();
2115 FATAL("No memory for layer 3 message\n");
2117 mb = container_of(l3m, struct mbuffer, l3);
2120 mqueue_tail(&mISDNport->upqueue, mb);
2126 * global function to add a new card (port)
2128 struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l2hold, struct interface *interface)
2131 struct mISDNport *mISDNport, **mISDNportp;
2135 // struct mlayer3 *ml3;
2136 struct mISDN_devinfo devinfo;
2137 unsigned int protocol, prop;
2139 /* check port counts */
2140 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2143 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2149 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2159 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2162 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2165 if (!strcasecmp(devinfo.name, portname))
2171 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", portname);
2174 // note: 'port' has still the port number
2176 if (port>cnt || port<0)
2178 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2182 /* get port attributes */
2183 pri = bri = pots = nt = te = 0;
2185 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2188 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2191 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0))
2196 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0))
2201 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1))
2206 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1))
2212 if (devinfo.Dprotocols & (1 << ISDN_P_FXS))
2219 if (devinfo.Dprotocols & (1 << ISDN_P_FXO))
2225 if (force_nt && !nt)
2227 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2232 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2235 if (pots && !bri && !pri)
2237 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2242 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2247 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2250 /* set NT by turning off TE */
2253 /* if TE an NT is supported (and not forced to NT), turn off NT */
2257 /* check for double use of port */
2260 mISDNport = mISDNport_first;
2263 if (mISDNport->portnum == port)
2265 mISDNport = mISDNport->next;
2269 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2275 /* add mISDNport structure */
2276 mISDNportp = &mISDNport_first;
2278 mISDNportp = &((*mISDNportp)->next);
2279 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2280 mISDNport->l1link = -1;
2281 mISDNport->l2link = -1;
2283 *mISDNportp = mISDNport;
2285 /* if pri, must set PTP */
2306 /* allocate ressources of port */
2307 /* open layer 3 and init upqueue */
2308 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2309 prop = (1 << MISDN_FLG_L2_CLEAN);
2310 if (ptp) // ptp forced
2311 prop |= (1 << MISDN_FLG_PTP);
2312 if (nt) // supports hold/retrieve on nt-mode
2313 prop |= (1 << MISDN_FLG_NET_HOLD);
2314 if (l2hold) // supports layer 2 hold
2315 prop |= (1 << MISDN_FLG_L2_HOLD);
2316 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2317 mqueue_init(&mISDNport->upqueue);
2318 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2319 if (!mISDNport->ml3)
2321 mqueue_purge(&mISDNport->upqueue);
2322 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2330 "PORT (open failed)");
2332 mISDNport_close(mISDNport);
2337 /* if ntmode, establish L1 to send the tei removal during start */
2338 if (mISDNport->ntmode)
2342 act.prim = PH_ACTIVATE | REQUEST;
2343 act.addr = mISDNport->upper_id | FLG_MSG_DOWN;
2344 printf("UPPER ID 0x%x, addr 0x%x\n",mISDNport->upper_id, act.addr);
2347 mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
2348 usleep(10000); /* to be sure, that l1 is up */
2352 SCPY(mISDNport->name, devinfo.name);
2353 mISDNport->b_num = devinfo.nrbchan;
2354 mISDNport->portnum = port;
2355 mISDNport->ntmode = nt;
2356 mISDNport->tespecial = te_special;
2357 mISDNport->pri = pri;
2358 mISDNport->ptp = ptp;
2359 mISDNport->l2hold = l2hold;
2360 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2362 while(i < mISDNport->b_num)
2364 mISDNport->b_state[i] = B_STATE_IDLE;
2365 mISDNport->b_socket[i] = -1;
2369 /* if ptp, pull up the link */
2370 if (mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode))
2372 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2373 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2374 add_trace("tei", NULL, "%d", 0);
2376 time(&mISDNport->l2establish);
2379 /* for nt-mode ptmp the link is always up */
2380 if (mISDNport->ntmode && !mISDNport->ptp)
2381 mISDNport->l2link = 1;
2383 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2385 start_trace(mISDNport->portnum,
2393 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2394 add_trace("channels", NULL, "%d", mISDNport->b_num);
2401 * function to free ALL cards (ports)
2403 void mISDNport_close_all(void)
2405 /* free all ports */
2406 while(mISDNport_first)
2407 mISDNport_close(mISDNport_first);
2411 * free only one port
2413 void mISDNport_close(struct mISDNport *mISDNport)
2415 struct mISDNport **mISDNportp;
2417 class PmISDN *isdnport;
2420 /* remove all port instance that are linked to this mISDNport */
2424 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN)
2426 isdnport = (class PmISDN *)port;
2427 if (isdnport->p_m_mISDNport)
2429 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2436 /* only if we are already part of interface */
2437 if (mISDNport->ifport)
2439 start_trace(mISDNport->portnum,
2440 mISDNport->ifport->interface,
2450 /* free bchannels */
2452 while(i < mISDNport->b_num)
2454 if (mISDNport->b_socket[i] > -1)
2456 _bchannel_destroy(mISDNport, i);
2457 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2462 /* close layer 3, if open and purge upqueue */
2465 close_layer3(mISDNport->ml3);
2466 mqueue_purge(&mISDNport->upqueue);
2469 /* remove from list */
2470 mISDNportp = &mISDNport_first;
2473 if (*mISDNportp == mISDNport)
2475 *mISDNportp = (*mISDNportp)->next;
2479 mISDNportp = &((*mISDNportp)->next);
2483 FATAL("mISDNport not in list\n");
2485 FREE(mISDNport, sizeof(struct mISDNport));
2492 * enque data from upper buffer
2494 void PmISDN::txfromup(unsigned char *data, int length)
2496 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2497 struct mISDNhead *hh = (struct mISDNhead *)buf;
2500 if (p_m_b_index < 0)
2502 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2505 /* check if high priority tones exist
2506 * ignore data in this case
2508 if (p_tone_name[0] || p_m_crypt_msg_loops)
2511 /* preload procedure
2512 * if transmit buffer in DSP module is empty,
2513 * preload it to DSP_LOAD to prevent jitter gaps.
2515 if (p_m_load==0 && ISDN_LOAD>0)
2517 hh->prim = PH_DATA_REQ;
2519 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2520 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2522 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2523 p_m_load += ISDN_LOAD;
2526 /* drop if load would exceed ISDN_MAXLOAD
2527 * this keeps the delay not too high
2529 if (p_m_load+length > ISDN_MAXLOAD)
2532 /* make and send frame */
2533 hh->prim = PH_DATA_REQ;
2535 memcpy(buf+MISDN_HEADER_LEN, data, length);
2536 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2538 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);