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