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);
55 if (mISDNsocket < 0) {
56 fprintf(stderr, "Cannot open mISDN due to '%s'. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
61 init_layer3(4); // buffer of 4
63 /* open debug, if enabled and not only stack debugging */
65 SPRINT(filename, "%s/debug.log", LOG_DIR);
66 debug_fp = fopen(filename, "a");
69 if (options.deb & DEBUG_STACK) {
70 SPRINT(filename, "%s/debug_mISDN.log", LOG_DIR);
71 mISDN_debug_init(0xfffffeff, filename, filename, filename);
73 mISDN_debug_init(0, NULL, NULL, NULL);
78 void mISDN_deinitialize(void)
95 PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive, int mode) : Port(type, portname, settings)
97 p_m_mISDNport = mISDNport;
98 p_m_portnum = mISDNport->portnum;
106 p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
107 p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
115 p_m_dtmf = !mISDNport->ifport->nodtmf;
118 p_m_remote_ref = 0; /* channel shall be exported to given remote */
119 p_m_remote_id = 0; /* remote admin socket */
120 SCPY(p_m_pipeline, mISDNport->ifport->interface->pipeline);
128 p_m_crypt_listen = 0;
129 p_m_crypt_msg_loops = 0;
130 p_m_crypt_msg_loops = 0;
131 p_m_crypt_msg_len = 0;
132 p_m_crypt_msg[0] = '\0';
133 p_m_crypt_msg_current = 0;
134 p_m_crypt_key_len = 0;
135 p_m_crypt_listen = 0;
136 p_m_crypt_listen_state = 0;
137 p_m_crypt_listen_len = 0;
138 p_m_crypt_listen_msg[0] = '\0';
139 p_m_crypt_listen_crc = 0;
140 if (mISDNport->ifport->interface->bf_len >= 4 && mISDNport->ifport->interface->bf_len <= 56) {
141 memcpy(p_m_crypt_key, mISDNport->ifport->interface->bf_key, p_m_crypt_key_len);
142 p_m_crypt_key_len = mISDNport->ifport->interface->bf_len;
146 /* if any channel requested by constructor */
147 if (channel == CHANNEL_ANY) {
148 /* reserve channel */
150 mISDNport->b_reserved++;
153 /* reserve channel */
154 if (channel > 0) // only if constructor was called with a channel resevation
155 seize_bchannel(channel, exclusive);
157 /* we increase the number of objects: */
159 PDEBUG(DEBUG_ISDN, "Created new mISDNPort(%s). Currently %d objects use, port #%d\n", portname, mISDNport->use, p_m_portnum);
168 struct lcr_msg *message;
170 /* remove bchannel relation */
174 while (p_epointlist) {
175 PDEBUG(DEBUG_ISDN, "destroy mISDNPort(%s). endpoint still exists, releaseing.\n", p_name);
176 message = message_create(p_serial, p_epointlist->epoint_id, PORT_TO_EPOINT, MESSAGE_RELEASE);
177 message->param.disconnectinfo.cause = 16;
178 message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
179 message_put(message);
180 /* remove from list */
181 free_epointlist(p_epointlist);
184 /* we decrease the number of objects: */
185 p_m_mISDNport->use--;
186 PDEBUG(DEBUG_ISDN, "destroyed mISDNPort(%s). Currently %d objects\n", p_name, p_m_mISDNport->use);
193 void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, const char *msgtext, int direction)
195 /* init trace with given values */
196 start_trace(mISDNport?mISDNport->portnum:-1,
197 (mISDNport)?((mISDNport->ifport)?mISDNport->ifport->interface:NULL):NULL,
198 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
199 port?port->p_dialinginfo.id:NULL,
202 port?port->p_serial:0,
210 static struct isdn_message {
214 {"PH_ACTIVATE", L1_ACTIVATE_REQ},
215 {"PH_DEACTIVATE", L1_DEACTIVATE_REQ},
216 {"DL_ESTABLISH", L2_ESTABLISH_REQ},
217 {"DL_RELEASE", L2_RELEASE_REQ},
218 {"UNKNOWN", L3_UNKNOWN_REQ},
219 {"MT_TIMEOUT", L3_TIMEOUT_REQ},
220 {"MT_SETUP", L3_SETUP_REQ},
221 {"MT_SETUP_ACK", L3_SETUP_ACKNOWLEDGE_REQ},
222 {"MT_PROCEEDING", L3_PROCEEDING_REQ},
223 {"MT_ALERTING", L3_ALERTING_REQ},
224 {"MT_CONNECT", L3_CONNECT_REQ},
225 {"MT_CONNECT_ACK", L3_CONNECT_ACKNOWLEDGE_REQ},
226 {"MT_DISCONNECT", L3_DISCONNECT_REQ},
227 {"MT_RELEASE", L3_RELEASE_REQ},
228 {"MT_RELEASE_COMP", L3_RELEASE_COMPLETE_REQ},
229 {"MT_INFORMATION", L3_INFORMATION_REQ},
230 {"MT_PROGRESS", L3_PROGRESS_REQ},
231 {"MT_NOTIFY", L3_NOTIFY_REQ},
232 {"MT_SUSPEND", L3_SUSPEND_REQ},
233 {"MT_SUSPEND_ACK", L3_SUSPEND_ACKNOWLEDGE_REQ},
234 {"MT_SUSPEND_REJ", L3_SUSPEND_REJECT_REQ},
235 {"MT_RESUME", L3_RESUME_REQ},
236 {"MT_RESUME_ACK", L3_RESUME_ACKNOWLEDGE_REQ},
237 {"MT_RESUME_REJ", L3_RESUME_REJECT_REQ},
238 {"MT_HOLD", L3_HOLD_REQ},
239 {"MT_HOLD_ACK", L3_HOLD_ACKNOWLEDGE_REQ},
240 {"MT_HOLD_REJ", L3_HOLD_REJECT_REQ},
241 {"MT_RETRIEVE", L3_RETRIEVE_REQ},
242 {"MT_RETRIEVE_ACK", L3_RETRIEVE_ACKNOWLEDGE_REQ},
243 {"MT_RETRIEVE_REJ", L3_RETRIEVE_REJECT_REQ},
244 {"MT_FACILITY", L3_FACILITY_REQ},
245 {"MT_STATUS", L3_STATUS_REQ},
246 {"MT_RESTART", L3_RESTART_REQ},
247 {"MT_NEW_L3ID", L3_NEW_L3ID_REQ},
248 {"MT_RELEASE_L3ID", L3_RELEASE_L3ID_REQ},
251 static const char *isdn_prim[4] = {
257 void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned int msg, int direction)
262 SCPY(msgtext, "<<UNKNOWN MESSAGE>>");
263 /* select message and primitive text */
265 while(isdn_message[i].name) {
266 // if (msg == L3_NOTIFY_REQ) printf("val = %x %s\n", isdn_message[i].value, isdn_message[i].name);
267 if (isdn_message[i].value == (msg&0xffffff00)) {
268 SCPY(msgtext, isdn_message[i].name);
273 SCAT(msgtext, isdn_prim[msg&0x00000003]);
276 if (direction && (msg&0xffffff00)!=L3_NEW_L3ID_REQ && (msg&0xffffff00)!=L3_RELEASE_L3ID_REQ) {
278 if (mISDNport->ntmode) {
279 if (direction == DIRECTION_OUT)
280 SCAT(msgtext, " N->U");
282 SCAT(msgtext, " N<-U");
284 if (direction == DIRECTION_OUT)
285 SCAT(msgtext, " U->N");
287 SCAT(msgtext, " U<-N");
292 /* init trace with given values */
293 start_trace(mISDNport?mISDNport->portnum:-1,
294 mISDNport?(mISDNport->ifport?mISDNport->ifport->interface:NULL):NULL,
295 port?numberrize_callerinfo(port->p_callerinfo.id, port->p_callerinfo.ntype, options.national, options.international):NULL,
296 port?port->p_dialinginfo.id:NULL,
299 port?port->p_serial:0,
305 * send control information to the channel (dsp-module)
307 void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, int sock, unsigned int c1, unsigned int c2, const char *trace_name, int trace_value)
309 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
310 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
311 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
317 ctrl->prim = PH_CONTROL_REQ;
321 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
323 PERROR("Failed to send to socket %d\n", sock);
324 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
325 if (c1 == DSP_CONF_JOIN)
326 add_trace(trace_name, NULL, "0x%08x", trace_value);
328 add_trace(trace_name, NULL, "%d", trace_value);
332 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)
334 unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
335 struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
336 unsigned int *d = (unsigned int *)(buffer+MISDN_HEADER_LEN);
342 ctrl->prim = PH_CONTROL_REQ;
345 memcpy(d, c2, c2_len);
346 ret = sendto(sock, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
348 PERROR("Failed to send to socket %d\n", sock);
349 chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
350 add_trace(trace_name, NULL, "%d", trace_value);
356 * subfunction for bchannel_event
359 static int _bchannel_create(struct mISDNport *mISDNport, int i)
363 struct sockaddr_mISDN addr;
365 if (mISDNport->b_socket[i] > -1) {
366 PERROR("Error: Socket already created for index %d\n", i);
371 //#warning testing without DSP
372 // mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_HDLC:ISDN_P_B_RAW);
373 mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, (mISDNport->b_mode[i]==B_MODE_HDLC)?ISDN_P_B_L2DSPHDLC:ISDN_P_B_L2DSP);
374 if (mISDNport->b_socket[i] < 0) {
375 PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDN_dsp.ko?\n", i);
379 /* set nonblocking io */
380 ret = ioctl(mISDNport->b_socket[i], FIONBIO, &on);
382 PERROR("Error: Failed to set bchannel-socket index %d into nonblocking IO\n", i);
383 close(mISDNport->b_socket[i]);
384 mISDNport->b_socket[i] = -1;
388 /* bind socket to bchannel */
389 addr.family = AF_ISDN;
390 addr.dev = mISDNport->portnum;
391 addr.channel = i+1+(i>=15);
392 ret = bind(mISDNport->b_socket[i], (struct sockaddr *)&addr, sizeof(addr));
394 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);
395 close(mISDNport->b_socket[i]);
396 mISDNport->b_socket[i] = -1;
400 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
401 add_trace("channel", NULL, "%d", i+1+(i>=15));
402 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
410 * subfunction for bchannel_event
411 * activate / deactivate request
413 static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
415 struct mISDNhead act;
418 if (mISDNport->b_socket[i] < 0)
420 act.prim = (activate)?PH_ACTIVATE_REQ:PH_DEACTIVATE_REQ;
422 ret = sendto(mISDNport->b_socket[i], &act, MISDN_HEADER_LEN, 0, NULL, 0);
424 PERROR("Failed to send to socket %d\n", mISDNport->b_socket[i]);
427 chan_trace_header(mISDNport, mISDNport->b_port[i], activate ? "BCHANNEL activate" : "BCHANNEL deactivate", DIRECTION_OUT);
428 add_trace("channel", NULL, "%d", i+1+(i>=15));
429 if (mISDNport->b_timer[i])
430 add_trace("event", NULL, "timeout recovery");
436 * subfunction for bchannel_event
439 static void _bchannel_configure(struct mISDNport *mISDNport, int i)
444 if (mISDNport->b_socket[i] < 0)
446 handle = mISDNport->b_socket[i];
447 port = mISDNport->b_port[i];
448 mode = mISDNport->b_mode[i];
450 PERROR("bchannel index i=%d not associated with a port object\n", i);
454 /* set dsp features */
455 if (port->p_m_txdata)
456 ph_control(mISDNport, port, handle, (port->p_m_txdata)?DSP_TXDATA_ON:DSP_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
457 if (port->p_m_delay && mode == B_MODE_TRANSPARENT)
458 ph_control(mISDNport, port, handle, DSP_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
459 if (port->p_m_tx_gain && mode == B_MODE_TRANSPARENT)
460 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
461 if (port->p_m_rx_gain && mode == B_MODE_TRANSPARENT)
462 ph_control(mISDNport, port, handle, DSP_VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
463 if (port->p_m_pipeline[0] && mode == B_MODE_TRANSPARENT)
464 ph_control_block(mISDNport, port, handle, DSP_PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
466 ph_control(mISDNport, port, handle, DSP_CONF_JOIN, port->p_m_conf, "DSP-CONF", port->p_m_conf);
468 ph_control(mISDNport, port, handle, DSP_ECHO_ON, 0, "DSP-ECHO", 1);
469 if (port->p_m_tone && mode == B_MODE_TRANSPARENT)
470 ph_control(mISDNport, port, handle, DSP_TONE_PATT_ON, port->p_m_tone, "DSP-TONE", port->p_m_tone);
472 ph_control(mISDNport, port, handle, DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
473 // if (port->p_m_txmix && mode == B_MODE_TRANSPARENT)
474 // ph_control(mISDNport, port, handle, DSP_MIX_ON, 0, "DSP-MIX", 1);
475 if (port->p_m_dtmf && mode == B_MODE_TRANSPARENT)
476 ph_control(mISDNport, port, handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
477 if (port->p_m_crypt && mode == B_MODE_TRANSPARENT)
478 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);
482 * subfunction for bchannel_event
485 static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
487 if (mISDNport->b_socket[i] < 0)
489 chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
490 add_trace("channel", NULL, "%d", i+1+(i>=15));
491 add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
493 close(mISDNport->b_socket[i]);
494 mISDNport->b_socket[i] = -1;
502 A bchannel goes through the following states in this order:
505 No one is using the bchannel.
506 It is available and not linked to Port class, nor reserved.
509 The bchannel stack is created and an activation request is sent.
510 It MAY be linked to Port class, but already unlinked due to Port class removal.
513 The bchannel is active and cofigured to the Port class needs.
514 Also it is linked to a Port class, otherwhise it would be deactivated.
516 - B_STATE_DEACTIVATING
517 The bchannel is in deactivating state, due to deactivation request.
518 It may be linked to a Port class, that likes to reactivate it.
522 After deactivating bchannel, and if not used, the bchannel becomes idle again.
524 Also the bchannel may be exported, but only if the state is or becomes idle:
527 The bchannel assignment has been sent to the remove application.
530 The bchannel assignment is acknowledged by the remote application.
533 The bchannel is re-imported by mISDN port object.
537 After re-importing bchannel, and if not used, the bchannel becomes idle again.
540 A bchannel can have the following events:
543 A bchannel is required by a Port class.
546 The bchannel beomes active.
549 The bchannel is not required by Port class anymore
551 - B_EVENT_DEACTIVATED
552 The bchannel becomes inactive.
555 The bchannel is now used by remote application.
558 The bchannel is not used by remote application.
560 - B_EVENT_EXPORTREQUEST
561 The bchannel shall be exported to the remote application.
563 - B_EVENT_IMPORTREQUEST
564 The bchannel is released from the remote application.
566 All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
568 if an export request is receive by remote application, p_m_remote_* is set.
569 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.)
570 - set on export request from remote application (if port is assigned)
571 - set on channel use, if requested by remote application (p_m_remote_*)
572 - cleared on drop request
574 the bchannel will be exported with ref and stack given. remote application uses the ref to link bchannel to the call.
575 the bchannel will be imported with stack given only. remote application must store stack id with the bchannel process.
576 the bchannel import/export is acknowledged with stack given.
578 if exporting, b_remote_*[index] is set to the remote socket id.
579 if importing has been acknowledged. b_remote_*[index] is cleared.
584 * process bchannel events
585 * - mISDNport is a pointer to the port's structure
586 * - i is the index of the bchannel
587 * - event is the B_EVENT_* value
588 * - port is the PmISDN class pointer
590 void bchannel_event(struct mISDNport *mISDNport, int i, int event)
592 class PmISDN *b_port = mISDNport->b_port[i];
593 int state = mISDNport->b_state[i];
594 double timer = mISDNport->b_timer[i];
595 unsigned int p_m_remote_ref = 0;
596 unsigned int p_m_remote_id = 0;
599 char *p_m_pipeline = NULL;
600 unsigned char *p_m_crypt_key = NULL;
601 int p_m_crypt_key_len = 0;
602 int p_m_crypt_key_type = 0;
603 unsigned int portid = (mISDNport->portnum<<8) + i+1+(i>=15);
606 p_m_remote_id = b_port->p_m_remote_id;
607 p_m_remote_ref = b_port->p_m_remote_ref;
608 p_m_tx_gain = b_port->p_m_tx_gain;
609 p_m_rx_gain = b_port->p_m_rx_gain;
610 p_m_pipeline = b_port->p_m_pipeline;
611 p_m_crypt_key = b_port->p_m_crypt_key;
612 p_m_crypt_key_len = b_port->p_m_crypt_key_len;
613 p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
618 /* port must be linked in order to allow activation */
620 FATAL("bchannel must be linked to a Port class\n");
623 if (p_m_remote_ref) {
624 /* export bchannel */
625 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);
626 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
627 add_trace("type", NULL, "assign");
628 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
630 state = B_STATE_EXPORTING;
631 mISDNport->b_remote_id[i] = p_m_remote_id;
632 mISDNport->b_remote_ref[i] = p_m_remote_ref;
634 /* create stack and send activation request */
635 if (_bchannel_create(mISDNport, i)) {
636 _bchannel_activate(mISDNport, i, 1);
637 state = B_STATE_ACTIVATING;
638 timer = now_d + B_TIMER_ACTIVATING;
643 case B_STATE_ACTIVATING:
644 case B_STATE_EXPORTING:
645 /* do nothing, because it is already activating */
648 case B_STATE_DEACTIVATING:
649 case B_STATE_IMPORTING:
650 /* do nothing, because we must wait until we can reactivate */
654 /* problems that might ocurr:
655 * B_EVENT_USE is received when channel already in use.
656 * bchannel exported, but not freed by other port
658 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
662 case B_EVENT_EXPORTREQUEST:
663 /* special case where the bchannel is requested by remote */
664 if (!p_m_remote_ref) {
665 PERROR("export request without remote channel set, please correct.\n");
670 /* in case, the bchannel is exported right after seize_bchannel */
671 /* export bchannel */
672 /* p_m_remote_id is set, when this event happens. */
673 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);
674 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
675 add_trace("type", NULL, "assign");
676 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
678 state = B_STATE_EXPORTING;
679 mISDNport->b_remote_id[i] = p_m_remote_id;
680 mISDNport->b_remote_ref[i] = p_m_remote_ref;
683 case B_STATE_ACTIVATING:
684 case B_STATE_EXPORTING:
685 /* do nothing, because it is already activating */
688 case B_STATE_DEACTIVATING:
689 case B_STATE_IMPORTING:
690 /* do nothing, because we must wait until we can reactivate */
694 /* bchannel is active, so we deactivate */
695 _bchannel_activate(mISDNport, i, 0);
696 state = B_STATE_DEACTIVATING;
697 timer = now_d + B_TIMER_DEACTIVATING;
701 /* problems that might ocurr:
702 * ... when channel already in use.
703 * bchannel exported, but not freed by other port
705 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
709 case B_EVENT_IMPORTREQUEST:
710 /* special case where the bchannel is released by remote */
711 if (p_m_remote_ref) {
712 PERROR("import request with remote channel set, please correct.\n");
718 /* bchannel is not exported */
721 case B_STATE_ACTIVATING:
722 case B_STATE_EXPORTING:
723 /* do nothing because we must wait until bchanenl is active before deactivating */
727 /* bchannel is exported, so we re-import */
728 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
729 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
730 add_trace("type", NULL, "remove");
731 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
733 state = B_STATE_IMPORTING;
736 case B_STATE_DEACTIVATING:
737 case B_STATE_IMPORTING:
738 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
742 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
746 case B_EVENT_ACTIVATED:
749 case B_STATE_ACTIVATING:
750 if (b_port && !p_m_remote_id) {
751 /* bchannel is active and used by Port class, so we configure bchannel */
752 _bchannel_configure(mISDNport, i);
753 state = B_STATE_ACTIVE;
754 b_port->p_m_load = 0;
756 /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
757 _bchannel_activate(mISDNport, i, 0);
758 state = B_STATE_DEACTIVATING;
759 timer = now_d + B_TIMER_DEACTIVATING;
764 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
768 case B_EVENT_EXPORTED:
770 case B_STATE_EXPORTING:
771 if (b_port && p_m_remote_ref && p_m_remote_ref==mISDNport->b_remote_ref[i]) {
772 /* remote export done */
773 state = B_STATE_REMOTE;
775 /* bchannel is now exported, but we need bchannel back
776 * OR bchannel is not used anymore
777 * OR bchannel has been exported to an obsolete ref,
778 * so reimport, to later export to new remote */
779 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
780 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
781 add_trace("type", NULL, "remove");
782 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
784 state = B_STATE_IMPORTING;
789 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
795 FATAL("bchannel must be linked to a Port class\n");
798 /* bchannel is idle due to an error, so we do nothing */
801 case B_STATE_ACTIVATING:
802 case B_STATE_EXPORTING:
803 /* do nothing because we must wait until bchanenl is active before deactivating */
807 /* bchannel is active, so we deactivate */
808 _bchannel_activate(mISDNport, i, 0);
809 state = B_STATE_DEACTIVATING;
810 timer = now_d + B_TIMER_DEACTIVATING;
814 /* bchannel is exported, so we re-import */
815 message_bchannel_to_remote(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
816 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
817 add_trace("type", NULL, "remove");
818 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
820 state = B_STATE_IMPORTING;
823 case B_STATE_DEACTIVATING:
824 case B_STATE_IMPORTING:
825 /* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
829 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
833 case B_EVENT_DEACTIVATED:
837 /* ignore due to deactivation confirm after unloading */
840 case B_STATE_DEACTIVATING:
841 _bchannel_destroy(mISDNport, i);
842 state = B_STATE_IDLE;
844 /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
845 if (p_m_remote_ref) {
846 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);
847 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
848 add_trace("type", NULL, "assign");
849 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
851 state = B_STATE_EXPORTING;
852 mISDNport->b_remote_id[i] = p_m_remote_id;
853 mISDNport->b_remote_ref[i] = p_m_remote_ref;
855 if (_bchannel_create(mISDNport, i)) {
856 _bchannel_activate(mISDNport, i, 1);
857 state = B_STATE_ACTIVATING;
858 timer = now_d + B_TIMER_ACTIVATING;
865 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
869 case B_EVENT_IMPORTED:
871 case B_STATE_IMPORTING:
872 state = B_STATE_IDLE;
873 mISDNport->b_remote_id[i] = 0;
874 mISDNport->b_remote_ref[i] = 0;
876 /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
877 if (p_m_remote_ref) {
878 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);
879 chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
880 add_trace("type", NULL, "assign");
881 add_trace("channel", NULL, "%d.%d", portid>>8, portid&0xff);
883 state = B_STATE_EXPORTING;
884 mISDNport->b_remote_id[i] = p_m_remote_id;
885 mISDNport->b_remote_ref[i] = p_m_remote_ref;
887 if (_bchannel_create(mISDNport, i)) {
888 _bchannel_activate(mISDNport, i, 1);
889 state = B_STATE_ACTIVATING;
890 timer = now_d + B_TIMER_ACTIVATING;
897 /* ignore, because not assigned */
902 case B_EVENT_TIMEOUT:
906 /* ignore due to deactivation confirm after unloading */
909 case B_STATE_ACTIVATING:
910 _bchannel_activate(mISDNport, i, 1);
911 timer = now_d + B_TIMER_ACTIVATING;
914 case B_STATE_DEACTIVATING:
915 _bchannel_activate(mISDNport, i, 0);
916 timer = now_d + B_TIMER_DEACTIVATING;
920 PERROR("Illegal event %d at state %d, please correct.\n", event, state);
925 PERROR("Illegal event %d, please correct.\n", event);
928 mISDNport->b_state[i] = state;
929 mISDNport->b_timer[i] = timer;
936 * check for available channel and reserve+set it.
937 * give channel number or SEL_CHANNEL_ANY or SEL_CHANNEL_NO
939 * returns -(cause value) or x = channel x or 0 = no channel
940 * NOTE: no activation is done here
942 int PmISDN::seize_bchannel(int channel, int exclusive)
946 /* the channel is what we have */
947 if (p_m_b_channel == channel)
950 /* if channel already in use, release it */
955 if (channel==CHANNEL_NO || channel==0)
958 /* is channel in range ? */
960 || (channel>p_m_mISDNport->b_num && channel<16)
961 || ((channel-1)>p_m_mISDNport->b_num && channel>16)) /* channel-1 because channel 16 is not counted */
962 return(-6); /* channel unacceptable */
964 /* request exclusive channel */
965 if (exclusive && channel>0) {
966 i = channel-1-(channel>16);
967 if (p_m_mISDNport->b_port[i])
968 return(-44); /* requested channel not available */
972 /* ask for channel */
974 i = channel-1-(channel>16);
975 if (p_m_mISDNport->b_port[i] == NULL)
979 /* search for channel */
981 while(i < p_m_mISDNport->b_num) {
982 if (!p_m_mISDNport->b_port[i]) {
983 channel = i+1+(i>=15);
988 return(-34); /* no free channel */
991 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) seizing bchannel %d (index %d)\n", p_name, channel, i);
993 /* link Port, set parameters */
994 p_m_mISDNport->b_port[i] = this;
996 p_m_b_channel = channel;
997 p_m_b_exclusive = exclusive;
998 p_m_mISDNport->b_mode[i] = p_m_b_mode;
1000 /* reserve channel */
1001 if (!p_m_b_reserve) {
1003 p_m_mISDNport->b_reserved++;
1010 * drop reserved channel and unset it.
1011 * deactivation is also done
1013 void PmISDN::drop_bchannel(void)
1015 /* unreserve channel */
1017 p_m_mISDNport->b_reserved--;
1021 if (p_m_b_index < 0)
1026 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
1028 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
1029 bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP);
1030 p_m_mISDNport->b_port[p_m_b_index] = NULL;
1031 p_m_mISDNport->b_mode[p_m_b_index] = 0;
1034 p_m_b_exclusive = 0;
1037 /* process bchannel export/import message from join */
1038 void message_bchannel_from_remote(class JoinRemote *joinremote, int type, unsigned int handle)
1040 class Endpoint *epoint;
1042 class PmISDN *isdnport;
1043 struct mISDNport *mISDNport;
1047 case BCHANNEL_REQUEST:
1048 /* find the port object for the join object ref */
1049 if (!(epoint = find_epoint_id(joinremote->j_epoint_id))) {
1050 PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
1053 if (!epoint->ep_portlist) {
1054 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
1057 if (epoint->ep_portlist->next) {
1058 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);
1060 if (!(port = find_port_id(epoint->ep_portlist->port_id))) {
1061 PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
1064 if ((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN) {
1065 PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
1067 isdnport = (class PmISDN *)port;
1070 if (isdnport->p_m_remote_id) {
1071 PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
1074 mISDNport = isdnport->p_m_mISDNport;
1075 i = isdnport->p_m_b_index;
1076 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1077 add_trace("type", NULL, "export request");
1079 isdnport->p_m_remote_ref = joinremote->j_serial;
1080 isdnport->p_m_remote_id = joinremote->j_remote_id;
1081 if (mISDNport && i>=0) {
1082 bchannel_event(mISDNport, i, B_EVENT_EXPORTREQUEST);
1086 case BCHANNEL_RELEASE:
1087 case BCHANNEL_ASSIGN_ACK:
1088 case BCHANNEL_REMOVE_ACK:
1089 /* find mISDNport for stack ID */
1090 mISDNport = mISDNport_first;
1093 ii = mISDNport->b_num;
1095 if ((unsigned int)(mISDNport->portnum<<8)+i+1+(i>=15) == handle)
1101 mISDNport = mISDNport->next;
1104 PERROR("received assign/remove ack for bchannel's handle=%x, but handle does not exist in any mISDNport structure.\n", handle);
1108 if (type!=BCHANNEL_RELEASE) {
1110 chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1111 add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
1113 bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED);
1116 isdnport = mISDNport->b_port[i];
1117 chan_trace_header(mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
1118 add_trace("type", NULL, "import request");
1121 isdnport->p_m_remote_ref = 0;
1122 isdnport->p_m_remote_id = 0;
1124 bchannel_event(mISDNport, i, B_EVENT_IMPORTREQUEST);
1128 PERROR("received wrong bchannel message type %d from remote\n", type);
1136 audio transmission procedure:
1137 -----------------------------
1140 three sources of audio transmission:
1141 - crypto-data high priority
1142 - tones high priority (also high)
1143 - remote-data low priority
1146 a variable that temporarily shows the number of samples elapsed since last transmission process.
1147 p_m_last_tv_* is used to store that last timestamp. this is used to calculate the time elapsed.
1150 a variable that is increased whenever data is transmitted.
1151 it is decreased while time elapses. it stores the number of samples that
1152 are currently loaded to dsp module.
1153 since clock in dsp module is the same clock for user space process, these
1157 there are two levels:
1158 ISDN_LOAD will give the load that have to be kept in dsp.
1159 ISDN_MAXLOAD will give the maximum load before dropping.
1161 * procedure for low priority data
1162 see txfromup() for procedure
1163 in short: remote data is ignored during high priority tones
1165 * procedure for high priority data
1166 whenever load is below ISDN_LOAD, load is filled up to ISDN_LOAD
1167 if no more data is available, load becomes empty again.
1170 0 ISDN_LOAD ISDN_MAXLOAD
1171 +--------------------+----------------------+
1173 +--------------------+----------------------+
1175 on empty load or on load below ISDN_LOAD, the load is inceased to ISDN_LOAD:
1176 0 ISDN_LOAD ISDN_MAXLOAD
1177 +--------------------+----------------------+
1178 |TTTTTTTTTTTTTTTTTTTT| |
1179 +--------------------+----------------------+
1181 on empty load, remote-audio causes the load with the remote audio to be increased to ISDN_LOAD.
1182 0 ISDN_LOAD ISDN_MAXLOAD
1183 +--------------------+----------------------+
1184 |TTTTTTTTTTTTTTTTTTTTRRRRR |
1185 +--------------------+----------------------+
1188 int PmISDN::handler(void)
1190 struct lcr_msg *message;
1194 if ((ret = Port::handler()))
1198 if (p_m_last_tv_sec) {
1199 elapsed = 8000 * (now_tv.tv_sec - p_m_last_tv_sec)
1200 + 8 * (now_tv.tv_usec/1000 - p_m_last_tv_msec);
1202 /* set clock of first process ever in this instance */
1203 p_m_last_tv_sec = now_tv.tv_sec;
1204 p_m_last_tv_msec = now_tv.tv_usec/1000;
1206 /* process only if we have a minimum of samples, to make packets not too small */
1207 if (elapsed >= ISDN_TRANSMIT
1208 && p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE) {
1209 /* set clock of last process! */
1210 p_m_last_tv_sec = now_tv.tv_sec;
1211 p_m_last_tv_msec = now_tv.tv_usec/1000;
1214 if (elapsed < p_m_load)
1215 p_m_load -= elapsed;
1219 /* to send data, tone must be active OR crypt messages must be on */
1220 if ((p_tone_name[0] || p_m_crypt_msg_loops)
1221 && (p_m_load < ISDN_LOAD)
1222 && (p_state==PORT_STATE_CONNECT || p_m_mISDNport->tones)) {
1223 int tosend = ISDN_LOAD - p_m_load, length;
1224 unsigned char buf[MISDN_HEADER_LEN+tosend];
1225 struct mISDNhead *frm = (struct mISDNhead *)buf;
1226 unsigned char *p = buf+MISDN_HEADER_LEN;
1228 /* copy crypto loops */
1229 while (p_m_crypt_msg_loops && tosend) {
1230 /* how much do we have to send */
1231 length = p_m_crypt_msg_len - p_m_crypt_msg_current;
1234 if (length > tosend)
1237 /* copy message (part) to buffer */
1238 memcpy(p, p_m_crypt_msg+p_m_crypt_msg_current, length);
1241 p_m_crypt_msg_current += length;
1242 if (p_m_crypt_msg_current == p_m_crypt_msg_len) {
1244 p_m_crypt_msg_current = 0;
1245 p_m_crypt_msg_loops--;
1246 // puts("eine loop weniger");
1254 if (p_tone_name[0] && tosend) {
1255 tosend -= read_audio(p, tosend);
1259 if (ISDN_LOAD - p_m_load - tosend > 0) {
1260 frm->prim = PH_DATA_REQ;
1262 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD-p_m_load-tosend, 0, NULL, 0);
1264 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);
1265 p_m_load += ISDN_LOAD - p_m_load - tosend;
1270 // NOTE: deletion is done by the child class
1272 /* handle timeouts */
1274 if (p_m_timer+p_m_timeout < now_d) {
1275 PDEBUG(DEBUG_ISDN, "(%s) timeout after %d seconds detected (state=%d).\n", p_name, p_m_timeout, p_state);
1277 /* send timeout to endpoint */
1278 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_TIMEOUT);
1279 message->param.state = p_state;
1280 message_put(message);
1285 return(0); /* nothing done */
1290 * whenever we get audio data from bchannel, we process it here
1292 void PmISDN::bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len)
1294 unsigned int cont = *((unsigned int *)data);
1295 unsigned char *data_temp;
1296 unsigned int length_temp;
1297 struct lcr_msg *message;
1301 if (hh->prim == PH_CONTROL_IND) {
1303 PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
1306 if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL) {
1307 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1308 add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
1310 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
1311 message->param.dtmf = cont & DTMF_TONE_MASK;
1312 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION DTMF digit '%c'\n", p_name, message->param.dtmf);
1313 message_put(message);
1318 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1319 add_trace("DSP-CRYPT", NULL, "error");
1321 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1322 message->param.crypt.type = CC_ERROR_IND;
1323 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION reject of blowfish.\n", p_name);
1324 message_put(message);
1328 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1329 add_trace("DSP-CRYPT", NULL, "ok");
1331 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1332 message->param.crypt.type = CC_ACTBF_CONF;
1333 PDEBUG(DEBUG_PORT, "PmISDN(%s) PH_CONTROL INDICATION accept of blowfish.\n", p_name);
1334 message_put(message);
1338 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1339 add_trace("unknown", NULL, "0x%x", cont);
1344 if (hh->prim == PH_CONTROL_IND) {
1347 chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
1348 add_trace("unknown", NULL, "0x%x", hh->id);
1353 if (hh->prim == PH_DATA_REQ || hh->prim == DL_DATA_REQ) {
1355 /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
1356 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
1359 /* see below (same condition) */
1360 if (p_state!=PORT_STATE_CONNECT
1361 && !p_m_mISDNport->tones)
1363 // printf(".");fflush(stdout);return;
1365 record(data, len, 1); // from up
1368 if (hh->prim != PH_DATA_IND && hh->prim != DL_DATA_IND) {
1369 PERROR("Bchannel received unknown primitve: 0x%x\n", hh->prim);
1373 /* calls will not process any audio data unless
1374 * the call is connected OR tones feature is enabled.
1376 #ifndef DEBUG_COREBRIDGE
1377 if (p_state!=PORT_STATE_CONNECT
1378 && !p_m_mISDNport->tones)
1383 /* the bearer capability must be audio in order to send and receive
1384 * audio prior or after connect.
1386 if (!(p_bearerinfo.capability&CLASS_CAPABILITY_AUDIO) && p_state!=PORT_STATE_CONNECT)
1390 /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
1392 PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
1398 record(data, len, 0); // from down
1400 /* randomize and listen to crypt message if enabled */
1401 if (p_m_crypt_listen) {
1402 /* the noisy randomizer */
1406 mISDN_rand[mISDN_rand_count & 0xff] += *p++;
1408 cryptman_listen_bch(data, len);
1413 /* send data to epoint */
1414 if (p_m_joindata && ACTIVE_EPOINT(p_epointlist)) { /* only if we have an epoint object */
1417 while(length_temp) {
1418 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_DATA);
1419 message->param.data.len = (length_temp>sizeof(message->param.data.data))?sizeof(message->param.data.data):length_temp;
1420 memcpy(message->param.data.data, data_temp, message->param.data.len);
1421 message_put(message);
1422 if (length_temp <= sizeof(message->param.data.data))
1424 data_temp += sizeof(message->param.data.data);
1425 length_temp -= sizeof(message->param.data.data);
1434 void PmISDN::set_echotest(int echo)
1436 if (p_m_echo != echo) {
1438 PDEBUG(DEBUG_ISDN, "we set echo to echo=%d.\n", p_m_echo);
1440 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1441 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);
1448 void PmISDN::set_tone(const char *dir, const char *tone)
1453 /* if no directory is given (by extension), we use interface.conf or options.conf */
1454 if (!dir || !dir[0]) {
1455 if (p_m_mISDNport->ifport->tones_dir[0])
1456 dir = p_m_mISDNport->ifport->tones_dir;
1457 else if (options.tones_dir[0])
1458 dir = options.tones_dir;
1463 PDEBUG(DEBUG_ISDN, "isdn port now plays tone:'%s'.\n", tone);
1469 /* check for dsp tones */
1470 if (!strcmp(dir, "american"))
1472 if (!strcmp(dir, "german"))
1474 if (!strcmp(dir, "oldgerman"))
1475 dsp = DSP_OLDGERMAN;
1477 /* check if we NOT really have to use a dsp-tone */
1478 if (dsp == DSP_NONE) {
1481 if (p_m_b_index > -1)
1482 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) {
1483 PDEBUG(DEBUG_ISDN, "we reset tone from id=%d to OFF.\n", p_m_tone);
1484 ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], DSP_TONE_PATT_OFF, 0, "DSP-TONE", 0);
1487 Port::set_tone(dir, tone);
1491 /* now we USE dsp-tone, convert name */
1492 if (!strcmp(tone, "dialtone")) {
1494 case DSP_AMERICAN: id = TONE_AMERICAN_DIALTONE; break;
1495 case DSP_GERMAN: id = TONE_GERMAN_DIALTONE; break;
1496 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALTONE; break;
1498 } else if (!strcmp(tone, "dialpbx")) {
1500 case DSP_AMERICAN: id = TONE_AMERICAN_DIALPBX; break;
1501 case DSP_GERMAN: id = TONE_GERMAN_DIALPBX; break;
1502 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDDIALPBX; break;
1504 } else if (!strcmp(tone, "ringing")) {
1506 case DSP_AMERICAN: id = TONE_AMERICAN_RINGING; break;
1507 case DSP_GERMAN: id = TONE_GERMAN_RINGING; break;
1508 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGING; break;
1510 } else if (!strcmp(tone, "ringpbx")) {
1512 case DSP_AMERICAN: id = TONE_AMERICAN_RINGPBX; break;
1513 case DSP_GERMAN: id = TONE_GERMAN_RINGPBX; break;
1514 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDRINGPBX; break;
1516 } else if (!strcmp(tone, "busy")) {
1519 case DSP_AMERICAN: id = TONE_AMERICAN_BUSY; break;
1520 case DSP_GERMAN: id = TONE_GERMAN_BUSY; break;
1521 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1523 } else if (!strcmp(tone, "release")) {
1526 case DSP_AMERICAN: id = TONE_AMERICAN_HANGUP; break;
1527 case DSP_GERMAN: id = TONE_GERMAN_HANGUP; break;
1528 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDHANGUP; break;
1530 } else if (!strcmp(tone, "cause_10"))
1532 else if (!strcmp(tone, "cause_11"))
1534 else if (!strcmp(tone, "cause_22")) {
1536 case DSP_AMERICAN: id = TONE_SPECIAL_INFO; break;
1537 case DSP_GERMAN: id = TONE_GERMAN_GASSENBESETZT; break;
1538 case DSP_OLDGERMAN: id = TONE_GERMAN_OLDBUSY; break;
1540 } else if (!strncmp(tone, "cause_", 6))
1541 id = TONE_SPECIAL_INFO;
1545 /* if we have a tone that is not supported by dsp */
1546 if (id==TONE_OFF && tone[0])
1550 if (p_m_tone != id) {
1553 PDEBUG(DEBUG_ISDN, "we set tone to id=%d.\n", p_m_tone);
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)
1556 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);
1558 /* turn user-space tones off in cases of no tone OR dsp tone */
1559 Port::set_tone("",NULL);
1563 /* MESSAGE_mISDNSIGNAL */
1564 //extern struct lcr_msg *dddebug;
1565 void PmISDN::message_mISDNsignal(unsigned int epoint_id, int message_id, union parameter *param)
1567 switch(param->mISDNsignal.message) {
1568 case mISDNSIGNAL_VOLUME:
1569 if (p_m_tx_gain != param->mISDNsignal.tx_gain) {
1570 p_m_tx_gain = param->mISDNsignal.tx_gain;
1571 PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
1572 if (p_m_b_index > -1)
1573 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)
1574 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);
1576 PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
1577 if (p_m_rx_gain != param->mISDNsignal.rx_gain) {
1578 p_m_rx_gain = param->mISDNsignal.rx_gain;
1579 PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
1580 if (p_m_b_index > -1)
1581 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)
1582 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);
1584 PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
1587 case mISDNSIGNAL_CONF:
1588 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1589 //tone if (!p_m_tone && p_m_conf!=param->mISDNsignal.conf)
1590 if (p_m_conf != param->mISDNsignal.conf) {
1591 p_m_conf = param->mISDNsignal.conf;
1592 PDEBUG(DEBUG_BCHANNEL, "we change conference to conf=%d.\n", p_m_conf);
1593 if (p_m_b_index > -1)
1594 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
1595 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);
1597 PDEBUG(DEBUG_BCHANNEL, "we already have conf=%d.\n", p_m_conf);
1598 /* we must set, even if currently tone forbids conf */
1599 p_m_conf = param->mISDNsignal.conf;
1600 //if (dddebug) PDEBUG(DEBUG_ISDN, "dddebug = %d\n", dddebug->type);
1603 case mISDNSIGNAL_JOINDATA:
1604 if (p_m_joindata != param->mISDNsignal.joindata) {
1605 p_m_joindata = param->mISDNsignal.joindata;
1606 PDEBUG(DEBUG_BCHANNEL, "we change to joindata=%d.\n", p_m_joindata);
1608 PDEBUG(DEBUG_BCHANNEL, "we already have joindata=%d.\n", p_m_joindata);
1611 case mISDNSIGNAL_DELAY:
1612 if (p_m_delay != param->mISDNsignal.delay) {
1613 p_m_delay = param->mISDNsignal.delay;
1614 PDEBUG(DEBUG_BCHANNEL, "we change delay mode to delay=%d.\n", p_m_delay);
1615 if (p_m_b_index > -1)
1616 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)
1617 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);
1619 PDEBUG(DEBUG_BCHANNEL, "we already have delay=%d.\n", p_m_delay);
1623 PERROR("PmISDN(%s) unsupported signal message %d.\n", p_name, param->mISDNsignal.message);
1628 void PmISDN::message_crypt(unsigned int epoint_id, int message_id, union parameter *param)
1630 struct lcr_msg *message;
1632 switch(param->crypt.type) {
1633 case CC_ACTBF_REQ: /* activate blowfish */
1635 p_m_crypt_key_len = param->crypt.len;
1636 if (p_m_crypt_key_len > (int)sizeof(p_m_crypt_key)) {
1637 PERROR("PmISDN(%s) key too long %d > %d\n", p_name, p_m_crypt_key_len, sizeof(p_m_crypt_key));
1638 message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_CRYPT);
1639 message->param.crypt.type = CC_ERROR_IND;
1640 message_put(message);
1643 memcpy(p_m_crypt_key, param->crypt.data, p_m_crypt_key_len);
1645 PDEBUG(DEBUG_BCHANNEL, "we set encryption to crypt=%d. (0 means OFF)\n", p_m_crypt);
1646 if (p_m_b_index > -1)
1647 if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT)
1648 ph_control_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);
1651 case CC_DACT_REQ: /* deactivate session encryption */
1656 case CR_LISTEN_REQ: /* start listening to messages */
1657 p_m_crypt_listen = 1;
1658 p_m_crypt_listen_state = 0;
1661 case CR_UNLISTEN_REQ: /* stop listening to messages */
1662 p_m_crypt_listen = 0;
1665 case CR_MESSAGE_REQ: /* send message */
1666 p_m_crypt_msg_len = cryptman_encode_bch(param->crypt.data, param->crypt.len, p_m_crypt_msg, sizeof(p_m_crypt_msg));
1667 if (!p_m_crypt_msg_len) {
1668 PERROR("PmISDN(%s) message too long %d > %d\n", p_name, param->crypt.len-1, sizeof(p_m_crypt_msg));
1671 p_m_crypt_msg_current = 0; /* reset */
1672 p_m_crypt_msg_loops = 6; /* enable */
1674 /* disable txmix, or we get corrupt data due to audio process */
1675 if (p_m_txmix && p_m_b_index>=0 && p_m_mISDNport->b_mode[p_m_b_index] == B_MODE_TRANSPARENT) {
1676 PDEBUG(DEBUG_BCHANNEL, "for sending CR_MESSAGE_REQ, we reset txmix from txmix=%d.\n", p_m_txmix);
1677 ph_control(p_m_mISDNport, this, p_mISDNport->b_socket[p_m_b_index], DSP_MIX_OFF, 0, "DSP-TXMIX", 0);
1683 PERROR("PmISDN(%s) unknown crypt message %d\n", p_name, param->crypt.type);
1689 * endpoint sends messages to the port
1691 int PmISDN::message_epoint(unsigned int epoint_id, int message_id, union parameter *param)
1693 if (Port::message_epoint(epoint_id, message_id, param))
1696 switch(message_id) {
1697 case MESSAGE_DATA: /* tx-data from upper layer */
1698 txfromup(param->data.data, param->data.len);
1701 case MESSAGE_mISDNSIGNAL: /* user command */
1702 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received special ISDN SIGNAL %d.\n", p_name, param->mISDNsignal.message);
1703 message_mISDNsignal(epoint_id, message_id, param);
1706 case MESSAGE_CRYPT: /* crypt control command */
1707 PDEBUG(DEBUG_ISDN, "PmISDN(%s) received encryption command '%d'.\n", p_name, param->crypt.type);
1708 message_crypt(epoint_id, message_id, param);
1717 * main loop for processing messages from mISDN
1719 int mISDN_handler(void)
1722 struct mISDNport *mISDNport;
1723 class PmISDN *isdnport;
1725 unsigned char buffer[2048+MISDN_HEADER_LEN];
1726 struct mISDNhead *hh = (struct mISDNhead *)buffer;
1730 /* process all ports */
1731 mISDNport = mISDNport_first;
1733 /* process all bchannels */
1735 while(i < mISDNport->b_num) {
1736 /* process timer events for bchannel handling */
1737 if (mISDNport->b_timer[i]) {
1738 if (mISDNport->b_timer[i] <= now_d)
1739 bchannel_event(mISDNport, i, B_EVENT_TIMEOUT);
1741 /* handle port of bchannel */
1742 isdnport=mISDNport->b_port[i];
1744 /* call bridges in user space OR crypto OR recording */
1745 if (isdnport->p_m_joindata || isdnport->p_m_crypt_msg_loops || isdnport->p_m_crypt_listen || isdnport->p_record) {
1746 /* rx IS required */
1747 if (isdnport->p_m_rxoff) {
1749 isdnport->p_m_rxoff = 0;
1750 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is required, so we turn them on\n", __FUNCTION__);
1751 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1752 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_ON, 0, "DSP-RXOFF", 0);
1756 /* rx NOT required */
1757 if (!isdnport->p_m_rxoff) {
1759 isdnport->p_m_rxoff = 1;
1760 PDEBUG(DEBUG_BCHANNEL, "%s: receive data is not required, so we turn them off\n", __FUNCTION__);
1761 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1762 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
1767 if (isdnport->p_record) {
1768 /* txdata IS required */
1769 if (!isdnport->p_m_txdata) {
1771 isdnport->p_m_txdata = 1;
1772 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is required, so we turn them on\n", __FUNCTION__);
1773 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1774 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_ON, 0, "DSP-TXDATA", 1);
1778 /* txdata NOT required */
1779 if (isdnport->p_m_txdata) {
1781 isdnport->p_m_txdata = 0;
1782 PDEBUG(DEBUG_BCHANNEL, "%s: transmit data is not required, so we turn them off\n", __FUNCTION__);
1783 if (mISDNport->b_port[i] && mISDNport->b_state[i] == B_STATE_ACTIVE)
1784 ph_control(mISDNport, isdnport, mISDNport->b_socket[i], DSP_TXDATA_OFF, 0, "DSP-TXDATA", 0);
1790 /* handle message from bchannel */
1791 if (mISDNport->b_socket[i] > -1) {
1792 ret = recv(mISDNport->b_socket[i], buffer, sizeof(buffer), 0);
1793 if (ret >= (int)MISDN_HEADER_LEN) {
1796 /* we don't care about confirms, we use rx data to sync tx */
1800 /* we receive audio data, we respond to it AND we send tones */
1805 case PH_CONTROL_IND:
1806 if (mISDNport->b_port[i])
1807 mISDNport->b_port[i]->bchannel_receive(hh, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
1809 PDEBUG(DEBUG_BCHANNEL, "b-channel is not associated to an ISDNPort (socket %d), ignoring.\n", mISDNport->b_socket[i]);
1812 case PH_ACTIVATE_IND:
1813 case DL_ESTABLISH_IND:
1814 case PH_ACTIVATE_CNF:
1815 case DL_ESTABLISH_CNF:
1816 PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", mISDNport->b_socket[i]);
1817 bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
1820 case PH_DEACTIVATE_IND:
1821 case DL_RELEASE_IND:
1822 case PH_DEACTIVATE_CNF:
1823 case DL_RELEASE_CNF:
1824 PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", mISDNport->b_socket[i]);
1825 bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
1829 PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, mISDNport->b_socket[i], ret-MISDN_HEADER_LEN);
1832 if (ret < 0 && errno != EWOULDBLOCK)
1833 PERROR("Read from port %d, index %d failed with return code %d\n", mISDNport->portnum, i, ret);
1840 /* handle queued up-messages (d-channel) */
1841 if (!mISDNport->gsm) {
1842 while ((mb = mdequeue(&mISDNport->upqueue))) {
1845 case MPH_ACTIVATE_IND:
1846 if (mISDNport->l1link != 1) {
1847 l1l2l3_trace_header(mISDNport, NULL, L1_ACTIVATE_IND, DIRECTION_IN);
1849 mISDNport->l1link = 1;
1853 case MPH_DEACTIVATE_IND:
1854 if (mISDNport->l1link != 0) {
1855 l1l2l3_trace_header(mISDNport, NULL, L1_DEACTIVATE_IND, DIRECTION_IN);
1857 mISDNport->l1link = 0;
1861 case MPH_INFORMATION_IND:
1862 PDEBUG(DEBUG_ISDN, "Received MPH_INFORMATION_IND for port %d (%s).\n", mISDNport->portnum, mISDNport->ifport->interface->name);
1864 case L1_SIGNAL_LOS_ON:
1867 case L1_SIGNAL_LOS_OFF:
1870 case L1_SIGNAL_AIS_ON:
1873 case L1_SIGNAL_AIS_OFF:
1876 case L1_SIGNAL_RDI_ON:
1879 case L1_SIGNAL_RDI_OFF:
1882 case L1_SIGNAL_SLIP_TX:
1883 mISDNport->slip_tx++;
1885 case L1_SIGNAL_SLIP_RX:
1886 mISDNport->slip_rx++;
1891 case MT_L2ESTABLISH:
1892 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_IND, DIRECTION_IN);
1893 add_trace("tei", NULL, "%d", l3m->pid);
1895 mISDNport->l2link = 1;
1897 mISDNport->l2mask[l3m->pid >> 3] |= (1 << (l3m->pid & 7));
1898 if ((!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1899 if (mISDNport->l2establish) {
1900 mISDNport->l2establish = 0;
1901 PDEBUG(DEBUG_ISDN, "the link became active before l2establish timer expiry.\n");
1908 mISDNport->l2mask[l3m->pid >> 3] &= ~(1 << (l3m->pid & 7));
1909 if (!mISDNport->l2establish) {
1910 l1l2l3_trace_header(mISDNport, NULL, L2_RELEASE_IND, DIRECTION_IN);
1911 add_trace("tei", NULL, "%d", l3m->pid);
1913 /* down if not nt-ptmp */
1914 if (!mISDNport->ntmode || mISDNport->ptp)
1915 mISDNport->l2link = 0;
1917 if (!mISDNport->gsm && (!mISDNport->ntmode || mISDNport->ptp) && l3m->pid < 127) {
1918 if (!mISDNport->l2establish && mISDNport->l2hold) {
1919 PDEBUG(DEBUG_ISDN, "set timer and establish.\n");
1920 time(&mISDNport->l2establish);
1921 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1927 /* l3-data is sent to LCR */
1928 stack2manager(mISDNport, l3m->type, l3m->pid, l3m);
1936 if (mISDNport->l1timeout && now>mISDNport->l1timeout)
1938 PDEBUG(DEBUG_ISDN, "the L1 establish timer expired, we release all pending messages.\n", mISDNport->portnum);
1939 mISDNport->l1timeout = 0;
1942 /* layer 2 establish timer */
1943 if (mISDNport->l2establish) {
1944 if (now-mISDNport->l2establish > 5) {
1945 mISDNport->l2establish = 0;
1946 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
1948 PDEBUG(DEBUG_ISDN, "the L2 establish timer expired, we try to establish the link portnum=%d.\n", mISDNport->portnum);
1949 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
1950 time(&mISDNport->l2establish);
1957 mISDNport = mISDNport->next;
1960 /* if we received at least one b-frame, we will return 1 */
1964 int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3_msg *l3m)
1968 * l3m must be queued, except for MT_ASSIGN
1971 struct mISDNport *mISDNport = (struct mISDNport *)ml3->priv;
1974 /* special MT_ASSIGN handling:
1976 * if we request a PID from mlayer, we always do it while lcr is locked.
1977 * therefore we must check the MT_ASSIGN reply first before we lock.
1978 * this is because the MT_ASSIGN reply is received with the requesting
1979 * process, not by the mlayer thread!
1980 * this means, that the reply is sent during call of the request.
1981 * we must check if we get a reply and we know that we lcr is currently
1984 if (cmd==MT_ASSIGN && (pid&MISDN_PID_CR_FLAG) && (pid>>16)==MISDN_CES_MASTER) {
1985 /* let's do some checking if someone changes stack behaviour */
1986 if (mt_assign_pid != 0)
1987 FATAL("someone played with the mISDNuser stack. MT_ASSIGN not currently expected.\n");
1988 mt_assign_pid = pid;
1991 /* queue message, create, if required */
1993 l3m = alloc_l3_msg();
1995 FATAL("No memory for layer 3 message\n");
1997 mb = container_of(l3m, struct mbuffer, l3);
2000 mqueue_tail(&mISDNport->upqueue, mb);
2004 int mISDN_getportbyname(int sock, int cnt, char *portname)
2006 struct mISDN_devinfo devinfo;
2010 while (port < cnt) {
2012 ret = ioctl(sock, IMGETDEVINFO, &devinfo);
2015 if (!strcasecmp(devinfo.name, portname))
2026 * global function to add a new card (port)
2028 struct mISDNport *mISDNport_open(int port, char *portname, int ptp, int force_nt, int te_special, int l1hold, int l2hold, struct interface *interface, int gsm)
2031 struct mISDNport *mISDNport, **mISDNportp;
2035 // struct mlayer3 *ml3;
2036 struct mISDN_devinfo devinfo;
2037 unsigned int protocol, prop;
2039 /* check port counts */
2040 ret = ioctl(mISDNsocket, IMGETCOUNT, &cnt);
2042 fprintf(stderr, "Cannot get number of mISDN devices. (ioctl IMGETCOUNT failed ret=%d)\n", ret);
2047 PERROR_RUNTIME("Found no card. Please be sure to load card drivers.\n");
2051 port = mISDN_getportbyname(mISDNsocket, cnt, portname);
2054 PERROR_RUNTIME("Port name '%s' not found, did you load loopback interface for GSM?.\n", portname);
2056 PERROR_RUNTIME("Port name '%s' not found, use 'misdn_info' tool to list all existing ports.\n", portname);
2059 // note: 'port' has still the port number
2061 if (port>cnt || port<0) {
2062 PERROR_RUNTIME("Port (%d) given at 'ports' (options.conf) is out of existing port range (%d-%d)\n", port, 0, cnt);
2066 /* get port attributes */
2067 pri = bri = pots = nt = te = 0;
2069 ret = ioctl(mISDNsocket, IMGETDEVINFO, &devinfo);
2071 PERROR_RUNTIME("Cannot get device information for port %d. (ioctl IMGETDEVINFO failed ret=%d)\n", port, ret);
2074 if (devinfo.Dprotocols & (1 << ISDN_P_TE_S0)) {
2078 if (devinfo.Dprotocols & (1 << ISDN_P_NT_S0)) {
2082 if (devinfo.Dprotocols & (1 << ISDN_P_TE_E1)) {
2086 if (devinfo.Dprotocols & (1 << ISDN_P_NT_E1)) {
2091 if (devinfo.Dprotocols & (1 << ISDN_P_FXS)) {
2097 if (devinfo.Dprotocols & (1 << ISDN_P_FXO)) {
2102 if (force_nt && !nt) {
2103 PERROR_RUNTIME("Port %d does not support NT-mode\n", port);
2107 PERROR_RUNTIME("Port %d supports BRI and PRI?? What kind of controller is that?. (Can't use this!)\n", port);
2110 if (pots && !bri && !pri) {
2111 PERROR_RUNTIME("Port %d supports POTS, LCR does not!\n", port);
2115 PERROR_RUNTIME("Port %d does not support BRI nor PRI!\n", port);
2119 PERROR_RUNTIME("Port %d does not support NT-mode nor TE-mode!\n", port);
2122 /* set NT by turning off TE */
2125 /* if TE an NT is supported (and not forced to NT), turn off NT */
2129 /* check for double use of port */
2131 mISDNport = mISDNport_first;
2133 if (mISDNport->portnum == port)
2135 mISDNport = mISDNport->next;
2138 PERROR_RUNTIME("Port %d already in use by LCR. You can't use a NT port multiple times.\n", port);
2143 /* check for continous channelmap with no bchannel on slot 16 */
2144 if (test_channelmap(0, devinfo.channelmap)) {
2145 PERROR_RUNTIME("Port %d provides channel 0, but we cannot access it!\n", port);
2149 while(i < (int)devinfo.nrbchan + 1) {
2151 if (test_channelmap(i, devinfo.channelmap)) {
2152 PERROR("Port %d provides bchannel 16. Pleas upgrade mISDN, if this port is mISDN loopback interface.\n", port);
2156 if (!test_channelmap(i, devinfo.channelmap)) {
2157 PERROR_RUNTIME("Port %d has no channel on slot %d!\n", port, i);
2164 /* add mISDNport structure */
2165 mISDNportp = &mISDNport_first;
2167 mISDNportp = &((*mISDNportp)->next);
2168 mISDNport = (struct mISDNport *)MALLOC(sizeof(struct mISDNport));
2170 /* gsm audio is always active */
2171 mISDNport->l1link = 1;
2172 mISDNport->l2link = 1;
2174 mISDNport->l1link = -1;
2175 mISDNport->l2link = -1;
2177 mISDNport->gsm = gsm;
2179 *mISDNportp = mISDNport;
2181 /* if pri, must set PTP */
2201 /* allocate ressources of port */
2202 protocol = (nt)?L3_PROTOCOL_DSS1_NET:L3_PROTOCOL_DSS1_USER;
2203 prop = (1 << MISDN_FLG_L2_CLEAN);
2204 if (ptp) // ptp forced
2205 prop |= (1 << MISDN_FLG_PTP);
2206 if (nt) // supports hold/retrieve on nt-mode
2207 prop |= (1 << MISDN_FLG_NET_HOLD);
2208 if (l1hold) // supports layer 1 hold
2209 prop |= (1 << MISDN_FLG_L1_HOLD);
2210 if (l2hold) // supports layer 2 hold
2211 prop |= (1 << MISDN_FLG_L2_HOLD);
2212 /* open layer 3 and init upqueue */
2214 unsigned long on = 1;
2215 struct sockaddr_mISDN addr;
2217 if (devinfo.nrbchan < 8) {
2218 PERROR_RUNTIME("GSM port %d must have at least 8 b-channels.\n", port);
2219 mISDNport_close(mISDNport);
2223 if ((mISDNport->lcr_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_NT_S0)) < 0) {
2224 PERROR_RUNTIME("GSM port %d failed to open socket.\n", port);
2225 mISDNport_close(mISDNport);
2228 /* set nonblocking io */
2229 if (ioctl(mISDNport->lcr_sock, FIONBIO, &on) < 0) {
2230 PERROR_RUNTIME("GSM port %d failed to set socket into nonblocking io.\n", port);
2231 mISDNport_close(mISDNport);
2234 /* bind socket to dchannel */
2235 memset(&addr, 0, sizeof(addr));
2236 addr.family = AF_ISDN;
2239 if (bind(mISDNport->lcr_sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
2240 PERROR_RUNTIME("GSM port %d failed to bind socket. (errno %d)\n", port, errno);
2241 mISDNport_close(mISDNport);
2245 /* queue must be initializes, because l3-thread may send messages during open_layer3() */
2246 mqueue_init(&mISDNport->upqueue);
2247 mISDNport->ml3 = open_layer3(port, protocol, prop , do_layer3, mISDNport);
2248 if (!mISDNport->ml3) {
2249 mqueue_purge(&mISDNport->upqueue);
2250 PERROR_RUNTIME("open_layer3() failed for port %d\n", port);
2258 "PORT (open failed)");
2260 mISDNport_close(mISDNport);
2265 SCPY(mISDNport->name, devinfo.name);
2266 mISDNport->b_num = devinfo.nrbchan;
2267 mISDNport->portnum = port;
2268 mISDNport->ntmode = nt;
2269 mISDNport->tespecial = te_special;
2270 mISDNport->pri = pri;
2271 mISDNport->ptp = ptp;
2272 mISDNport->l1hold = l1hold;
2273 mISDNport->l2hold = l2hold;
2274 PDEBUG(DEBUG_ISDN, "Port has %d b-channels.\n", mISDNport->b_num);
2276 while(i < mISDNport->b_num) {
2277 mISDNport->b_state[i] = B_STATE_IDLE;
2278 mISDNport->b_socket[i] = -1;
2282 /* if ptp, pull up the link */
2283 if (!mISDNport->gsm && mISDNport->l2hold && (mISDNport->ptp || !mISDNport->ntmode)) {
2284 mISDNport->ml3->to_layer3(mISDNport->ml3, MT_L2ESTABLISH, 0, NULL);
2285 l1l2l3_trace_header(mISDNport, NULL, L2_ESTABLISH_REQ, DIRECTION_OUT);
2286 add_trace("tei", NULL, "%d", 0);
2288 time(&mISDNport->l2establish);
2291 /* for nt-mode ptmp the link is always up */
2292 if (mISDNport->ntmode && !mISDNport->ptp)
2293 mISDNport->l2link = 1;
2295 PDEBUG(DEBUG_BCHANNEL, "using 'mISDN_dsp.o' module\n");
2297 start_trace(mISDNport->portnum,
2305 add_trace("mode", NULL, (mISDNport->ntmode)?"network":"terminal");
2306 add_trace("channels", NULL, "%d", mISDNport->b_num);
2313 * function to free ALL cards (ports)
2315 void mISDNport_close_all(void)
2317 /* free all ports */
2318 while(mISDNport_first)
2319 mISDNport_close(mISDNport_first);
2323 * free only one port
2325 void mISDNport_close(struct mISDNport *mISDNport)
2327 struct mISDNport **mISDNportp;
2329 class PmISDN *isdnport;
2332 /* remove all port instance that are linked to this mISDNport */
2335 if ((port->p_type&PORT_CLASS_MASK) == PORT_CLASS_mISDN) {
2336 isdnport = (class PmISDN *)port;
2337 if (isdnport->p_m_mISDNport) {
2338 PDEBUG(DEBUG_ISDN, "port %s uses mISDNport %d, destroying it.\n", isdnport->p_name, mISDNport->portnum);
2345 /* only if we are already part of interface */
2346 if (mISDNport->ifport) {
2347 start_trace(mISDNport->portnum,
2348 mISDNport->ifport->interface,
2358 /* free bchannels */
2360 while(i < mISDNport->b_num) {
2361 if (mISDNport->b_socket[i] > -1) {
2362 _bchannel_destroy(mISDNport, i);
2363 PDEBUG(DEBUG_BCHANNEL, "freeing %s port %d bchannel (index %d).\n", (mISDNport->ntmode)?"NT":"TE", mISDNport->portnum, i);
2368 /* close layer 3, if open */
2369 if (!mISDNport->gsm && mISDNport->ml3) {
2370 close_layer3(mISDNport->ml3);
2373 /* close gsm socket, if open */
2374 if (mISDNport->gsm && mISDNport->lcr_sock > -1) {
2375 close(mISDNport->lcr_sock);
2379 if (!mISDNport->gsm)
2380 mqueue_purge(&mISDNport->upqueue);
2382 /* remove from list */
2383 mISDNportp = &mISDNport_first;
2384 while(*mISDNportp) {
2385 if (*mISDNportp == mISDNport) {
2386 *mISDNportp = (*mISDNportp)->next;
2390 mISDNportp = &((*mISDNportp)->next);
2394 FATAL("mISDNport not in list\n");
2396 FREE(mISDNport, sizeof(struct mISDNport));
2403 * enque data from upper buffer
2405 void PmISDN::txfromup(unsigned char *data, int length)
2407 unsigned char buf[MISDN_HEADER_LEN+((length>ISDN_LOAD)?length:ISDN_LOAD)];
2408 struct mISDNhead *hh = (struct mISDNhead *)buf;
2411 if (p_m_b_index < 0)
2413 if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_ACTIVE)
2416 /* check if high priority tones exist
2417 * ignore data in this case
2419 if (p_tone_name[0] || p_m_crypt_msg_loops)
2422 /* preload procedure
2423 * if transmit buffer in DSP module is empty,
2424 * preload it to DSP_LOAD to prevent jitter gaps.
2426 if (p_m_load==0 && ISDN_LOAD>0) {
2427 hh->prim = PH_DATA_REQ;
2429 memset(buf+MISDN_HEADER_LEN, (options.law=='a')?0x2a:0xff, ISDN_LOAD);
2430 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+ISDN_LOAD, 0, NULL, 0);
2432 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);
2433 p_m_load += ISDN_LOAD;
2436 /* drop if load would exceed ISDN_MAXLOAD
2437 * this keeps the delay not too high
2439 if (p_m_load+length > ISDN_MAXLOAD)
2442 /* make and send frame */
2443 hh->prim = PH_DATA_REQ;
2445 memcpy(buf+MISDN_HEADER_LEN, data, length);
2446 ret = sendto(p_m_mISDNport->b_socket[p_m_b_index], buf, MISDN_HEADER_LEN+length, 0, NULL, 0);
2448 PERROR("Failed to send to socket %d\n", p_m_mISDNport->b_socket[p_m_b_index]);